// EXAMPLECONV.h
//
// Copyright (c) 2006 Symbian Software Ltd. All rights reserved.
//
//
#if (!defined __EXAMPLECONV_H__)
#define __EXAMPLECONV_H____
#include <conarc.h>
#include <ecom.h>
#include <ImplementationProxy.h>
// CExampleConverter inherits from the abstract base class CConverterBase2.
// CConverterBase2 is the base class for ECom style converters.
class CExampleConverter : public CConverterBase2
{
public: static CConverterBase2* NewL();
CExampleConverter();
~CExampleConverter();
// from CConverterBase
void ConvertObjectAL(RReadStream& aReadStream, RWriteStream& aWriteStream, MConverterUiObserver* aObserver=NULL);
TBool DoConvertL();
TUid Uid();
TInt Capabilities();
void CancelConvert();
private:
RReadStream* iReadStream;
RWriteStream* iWriteStream;
TBuf8<3> iBuffer;
TInt iBufferPos;
};
#endif /* __EXAMPLECONV_H___ */
// ExampleConv.cpp
//
// Copyright (c) 2006 Symbian Software Ltd. All rights reserved.
// This is an example converter that converts a file containing
// text encoded in quoted-printable to plain text.
//
#include <conarc.h>
#include <ecom.h>
#include <ImplementationProxy.h>
#include "ExampleConv.hrh"
#include "ExampleConv.h"
#include <E32STD.H>
#include <e32uid.h>
#include <S32STRM.H>
#define KLineFeed 10
#define KCarriageReturn 13
#define KEquals '='
CConverterBase2* CExampleConverter::NewL()
{
CConverterBase2* egConv=new (ELeave) CExampleConverter();
return egConv;
}
// Standard ECOM factory code
const TImplementationProxy ImplementationTable[] =
{
IMPLEMENTATION_PROXY_ENTRY(KExampleConvImplementationUid,CExampleConverter::NewL)
};
// Standard ECOM factory code
EXPORT_C const TImplementationProxy* ImplementationGroupProxy(TInt& aTableCount)
{
aTableCount = sizeof(ImplementationTable) / sizeof(TImplementationProxy);
return ImplementationTable;
}
// Prepares the converter for conversion. This is called by the converter's ConvertObjectL()
// once before calling DoConvertL() in a loop.
void CExampleConverter::ConvertObjectAL(RReadStream& aReadStream, RWriteStream& aWriteStream, MConverterUiObserver* /*aObserver*/)
{
iReadStream = &aReadStream;
iWriteStream = &aWriteStream;
iBufferPos = 0;
iBuffer.SetMax();
}
// Performs a step in converting the data. Called by the converter's ConvertObjectL()
// repeatedly until it returns false.
TBool CExampleConverter::DoConvertL()
{
// Check if we need to move out the oldest character
if (iBufferPos == 3)
{
iBuffer[0] = iBuffer[1];
iBuffer[1] = iBuffer[2];
iBufferPos = 2;
}
TBuf8<1> character;
TRAPD(err, iReadStream->ReadL(character));
if (err == KErrEof)
{
// Write what we have in the buffer, and exit
iWriteStream->WriteL(iBuffer, iBufferPos);
return EFalse;
}
else if (err == KErrNone)
{
iBuffer[iBufferPos] = character[0];
iBufferPos++;
if (iBufferPos == 3)
{
// Check that we have three characters to compare:
if (iBuffer[0] == KEquals)
{
// Check for special QP codes
if (!(iBuffer[1] == KCarriageReturn && iBuffer[2] == KLineFeed))
{
// act on the code
TLex8 lex(iBuffer);
TUint code;
(void)lex.Get(); // skip the equals
lex.Val(code,EHex);
iWriteStream->WriteUint8L(STATIC_CAST(TUint8,code));
}
iBufferPos=0;
}
else if (iBuffer[1] == KCarriageReturn && iBuffer[2] == KLineFeed)
{
// throw away these characters
iBufferPos=0;
}
else
{
// Write out the last character in the stream
iWriteStream->WriteUint8L(iBuffer[0]);
}
}
}
else
{
// Some other error
return EFalse;
}
return ETrue;
}
TUid CExampleConverter::Uid()
{
return TUid::Uid(KExampleConvImplementationUid);
}
TInt CExampleConverter::Capabilities()
{
return EConvertsObjects;
}
// Cleans up after the conversion.
void CExampleConverter::CancelConvert()
{
iReadStream->Close();
iWriteStream->Close();
}
CExampleConverter::CExampleConverter()
{
}
CExampleConverter::~CExampleConverter()
{
}
// BLD.INF
//
// Copyright (c) 2006 Symbian Software Ltd. All rights reserved.
//
PRJ_MMPFILES
ExampleConv.MMP
// ExampleConv.MMP
//
// Copyright (c) 2006 Symbian Software Ltd. All rights reserved.
target EXAMPLECONV.dll
targettype plugin
UID 0x10009d8d 0xE800009B
VENDORID 0x70000001
CAPABILITY All -Tcb
sourcepath .
start resource E800009B.rss
target exampleconv.rsc
end
start resource 10207F6A.rss
targetpath \resource\convert
end
userinclude .
systeminclude . \epoc32\include
systeminclude \epoc32\include\ecom
source ExampleConv.CPP
library EUSER.LIB
library CONARC.LIB estor.lib
// UsingConverter.cpp
//
// Copyright (c) 2006 Symbian Software Ltd. All rights reserved.
//
///
// This code demonstrates how to use a file converter.
#include <e32base.h>
#include <e32cons.h>
#include <s32file.h>
#include <s32mem.h>
#include <conarc.h>
#include <concnf.h>
#include <conlist.h>
#include <bautils.h>
#include "usingconverter.h"
#include <ecom.h>
static CConsoleBase* gConsole;
_LIT8(KFromType,"example/qp");
_LIT8(KToType,"example/text");
_LIT(KLitOriginalQuotedPrintableFile, "c:\\Private\\E800009C\\w7allchr.doc.qp");
_LIT(KLitGeneratedDocFileFromQuotedPrintable, "c:\\Private\\E800009C\\w7allchr.doc.qp.doc");
void CUsingConverter::ConvertFileL(CCnaConverterList& aList, TInt aConverterUid, const TDesC& aInputFile, const TDesC& aOutputFile)
{
// Finds the converter with the specified UID, loads its DLL and returns a pointer to it
CConverterBase* const converter=aList.NewConverterL(TUid::Uid(aConverterUid));
if(converter==NULL)
{
_LIT(KConsoleMessage, "\nConverter not found");
gConsole->Printf(KConsoleMessage);
User::Leave(KErrNotFound);
}
else
{
CleanupStack::PushL(converter);
if(converter->Uid().iUid==aConverterUid)
{
_LIT(KConsoleMessage1, "\nCorrect Uid");
gConsole->Printf(KConsoleMessage1);
if(converter->Capabilities()&CConverterBase::EConvertsObjects)
{
_LIT(KConsoleMessage2, "\nCorrect Capability");
gConsole->Printf(KConsoleMessage2);
RFileReadStream inputStream;
CleanupClosePushL(inputStream);
RFileWriteStream outputStream;
CleanupClosePushL(outputStream);
User::LeaveIfError(inputStream.Open(iFs, aInputFile, EFileShareReadersOnly|EFileStream|EFileRead));
User::LeaveIfError(outputStream.Replace(iFs, aOutputFile, EFileShareExclusive|EFileStream|EFileWrite));
// this calls the converter's DoConvertL() and ConvertObjectAL()
converter->ConvertObjectL(inputStream, outputStream);
outputStream.CommitL();
CleanupStack::PopAndDestroy(2,&inputStream);
_LIT(KConsoleMessage3, "\nFile converted successfully");
gConsole->Printf(KConsoleMessage3);
}
else
{
_LIT(KConsoleMessage4, "\nIncorrect Capability");
gConsole->Printf(KConsoleMessage4);
}
}
else
{
_LIT(KConsoleMessage5, "\nIncorrect UID");
gConsole->Printf(KConsoleMessage5);
}
CleanupStack::PopAndDestroy(converter);
}
}
void CUsingConverter::EgConverterL()
{
// connects to the file server
iFs.Connect();
// creates the executable's private directory (which stores the input and output files)
User::LeaveIfError(iFs.CreatePrivatePath(EDriveC));
// gets a list of available converters.
CCnaConverterList* const list=CCnaConverterList::NewLC();
// Gets the uid of the converter that converts from the source to the target data types
TUid cuid =list->ConverterL(TDataType(KFromType),TDataType(KToType));
ConvertFileL(*list,cuid.iUid,KLitOriginalQuotedPrintableFile, KLitGeneratedDocFileFromQuotedPrintable);
CleanupStack::PopAndDestroy(list);
}
CUsingConverter::~CUsingConverter()
{
// Closes the session with the file server
iFs.Close();
}
CUsingConverter::CUsingConverter()
{
}
static void DoExampleL()
{
// Create the console to print the messages to.
_LIT(KConsoleMessageDisplay, "Converter Example");
_LIT(KConsoleStars,"\n*************************\n");
gConsole = Console::NewL(KConsoleMessageDisplay,TSize(KConsFullScreen,KConsFullScreen));
CleanupStack::PushL(gConsole);
gConsole->Printf(KConsoleMessageDisplay);
gConsole->Printf(KConsoleStars);
CUsingConverter* example= new(ELeave) CUsingConverter();
TRAPD(err, example->EgConverterL());
if (err)
{
_LIT(KFailed,"\n\nExample failed: leave code=%d");
gConsole->Printf(KFailed, err);
}
delete example;
// wait for user to press a key before destroying gConsole
_LIT(KMsgPressAnyKey, "\nPress any key to continue");
gConsole->Printf(KMsgPressAnyKey);
gConsole->Getch();
//This method is called once all the ECOM implementations
//are destroyed
REComSession::FinalClose();
CleanupStack::PopAndDestroy(gConsole);
}
// Standard entry point function
GLDEF_C TInt E32Main()
{
__UHEAP_MARK;
// Active scheduler required as this is a console app
CActiveScheduler* scheduler=new CActiveScheduler;
// If active scheduler has been created, install it.
if (scheduler)
{
CActiveScheduler::Install(scheduler);
// Cleanup stack needed
CTrapCleanup* cleanup=CTrapCleanup::New();
if (cleanup)
{
TRAP_IGNORE(DoExampleL());
delete cleanup;
}
delete scheduler;
}
__UHEAP_MARKEND;
return KErrNone;
}
This example program consists of a converter DLL
(exampleconv.dll
), which converts quoted-printable text to plain
text and an executable (UsingConverter.exe
), which loads the
converter DLL and uses it to convert an example source file.
The source file containing quoted-printable text,
w7allchr.doc.qp
, is located in the executable's private directory
(c:\Private\E800009C\
). The output file,
w7allchr.doc.qp.doc
is generated in the same location.
To perform the conversion, UsingConverter.exe
first gets a
list of all available converters using
CCnaConverterList::NewLC()
. Next, it gets the UID of a
converter in the list that can convert from and to the required MIME types
(using CCnaConverterList::ConverterL()
), and uses this UID
to construct the converter (using
CCnaConverterList::NewConverterL()
). UsingConverter calls
CConverterBase2::ConvertObjectL()
, which in
turn calls CExampleConverter::ConvertObjectAL()
to prepare
the converter object to convert, using streams, then calls
CExampleConverter::DoConvertL()
until the conversion is
complete.