// EncCache.cpp // // Example code for making a list of codecs available // // Otfried Cheong // #include #include #include #include #include #include #include "ufcodec.h" class CUniEncoderCache : public CBase { public: static CUniEncoderCache *NewL(RFs &aFs); ~CUniEncoderCache(); // Find Encodings supported inline TInt NumEncodings() const; inline TDesC &EncodingName(TInt anIndex) const; inline TUid EncodingUid(TInt anIndex) const; void ReleaseEncoding(TInt anIndex); // Get pointer to encoder CUniEncoder *EncoderL(TInt anIndex); CUniEncoder *EncoderL(TUid aUid); private: CUniEncoderCache() {} void CollectEncodingsL(RFs &aFs); // Encodings struct TCodingSystem { RLibrary iDll; TFileName iDllName; CUniEncoder *iEncoder; TUid iUid; TBuf<0x20> iName; }; CArrayFixFlat *jCodingSystem; }; inline TInt CUniEncoderCache::NumEncodings() const { return jCodingSystem->Count(); } inline TDesC &CUniEncoderCache::EncodingName(TInt anIndex) const { return (*jCodingSystem)[anIndex].iName; } inline TUid CUniEncoderCache::EncodingUid(TInt anIndex) const { return (*jCodingSystem)[anIndex].iUid; } // -------------------------------------------------------------------- CUniEncoderCache *CUniEncoderCache::NewL(RFs &aFs) { CUniEncoderCache *This = new (ELeave) CUniEncoderCache(); This->CollectEncodingsL(aFs); return This; } CUniEncoderCache::~CUniEncoderCache() { // release encoding Dlls if (jCodingSystem) { for (TInt i = 0; i < jCodingSystem->Count(); i++) ReleaseEncoding(i); delete jCodingSystem; } } // -------------------------------------------------------------------- // // Encoding/decoding // void CUniEncoderCache::ReleaseEncoding(TInt anIndex) { if ((*jCodingSystem)[anIndex].iEncoder) { delete (*jCodingSystem)[anIndex].iEncoder; (*jCodingSystem)[anIndex].iEncoder = 0; (*jCodingSystem)[anIndex].iDll.Close(); } } CUniEncoder *CUniEncoderCache::EncoderL(TInt anIndex) { if (!(*jCodingSystem)[anIndex].iEncoder) { (*jCodingSystem)[anIndex].iDll.Load((*jCodingSystem)[anIndex].iDllName); TLibraryFunction entry = (*jCodingSystem)[anIndex].iDll.Lookup(1); (*jCodingSystem)[anIndex].iEncoder = (CUniEncoder *) ((*entry)()); if ((*jCodingSystem)[anIndex].iEncoder == 0) { (*jCodingSystem)[anIndex].iDll.Close(); User::Leave(KErrNotSupported); } } return (*jCodingSystem)[anIndex].iEncoder; } CUniEncoder *CUniEncoderCache::EncoderL(TUid aUid) { for (TInt i = 0; i < jCodingSystem->Count(); ++i) { if ((*jCodingSystem)[i].iUid == aUid) { return EncoderL(i); } } return 0; } // ------------------------------------------------------------------ class CUtf8Encoder : public CUniEncoder { virtual TText16 DecodeWChar(TText16 aChar) { return aChar; } virtual TText16 EncodeWChar(TText16 aChar) { return aChar; } virtual HBufC8 *EncodeTextL(const TDesC8 &aText, TBool) { return aText.AllocL(); } virtual HBufC8 *DecodeTextL(const TDesC8 &aText) { return aText.AllocL(); } }; // ------------------------------------------------------------------ void CUniEncoderCache::CollectEncodingsL(RFs &aFs) { // find encodings jCodingSystem = new (ELeave) CArrayFixFlat(0x10); TCodingSystem aUtf8; aUtf8.iEncoder = new (ELeave) CUtf8Encoder; aUtf8.iName = _L("UTF-8"); aUtf8.iUid = KEncodingUidUtf8; jCodingSystem->AppendL(aUtf8); TUidType aUidType(KDynamicLibraryUid, KUniEncoderUid, KNullUid); TFileName aEncodingDir = _L("!:\\System\\UniFEP\\Encoding\\*.dll"); TInt drive = 'z'; do { drive--; if (drive < 'a') drive = 'z'; aEncodingDir[0] = drive; CDir *fileList; if (aFs.GetDir(aEncodingDir, aUidType, ESortByName, fileList) == KErrNone) { for (TInt j = 0; j < fileList->Count(); j++) { TPtrC aFileName = (*fileList)[j].iName; TParse parse; parse.Set(aFileName, &aEncodingDir, NULL); TCodingSystem aCodingSystem; aCodingSystem.iName = parse.Name(); aCodingSystem.iDllName = parse.FullName(); aCodingSystem.iUid = (*fileList)[j].MostDerivedUid(); aCodingSystem.iEncoder = 0; jCodingSystem->AppendL(aCodingSystem); } } delete fileList; } while (drive != 'z'); } // --------------------------------------------------------------------