/**
* Streams Listing 01
*
* An answering machine based on a one-way ACE_Stream
*/
#include "ace/OS_NS_string.h"
#include "ace/Stream.h"
#include "ace/Message_Block.h"
#include "ace/FILE_IO.h"
#include "MessageInfo.h"
#include "Message.h"
#include "BasicTask.h"
#include "EndTask.h"
#include "Util.h"
#include "RecordingDevice.h"
// Listing 21 code/ch18
class AnswerIncomingCall : public BasicTask
{
protected:
virtual int process (Message *message)
{
ACE_TRACE ("AnswerIncomingCall::process()");
if (message->recorder ()->answer_call () < 0)
ACE_ERROR_RETURN ((LM_ERROR,
ACE_TEXT ("%p\n"),
ACE_TEXT ("AnswerIncomingCall")),
-1);
return 0;
}
};
// Listing 21
// Listing 22 code/ch18
class GetCallerId : public BasicTask
{
protected:
virtual int process (Message *message)
{
ACE_TRACE ("GetCallerId::process()");
CallerId *id;
id = message->recorder ()->retrieve_callerId ();
if (!id)
ACE_ERROR_RETURN ((LM_ERROR,
ACE_TEXT ("%p\n"),
ACE_TEXT ("GetCallerId")),
-1);
message->caller_id (id);
return 0;
}
};
// Listing 22
// Listing 23 code/ch18
class PlayOutgoingMessage : public BasicTask
{
protected:
virtual int process (Message *message)
{
ACE_TRACE ("PlayOutgoingMessage::process()");
ACE_FILE_Addr outgoing_message =
this->get_outgoing_message (message);
int pmrv =
message->recorder ()->play_message (outgoing_message);
if (pmrv < 0)
ACE_ERROR_RETURN ((LM_ERROR,
ACE_TEXT ("%p\n"),
ACE_TEXT ("PlayOutgoingMessage")),
-1);
return 0;
}
ACE_FILE_Addr get_outgoing_message (Message *)
{
// Exclude 23
return ACE_FILE_Addr (ACE_TEXT ("/tmp/outgoing_message"));
// Exclude 23
}
};
// Listing 23
// Listing 24 code/ch18
class RecordIncomingMessage : public BasicTask
{
protected:
virtual int process (Message *message)
{
ACE_TRACE ("RecordIncomingMessage::process()");
ACE_FILE_Addr incoming_message =
this->get_incoming_message_queue ();
MessageType *type =
message->recorder ()->record_message (incoming_message);
if (!type)
ACE_ERROR_RETURN ((LM_ERROR,
ACE_TEXT ("%p\n"),
ACE_TEXT ("RecordIncomingMessage")),
-1);
message->incoming_message (incoming_message, type);
return 0;
}
ACE_FILE_Addr get_incoming_message_queue ()
{
// Exclude 24
return ACE_FILE_Addr (ACE_TEXT ("/tmp/incoming_message"));
// Exclude 24
}
};
// Listing 24
// Listing 25 code/ch18
class ReleaseDevice : public BasicTask
{
protected:
virtual int process (Message *message)
{
ACE_TRACE ("ReleaseDevice::process()");
message->recorder ()->release ();
return 0;
}
};
// Listing 25
// Listing 26 code/ch18
class EncodeMessage : public BasicTask
{
protected:
virtual int process (Message *message)
{
ACE_TRACE ("EncodeMessage::process()");
ACE_FILE_Addr &incoming = message->addr ();
ACE_FILE_Addr addr = this->get_message_destination (message);
if (message->is_text ())
Util::convert_to_unicode (incoming, addr);
else if (message->is_audio ())
Util::convert_to_mp3 (incoming, addr);
else if (message->is_video ())
Util::convert_to_mpeg (incoming, addr);
message->addr (addr);
return 0;
}
ACE_FILE_Addr get_message_destination (Message *)
{
// Exclude 26
return ACE_FILE_Addr (ACE_TEXT ("/tmp/encoded_message"));
// Exclude 26
}
};
// Listing 26
// Listing 27 code/ch18
class SaveMetaData : public BasicTask
{
protected:
virtual int process (Message *message)
{
ACE_TRACE ("SaveMetaData::process()");
ACE_TString path (message->addr ().get_path_name ());
path += ACE_TEXT (".xml");
ACE_FILE_Connector connector;
ACE_FILE_IO file;
ACE_FILE_Addr addr (path.c_str ());
if (connector.connect (file, addr) == -1)
ACE_ERROR_RETURN ((LM_ERROR,
ACE_TEXT ("%p\n"),
ACE_TEXT ("create meta-data file")),
0);
file.truncate (0);
this->write (file, "\n");
// ...
this->write (file, "\n");
file.close ();
return 0;
}
private:
//FUZZ: disable check_for_lack_ACE_OS
int write (ACE_FILE_IO &file, const char *str)
{
//FUZZ: enable check_for_lack_ACE_OS
return file.send (str, ACE_OS::strlen (str));
}
};
// Listing 27
// Listing 28 code/ch18
class NotifySomeone : public BasicTask
{
protected:
virtual int process (Message *message)
{
ACE_TRACE ("NotifySomeone::process()");
// Format an email to tell someone about the
// newly received message.
// ...
// Display message information in the logfile
ACE_DEBUG ((LM_INFO,
ACE_TEXT ("New message from %s ")
ACE_TEXT ("received and stored at %s\n"),
message->caller_id ()->string (),
message->addr ().get_path_name ()));
return 0;
}
};
// Listing 28
// Listing 10 code/ch18
class RecordingStream : public ACE_Stream
{
public:
typedef ACE_Stream inherited;
typedef ACE_Module Module;
RecordingStream () : inherited()
{ }
// Listing 10
//FUZZ: disable check_for_lack_ACE_OS
// Listing 1000 code/ch18
virtual int open (void *arg,
Module *head = 0, Module *tail = 0)
{
//FUZZ: enable check_for_lack_ACE_OS
if (tail == 0)
ACE_NEW_RETURN (tail,
Module (ACE_TEXT ("End Module"), new TheEndTask ()),
-1);
this->inherited::open (arg, head, tail);
// Listing 1000
// Listing 1001 code/ch18
Module *answerIncomingCallModule;
ACE_NEW_RETURN (answerIncomingCallModule,
Module (ACE_TEXT ("Answer Incoming Call"),
new AnswerIncomingCall ()),
-1);
// Listing 11 code/ch18
Module *getCallerIdModule;
ACE_NEW_RETURN (getCallerIdModule,
Module (ACE_TEXT ("Get Caller ID"), new GetCallerId ()),
-1);
// Listing 11
Module *playOGMModule;
ACE_NEW_RETURN (playOGMModule,
Module (ACE_TEXT ("Play Outgoing Message"),
new PlayOutgoingMessage ()),
-1);
Module *recordModule;
ACE_NEW_RETURN (recordModule,
Module (ACE_TEXT ("Record Incoming Message"),
new RecordIncomingMessage ()),
-1);
Module *releaseModule;
ACE_NEW_RETURN (releaseModule,
Module (ACE_TEXT ("Release Device"),
new ReleaseDevice ()),
-1);
Module *conversionModule;
ACE_NEW_RETURN (conversionModule,
Module (ACE_TEXT ("Encode Message"),
new EncodeMessage ()),
-1);
Module *saveMetaDataModule;
ACE_NEW_RETURN (saveMetaDataModule,
Module (ACE_TEXT ("Save Meta-Data"),
new SaveMetaData ()),
-1);
Module *notificationModule;
ACE_NEW_RETURN (notificationModule,
Module (ACE_TEXT ("Notify Someone"),
new NotifySomeone ()),
-1);
// Listing 1001
// Listing 12 code/ch18
if (this->push (notificationModule) == -1)
ACE_ERROR_RETURN ((LM_ERROR,
ACE_TEXT ("Failed to push %p\n"),
ACE_TEXT ("notificationModule")),
-1);
if (this->push (saveMetaDataModule) == -1)
ACE_ERROR_RETURN ((LM_ERROR,
ACE_TEXT ("Failed to push %p\n"),
ACE_TEXT ("saveMetaDataModule")),
-1);
if (this->push (conversionModule) == -1)
ACE_ERROR_RETURN ((LM_ERROR,
ACE_TEXT ("Failed to push %p\n"),
ACE_TEXT ("conversionModule")),
-1);
if (this->push (releaseModule) == -1)
ACE_ERROR_RETURN ((LM_ERROR,
ACE_TEXT ("Failed to push %p\n"),
ACE_TEXT ("releaseModule")),
-1);
if (this->push (recordModule) == -1)
ACE_ERROR_RETURN ((LM_ERROR,
ACE_TEXT ("Failed to push %p\n"),
ACE_TEXT ("recordModule")),
-1);
if (this->push (playOGMModule) == -1)
ACE_ERROR_RETURN ((LM_ERROR,
ACE_TEXT ("Failed to push %p\n"),
ACE_TEXT ("playOGMModule")),
-1);
if (this->push (getCallerIdModule) == -1)
ACE_ERROR_RETURN ((LM_ERROR,
ACE_TEXT ("Failed to push %p\n"),
ACE_TEXT ("getCallerIdModule")),
-1);
if (this->push (answerIncomingCallModule) == -1)
ACE_ERROR_RETURN ((LM_ERROR,
ACE_TEXT ("Failed to push %p\n")
ACE_TEXT ("answerIncomingCallModule")),
-1);
// Listing 12
return 0;
}
// Listing 13 code/ch18
int record (RecordingDevice *recorder)
{
ACE_Message_Block * mb = 0;
ACE_NEW_RETURN (mb, ACE_Message_Block (sizeof(Message)), -1);
Message *message = (Message *)mb->wr_ptr ();
mb->wr_ptr (sizeof(Message));
ACE_DEBUG ((LM_DEBUG,
ACE_TEXT ("RecordingStream::record() - ")
ACE_TEXT ("message->recorder(recorder)\n")));
message->recorder (recorder);
int rval = this->put (mb);
ACE_DEBUG ((LM_DEBUG,
ACE_TEXT ("RecordingStream::record() - ")
ACE_TEXT ("this->put() returns %d\n"),
rval));
return rval;
}
// Listing 13
};
// Listing 1 code/ch18
int ACE_TMAIN (int argc, ACE_TCHAR *argv[])
{
RecordingDevice *recorder =
RecordingDeviceFactory::instantiate (argc, argv);
// Listing 1
// Listing 2 code/ch18
RecordingStream *recording_stream;
ACE_NEW_RETURN (recording_stream, RecordingStream, -1);
if (recording_stream->open (0) < 0)
ACE_ERROR_RETURN ((LM_ERROR,
ACE_TEXT ("%p\n"),
ACE_TEXT ("RecordingStream->open()")),
0);
// Listing 2
// Listing 3 code/ch18
for (;;)
{
ACE_DEBUG ((LM_INFO,
ACE_TEXT ("Waiting for incoming message\n")));
RecordingDevice *activeRecorder =
recorder->wait_for_activity ();
ACE_DEBUG ((LM_INFO,
ACE_TEXT ("Initiating recording process\n")));
recording_stream->record (activeRecorder);
}
// Listing 3
ACE_NOTREACHED (return 0;)
}