remotestoragefw/mountmanager/src/rsfwmountutils.cpp
author Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Wed, 14 Apr 2010 16:50:39 +0300
branchRCL_3
changeset 12 fe0554130c0f
parent 0 3ad9d5175a89
permissions -rw-r--r--
Revision: 201013 Kit: 201015

/*
* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
* All rights reserved.
* This component and the accompanying materials are made available
* under the terms of "Eclipse Public License v1.0"
* which accompanies this distribution, and is available
* at the URL "http://www.eclipse.org/legal/epl-v10.html".
*
* Initial Contributors:
* Nokia Corporation - initial contribution.
*
* Contributors:
*
* Description:  Utility functions for managing mount configurations
*
*/

// INCLUDES

#include <s32file.h>
#include <uri8.h>
#include <utf.h>
#include <ecom/ecom.h>
#include <ecom/implementationinformation.h>
#include <rsfwmountentry.h>

#include "rsfwmountutils.h"
#include "rsfwremoteaccess.h"


// CONSTANTS
// These keywords must match with the entry items
_LIT(KKId, "Fname");
_LIT(KKDrive, "Fdrv");
_LIT(KKUri, "Furi");
_LIT(KKUserName, "Fuid");
_LIT(KKPassword, "Fpsw");

_LIT(KMountMessagePrefix, "//vnd.nokia.s60.mount.config\n");

// ============================ MEMBER FUNCTIONS ==============================

// ----------------------------------------------------------------------------
// RsfwMountUtils::ImportMountEntryL
// ----------------------------------------------------------------------------
//
EXPORT_C void RsfwMountUtils::ImportMountEntryL(const TDesC& aMsg,
                                            CRsfwMountEntry** aEntry)
    {
    // Expected to start with
    // //vnd.nokia.s60.mount.config\n
    
    TPtrC prefix = aMsg.Left(KMountMessagePrefixLength);
    if (prefix.Compare(KMountMessagePrefix) != 0)
        {
        User::Leave(KErrNotFound);
        }
    
    // It is a mount configuration message
    CRsfwMountEntry* entry = CRsfwMountEntry::NewLC();

    TInt lineNumber = 0;

    // SMS rich text messages may be have trailing characters -
    // that looks like ')' characters
    TInt i = aMsg.Length() - 1;
    while (i > 0)
        {
        TUint8 c = static_cast<TUint8>(aMsg[i]);
        if (c != ')')
            {
            break;
            }
        i--;
        }
    TPtrC msg  = aMsg.Left(i + 1);

    TLex lex(msg);
    while (!lex.Eos())
        {
        lineNumber++;
        lex.SkipSpaceAndMark();
        while (lex.Peek() != '\n'  && !lex.Eos())
            {
            lex.Inc();
            }
        // The marked token is now the whole line
        TPtrC line = lex.MarkedToken();
        ParseLineL(line, *entry);
        if (!lex.Eos())
            {
            // Skip the '\n'
            lex.Inc();
            }
        }

    CleanupStack::Pop(entry);
    *aEntry = entry;
    }

// ----------------------------------------------------------------------------
// RsfwMountUtils::ImportMountEntryFromStreamL
// ----------------------------------------------------------------------------
//
EXPORT_C void RsfwMountUtils::ImportMountEntryFromStreamL(RReadStream& aReadStream,
													      TInt aSize,
                                                          CRsfwMountEntry** aEntry)
    {
    // the string is assumed to be 8-bit in stream, 
    // and should be converted to Unicode
    *aEntry = NULL;
    HBufC8* tempbuf = HBufC8::NewLC(aSize);
    TPtr8 tbufPtr = tempbuf->Des();
    tbufPtr.Zero();
    TRAPD(err, aReadStream.ReadL(tbufPtr));
    
    HBufC* buf = HBufC::NewLC(aSize);
    TPtr bufPtr = buf->Des();
    CnvUtfConverter::ConvertToUnicodeFromUtf8(bufPtr, tbufPtr);
    if ((err == KErrNone) || (err == KErrEof))
        {
        ImportMountEntryL(bufPtr, aEntry);
        }
    CleanupStack::PopAndDestroy(2, tempbuf); // buf, tempbuf 
    }

// ----------------------------------------------------------------------------
// RsfwMountUtils::ExportMountEntryL
// ----------------------------------------------------------------------------
//
EXPORT_C void RsfwMountUtils::ExportMountEntryL(const CRsfwMountEntry& aEntry,
                                                TBool aSendCredentials,
                                                TDes& aBuf)
    {
    aBuf.Copy(KMountMessagePrefix);
    TInt i;
    // smart messaging sends:
    // EMountEntryItemName
    // EMountEntryItemUri
    // if aSendCredentials sends also:
    // EMountEntryItemUserName
    // EMountEntryItemPassword 
    TInt lastToExport;
    if (aSendCredentials) 
        {
        lastToExport = EMountEntryItemPassword; 
        }
    else 
        {
        lastToExport = EMountEntryItemUri;
        }
    
    for (i = EMountEntryItemName; i < lastToExport + 1; i++)
        {
        if (i != EMountEntryItemDrive) 
        	{
        	const HBufC* item = aEntry.Item(i);
        	if (item && item->Length())
            	{
            	aBuf.Append(GetKeyWord(i));
            	aBuf.Append(':');
                const TPtrC ip(*item);
                aBuf.Append(ip);
            	aBuf.Append('\n');
            	}        	
        	}
       }
    }
 
// ----------------------------------------------------------------------------
// RsfwMountUtils::IsFriendlyNameValid
// ----------------------------------------------------------------------------
//
EXPORT_C TBool RsfwMountUtils::IsFriendlyNameValid(const TDesC& aFriendlyName)
    {
    TInt err;
    TBool retValue = ETrue;
    RFs fsSession;
    err = fsSession.Connect();
    if (err)
        {
        return retValue;
        }    
    retValue = fsSession.IsValidName(aFriendlyName);
    fsSession.Close();  
        
    // Some names are acceptable by RFs.IsValidName(), 
    // but not acceptable by RFs.SetDriveName()
    // Those are checked below:
        
    // solely period characters ( e.g. "...")
    if (retValue)
        {
        retValue = EFalse;
        TChar period(46); // period (".") character
        TInt i;
        for (i = 0; i < aFriendlyName.Length(); i++)
            {   
            if (aFriendlyName[i] != period)
                {
                retValue = ETrue;
                break;
                }
            }
        }
        
    // period as the last character ( e.g. "myDrive.")
    if (retValue)
        {
        TChar period(46); // period (".") character
        TInt nameLength = aFriendlyName.Length();
        if (nameLength > 0 && aFriendlyName[nameLength-1] == period)
            {
            retValue = EFalse;
            }
        }    

    return retValue;    
    }

// ----------------------------------------------------------------------------
// RsfwMountUtils::IsDriveAddressValid
// ----------------------------------------------------------------------------
//
EXPORT_C TBool RsfwMountUtils::IsDriveAddressValid(const TDesC8& aDriveAddress)
    {
    // extract the protocol
    TInt err;
    TUriParser8 parser;
    err = parser.Parse(aDriveAddress);
    if (err) 
    		{
    		return EFalse;	
    		}
    TPtrC8 protocol = parser.Extract(EUriScheme);
    
    
    TBuf8<KMaxMatchStringSize> matchString;
    _LIT8(KRemoteMatchPrefix, "remoteaccess/");
    matchString.Copy(KRemoteMatchPrefix);

    // Both "http" and "https" are handled by davaccess module
    _LIT8(KHttps, "https"); 
    if (protocol.Compare(KHttps) == 0)
        {
        _LIT8(KHttp, "http");   
        matchString.Append(KHttp);
        }
    else
        {
        matchString.Append(protocol);
        }
    TEComResolverParams resolverParams;
    resolverParams.SetDataType(matchString);
    // Disable wildcard matching
    resolverParams.SetWildcardMatch(EFalse);    
    
    
    // check whether there is a remote access plugin implementation for that protocol 
    RImplInfoPtrArray implinfo;
    TRAP(err, REComSession::ListImplementationsL(
                             KCRemoteAccessUid,
                             resolverParams,
                             implinfo));
    
    if (err != KErrNone) 
        {
        // if fetching the list of implemenations fail,'
        // (for example a temporary out of memory situation)
        // just accept the string
		implinfo.ResetAndDestroy();
        return ETrue;
        }
     
    // we assume that protocol used for remote access
    //  represents hierarchical relationships within the namespace.  This
    // "generic URI" syntax consists of a sequence of four main components:
    //      <scheme>://<authority><path>?<query>
    // check that scheme is followed by "://"
    _LIT8(KDelimiter, "://");
    if (aDriveAddress.Length() < protocol.Length()+3) 
        {
		implinfo.ResetAndDestroy();
        return EFalse;
        }
    
    TPtrC8 test = aDriveAddress.Mid(protocol.Length(), 3);
    if (!(test.Compare(KDelimiter) == 0)) 
        {
		implinfo.ResetAndDestroy();
        return EFalse;    
        }
    
    TInt count = implinfo.Count();
    implinfo.ResetAndDestroy();
    if (count > 0) 
        {
        return ETrue;
        }
    else 
        {
        return EFalse;
        }
    }

// ----------------------------------------------------------------------------
// RsfwMountUtils::ParseLineL
// ----------------------------------------------------------------------------
//
void RsfwMountUtils::ParseLineL(const TDesC& aLine,
                                CRsfwMountEntry& aEntry)
    {
    TLex lex(aLine);
    // Extract Line i.e "leftToken:RightToken<LF>", then asign to TLex object
    while (lex.Peek() != ':' && lex.Peek() != '\n' && !lex.Eos())
        {
        lex.Inc();
        }

    // We are only interested in lines containing a colon delimeter ':'
    // other text lines are ignored i.e "Welcome !<LF>"
    if(lex.Peek() != ':')
        {
        // It was not a name value pair
        return;
        }
    if (lex.TokenLength() == 0)
        {
        User::Leave(KErrNotFound);
        }
    // Get the keyword
    HBufC* keyWord = lex.MarkedToken().AllocLC();
    // Go past the ':'
    lex.Inc();
    lex.SkipSpaceAndMark();
    while (lex.Peek() != '\n' && lex.Peek() != '\r' && !lex.Eos())
        {
        lex.Inc();
        }

    TInt i;
    // Keyword matching
    // password is the last possible entry that is transferred
    for (i = EMountEntryItemName; i < EMountEntryItemPassword + 1; i++)
        {
        if (GetKeyWord(i).Compare(*keyWord) == 0)
            {
            aEntry.SetItemL(i, lex.MarkedToken());
            }
        }
    CleanupStack::PopAndDestroy(keyWord);
    }

// ----------------------------------------------------------------------------
// RsfwMountUtils::GetKeyWord
// ----------------------------------------------------------------------------
//
const TDesC& RsfwMountUtils::GetKeyWord(TInt iItem)
    {
    switch (iItem)
        {
    case EMountEntryItemName:
        return KKId;
        
    case EMountEntryItemDrive:
        return KKDrive;

    case EMountEntryItemUri:
        return KKUri;

    case EMountEntryItemUserName:
        return KKUserName;

    case EMountEntryItemPassword:
        return KKPassword;

    default:
        return KKId;
        }
    }
// End of File