examples/Base/MessageQueueExample/Inverter/src/CInverter.cpp

Go to the documentation of this file.
00001 /*
00002 Copyright (c) 2008-2010 Nokia Corporation and/or its subsidiary(-ies). All rights reserved.
00003 
00004 Redistribution and use in source and binary forms, with or without
00005 modification, are permitted provided that the following conditions are met:
00006 
00007 * Redistributions of source code must retain the above copyright notice, this
00008   list of conditions and the following disclaimer.
00009 * Redistributions in binary form must reproduce the above copyright notice,
00010   this list of conditions and the following disclaimer in the documentation
00011   and/or other materials provided with the distribution.
00012 * Neither the name of Nokia Corporation nor the names of its contributors
00013   may be used to endorse or promote products derived from this software
00014   without specific prior written permission.
00015 
00016 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00017 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00018 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
00019 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
00020 FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00021 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
00022 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00023 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
00024 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
00025 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00026 
00027 Description: 
00028 The following class describes the Inverter class which recieves input 
00029 through InverterInq and sends it to InverterOutQ after inverting the recieved words.
00030 It implements a periodic timer which opens the InverterInq every 10 seconds. 
00031 */
00032 
00033 
00034 
00035 
00040 #include "CInverter.h"
00041 #include "e32keys.h"     // for EKeyEscape.
00042 
00043 //Periodic timer interval of 10 seconds.
00044 const TInt KPeriodicTimerInterval10Sec(10000000);
00045 
00046 //Error code to indicate Stop command.
00047 const TInt KErrStop = -100; 
00048 
00052 CInverter::~CInverter()
00053         {
00054     if(iTimer)
00055         {
00056         // Calling Cancel without checking if the timer is active is safe
00057         iTimer->Cancel();
00058         }
00059     delete iTimer;
00060         iInMsgQ.Close();
00061         iOutMsgQ.Close();
00062         }
00063 
00064 CInverter* CInverter::NewL()
00065         {
00066         CInverter* self=new(ELeave)CInverter();
00067         CleanupStack::PushL(self);
00068         self->ConstructL();
00069         CleanupStack::Pop(self);
00070         return self;
00071         }
00075 void CInverter::ConstructL()
00076     {
00077     // Initialize the periodic timer.
00078     iTimer = CPeriodic::NewL(CActive::EPriorityIdle);
00079     // Start the periodic timer, when ever the time elapsed
00080     // the StaticWake() will get called.
00081 
00082     iTimer->Start(KPeriodicTimerInterval10Sec, KPeriodicTimerInterval10Sec,TCallBack(StaticWake, this));
00083     
00084     }
00085 
00090 TInt CInverter::StaticWake(TAny* aAny)
00091         {
00092         CInverter* self = static_cast<CInverter*>( aAny );
00093         TInt ret = self->RecieveMsg();
00094         if(ret!= KErrStop) //KErrStop indicates that system has to be stopped and no more messages to be sent.
00095         self->SendMsg();
00096         return KErrNone; // Return value ignored by CPeriodic
00097         }
00098 
00105 TInt CInverter::RecieveMsg()
00106     {
00107 
00108     //Opens the message queue input to the inverter.
00109     _LIT(KGlobalInverterInQ, "InverterInQ");
00110     TInt ret = iInMsgQ.OpenGlobal(KGlobalInverterInQ); 
00111         
00112         if (ret == KErrNone)
00113         {
00114         //Recieve the message coming from the first process.
00115         iMsgQData.Zero();
00116         iInMsgQ.ReceiveBlocking(iMsgQData);
00117         
00118         //If the recieved data indicates stop command, stop the system.
00119         if(iMsgQData[0]==EKeyEscape)
00120                         {
00121                         this->Stop();
00122                         return KErrStop;
00123                         }
00124         }
00125         return KErrNone;
00126     }
00127 
00131 void CInverter::SendMsg()
00132         {
00133         //Opens the global message Queue named InverterOutQ.
00134         _LIT(KGlobalInverterOutQ, "InverterOutQ");
00135         TInt ret = iOutMsgQ.OpenGlobal(KGlobalInverterOutQ); 
00136         
00137         //Sends the inverted words to the opened message queue.
00138         if (ret == KErrNone)
00139         {
00140         DoInvert();
00141         iOutMsgQ.SendBlocking(idestMsg);
00142         }
00143         }
00144 
00148 void CInverter::DoInvert()
00149 {
00150 idestMsg.Zero();
00151 TInt i=0; 
00152 while(iMsgQData[i]!= '\r')
00153 {
00154         while((iMsgQData[i]!= ' ')&&(iMsgQData[i]!= '\r'))
00155         {
00156         iwords.Append(iMsgQData[i]);
00157         i++; 
00158         }
00159         ReverseWord(iwords);
00160         idestMsg.Append(itmpWord); 
00161         idestMsg.Append(' ');
00162         if(iMsgQData[i]== '\r')
00163         {
00164         i--;
00165         }
00166         i++;
00167         iwords.Zero();
00168     }
00169 }
00170 
00174 void CInverter::ReverseWord(TBuf<20> buf)
00175         {
00176         itmpWord.Zero();
00177         TInt size = (buf.Size())/2;
00178         for(int i=1; i<= size; i++)
00179                 {
00180                 itmpWord.Append(buf[size -i]);
00181                 }
00182         }
00183 
00188 void CInverter::Stop()
00189         {
00190         iTimer->Cancel();
00191         CActiveScheduler::Stop();
00192         }
00193 
00194 LOCAL_C void DoStartL()
00195         {
00196 
00197         CActiveScheduler* scheduler = new (ELeave) CActiveScheduler();
00198         CleanupStack::PushL(scheduler);
00199         CActiveScheduler::Install(scheduler);   
00200         
00201         CInverter* invert = CInverter::NewL();
00202         CleanupStack::PushL(invert);
00203         
00204         //Start the scheduler for the periodic timer
00205         CActiveScheduler::Start();
00206         
00207         CleanupStack::PopAndDestroy(invert);
00208         CleanupStack::PopAndDestroy(scheduler);
00209         }
00210 
00211 GLDEF_C TInt E32Main()
00212         {
00213         __UHEAP_MARK;
00214         CTrapCleanup* cleanup = CTrapCleanup::New();
00215         if(cleanup == NULL)
00216                 {
00217                 return KErrNoMemory;
00218                 }
00219         
00220 
00221         TRAPD(mainError, DoStartL());
00222         if(mainError != KErrNone)
00223                 {
00224                 _LIT(KUserPanic,"Failed to complete");  
00225                 User::Panic(KUserPanic, mainError);
00226                 }
00227 
00228                 delete cleanup;
00229                 __UHEAP_MARKEND;
00230                 return KErrNone;
00231         }

Generated by  doxygen 1.6.2