diff -r 000000000000 -r f5a58ecadc66 upnp/upnpstack/upnputils/src/upnpfileutils.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/upnp/upnpstack/upnputils/src/upnpfileutils.cpp Tue Feb 02 01:12:20 2010 +0200 @@ -0,0 +1,631 @@ +/** @file +* Copyright (c) 2005-2006 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: File utils + * +*/ + + +// INCLUDES +#include +#include +#include +#include +#include +#include +#define KLogFile _L("DLNAWebServer.txt") +#include "upnpcustomlog.h" +#include "upnpcons.h" +#include "upnpfileutils.h" +#include "upnpstring.h" +#include "uri8.h" +#include "in_sock.h" + +// ================= MEMBER FUNCTIONS ======================= +namespace UpnpFileUtil + { + // ----------------------------------------------------------------------------- + // UpnpFileUtil::ReadFileL + // Reads the specified file and returns a pointer to HBufC8 holding the + // information. + // ----------------------------------------------------------------------------- + // + EXPORT_C HBufC8* ReadFileL(const TDesC16& aFilename) + { + LOGS1("UpnpFileUtil::ReadFileL - File: %S", &aFilename); + + RFs fs; + HBufC8* buffer = NULL; + TInt error = fs.Connect(); + if ( error == KErrNone ) + { + CleanupClosePushL( fs ); + + RFile file; + error = file.Open(fs, aFilename, EFileRead|EFileShareAny ); + if ( error == KErrNone ) + { + CleanupClosePushL( file ); + + TInt fileSize; + error = file.Size(fileSize); + if ( error == KErrNone ) + { + buffer = HBufC8::NewLC(fileSize); + buffer->Des().SetLength(0); + + TPtr8 ptr = buffer->Des(); + error = file.Read( ptr ); + if ( error == KErrNone ) + { + CleanupStack::Pop( buffer ); + } + else + { + CleanupStack::PopAndDestroy( buffer ); + buffer = NULL; + } + } + + // Close File + CleanupStack::PopAndDestroy(); + } + else + { + LOGS1("UpnpFileUtil::ReadFileL - RFile::Open() failed: %d", error); + } + + // Close FS + CleanupStack::PopAndDestroy(); + } + else + { + LOGS1("UpnpFileUtil::ReadFileL - RFs::Connect() failed: %d", error ); + } + + // In case of an error, we leave as error would mean that the + // file system is down. Shouldn't fail in any other case. + User::LeaveIfError( error ); + + return buffer; + } + + // ----------------------------------------------------------------------------- + // UpnpFileUtil::GetMimeTypeForFileL + // - In emulator, checks the filename, and returns mimetype-string depending + // on extension. + // - In Target device, uses RApaLsSession (Application server) to find out + // file's mime type. + // ----------------------------------------------------------------------------- + // + EXPORT_C HBufC8* GetMimeTypeForFileL(const TDesC16& aFilename) + { + LOGS1("UpnpFileUtil::GetMimeTypeForFileL - Getting mime type for file: %S", &aFilename); + + HBufC8* mimetype = NULL; + + // Added extra functionality, due to DLNA requirements for XML files mime type. + // In mime type for xml files there should be explicitly defined used charset + // and RApaLsSession service doesn't provide such a functionality. + + // Check extension, if its .xml - set mime type to text/xml and check used encoding + _LIT8(KXmlUtf8, "text/xml; charset=\"utf-8\""); + TParse parse; + parse.Set( aFilename, NULL, NULL ); + TBufC16 ext( parse.Ext() ); + + if ( ext.FindC( KXml16 ) == 0 && ext.Length() == KXml16().Length() ) + { + // Extension says that's XML but we check content to be sure and get encoding + + + mimetype = HBufC8::NewL( KXmlUtf8().Length() ); + mimetype->Des().Zero(); + mimetype->Des().Append( KXmlUtf8() ); + return mimetype; + } + + // If it's not a XML file then use built-in service. + + RApaLsSession sess; + TInt error = sess.Connect(); + // We have FS, File and RApaLs open + if ( error == KErrNone ) + { + CleanupClosePushL( sess ); + + TUid id = TUid::Uid( 0 ); + + TDataType type; + + error = sess.AppForDocument( aFilename, id, type ); + if( error == KErrNone && type != TDataType()) + { + mimetype = HBufC8::NewL( type.Des8().Length() + UpnpString::KLineFeed().Length() ); + mimetype->Des().Append( type.Des8() ); + } + else + { + error = KErrNotFound; + LOGS1("UpnpFileUtil::GetMimeTypeForFileL - AppForDocument failed: %d", error ); + } + + CleanupStack::PopAndDestroy( &sess ); + } + else + { + LOGS1("UpnpFileUtil::GetMimeTypeForFileL - RFile::Open failed: %d", error ); + } + + if( error != KErrNone) + { + mimetype = GetMimeTypeByExtensionL( aFilename ); + } + + LOGS("UpnpFileUtil::GetMimeTypeForFileL - MIME type resolved: " ); + LOGT( mimetype->Des() ); + + return mimetype; + } + + // ----------------------------------------------------------------------------- + // UpnpFileUtil::GetMimeTypeByExtensionL + // - In emulator, checks the filename, and returns mimetype-string depending + // on extension. + // - In Target device, uses RApaLsSession (Application server) to find out + // file's mime type. + // ----------------------------------------------------------------------------- + // + HBufC8* GetMimeTypeByExtensionL( const TDesC16& aFilename ) + { + LOGS("UpnpFileUtil::GetMimeTypeForFileL - Starting search by file extension"); + + HBufC8* mimetype = NULL; + + TParse parse; + + parse.Set( aFilename, NULL, NULL ); + + TBufC16 ext( parse.Ext() ); + + // FindC and length calculation is used, + // beacause compareC does not work for undefined reason + + if ( ext.FindC( KHtml16 ) == 0 && ext.Length() == KHtml16().Length() ) + { + mimetype = HBufC8::NewLC( KHtml().Length() ); + mimetype->Des().Zero(); + mimetype->Des().Append( KHtml() ); + } + else if ( ext.FindC( KXml16 ) == 0 && ext.Length() == KXml16().Length() ) + { + mimetype = HBufC8::NewLC( KXml().Length() ); + mimetype->Des().Zero(); + mimetype->Des().Append( KXml() ); + } + else if ( ext.FindC( KTxt16 ) == 0 && ext.Length() == KTxt16().Length() ) + { + mimetype = HBufC8::NewLC( KTxt().Length() ); + mimetype->Des().Zero(); + mimetype->Des().Append( KTxt() ); + } + else if ( ( ext.FindC( KJpg16 ) == 0 && ext.Length() == KJpg16().Length() ) || + ( ext.FindC( KJpeg16 ) == 0 && ext.Length() == KJpeg16().Length() ) ) + { + mimetype = HBufC8::NewLC( KJpg().Length() ); + mimetype->Des().Zero(); + mimetype->Des().Append( KJpg() ); + } + else if ( ext.FindC( KGif16 ) == 0 && ext.Length() == KGif16().Length() ) + { + mimetype = HBufC8::NewLC( KGif().Length() ); + mimetype->Des().Zero(); + mimetype->Des().Append( KGif() ); + } + else if ( ext.FindC( KPng16 ) == 0 && ext.Length() == KPng16().Length() ) + { + mimetype = HBufC8::NewLC( KPng().Length() ); + mimetype->Des().Zero(); + mimetype->Des().Append( KPng() ); + } + else if ( ( ext.FindC( KMpg16 ) == 0 && ext.Length() == KMpg16().Length() ) || + ( ext.FindC( KMpeg16 ) == 0 && ext.Length() == KMpeg16().Length() ) ) + { + mimetype = HBufC8::NewLC( KMpeg().Length() ); + mimetype->Des().Zero(); + mimetype->Des().Append( KMpeg() ); + } + else if ( ext.FindC( KAvi16 ) == 0 && ext.Length() == KAvi16().Length() ) + { + mimetype =HBufC8::NewLC( KAvi().Length() ); + mimetype->Des().Zero(); + mimetype->Des().Append( KAvi() ); + } + else if ( ext.FindC( KMp316 ) == 0 && ext.Length() == KMp316().Length() ) + { + mimetype = HBufC8::NewLC( KMp3().Length() ); + mimetype->Des().Zero(); + mimetype->Des().Append( KMp3() ); + } + + // If type was not found, then set empty it here + if ( !mimetype ) + { + // We can't return mimetype=NULL; + + // Allocate one lenght mime. + mimetype = HBufC8::NewLC( 1 ); + } + CleanupStack::Pop( mimetype ); + + return mimetype; + } + + // ----------------------------------------------------------------------------- + // ExtractNumFromIP + // ----------------------------------------------------------------------------- + // + TInt ExtractNumFromIP(TPtrC8 ippart) + { + + TInt ipdef=KIPNumMin; + TLex8 lexip = TLex8(ippart); + TInt errorip = lexip.Val(ipdef); + + if (errorip == KErrNone) + return ipdef; + else + return KErrNotFound; + + } + // ----------------------------------------------------------------------------- + // Returns drive number + // ----------------------------------------------------------------------------- + // + TInt DriveNumberFromPath( const TDesC16& aPath, RFs& aFs ) + { + TInt drive_num; + TParse p; + p.Set( aPath, NULL, NULL ); + TPtrC pointer = p.Drive(); + TLex lineParser( pointer.Ptr() ); + TChar ch = lineParser.Get(); + + //sets the default drive or the found value + if( aFs.CharToDrive( ch, drive_num ) 3 ) || (posOfFirstDot < 1))) + { + return EFalse; + } + else + { + TPtrC8 ip1; + ip1.Set( hostt.Left( posOfFirstDot)); + + TInt ip1def = ExtractNumFromIP(ip1); + + if ((ip1def> KIPNumMax) || (ip1def < KIPNumMin )) + { + return EFalse; + } + + hostt.Set(hostt.Mid(posOfFirstDot + UpnpString::KDot8().Length())); + posOfSecondDot = hostt.FindC( UpnpString::KDot8() ); + + //position of the dot in IP address must from 1 to 3 starting from the position of former dot + if( (posOfSecondDot < KErrNone) || ((posOfSecondDot> 3 ) || (posOfSecondDot < 1))) + { + return EFalse; + } + else + { + TPtrC8 ip2; + ip2.Set( hostt.Left( posOfSecondDot)); + + ip1def = ExtractNumFromIP(ip2); + + if ((ip1def == KErrNotFound) || (ip1def> KIPNumMax)) + { + return EFalse; + } + + hostt.Set(hostt.Mid(posOfSecondDot + UpnpString::KDot8().Length())); + posOfThirdDot = hostt.FindC( UpnpString::KDot8() ); + + //position of the dot in IP address must from 1 to 3 starting from the position of former dot + if( (posOfThirdDot < KErrNone ) || ((posOfThirdDot> 3 ) || (posOfThirdDot < 1))) + { + return EFalse; + } + else + { + TPtrC8 ip3; + ip3.Set( hostt.Left( posOfThirdDot)); + + ip1def = ExtractNumFromIP(ip3); + + if ((ip1def == KErrNotFound) || (ip1def> KIPNumMax)) + { + return EFalse; + } + + TPtrC8 ip4; + ip4.Set(hostt.Mid(posOfThirdDot + UpnpString::KDot8().Length())); + + //position of the dot in IP address must from 1 to 3 starting from the position of former dot + if((ip4.Length() < 1) || (ip4.Length()> 3)) + { + return EFalse; + } + + ip1def = ExtractNumFromIP (ip4); + + if ((ip1def == KErrNotFound) || (ip1def> KIPNumMax)) + { + return EFalse; + } + else + { + return ETrue; + } + + } + } + } + } + + // ----------------------------------------------------------------------------- + // ExtractUrlPath + // ----------------------------------------------------------------------------- + // + EXPORT_C TPtrC8 ExtractUrlPath( + const TDesC8& aUrl, TPtrC8& aFilename, TPtrC8& aScheme, TInt& aParseError ) + { + + LOGS("CHttpFolderUrlMatch::ExtractUrlPath()"); + TUriParser8 up; + aParseError = up.Parse(aUrl); + if( aParseError != KErrNone) + { + return KNullDesC8(); + } + TPtrC8 path(up.Extract(EUriPath)); + TPtrC8 scheme(up.Extract(EUriScheme)); + TPtrC8 port(up.Extract(EUriPort)); + TPtrC8 host(up.Extract(EUriHost)); + TInt position (0); + TPtrC8 urlPath; + + if(up.IsPresent(EUriScheme)) + { + + if(scheme.Compare(UpnpHTTP::KSchemeHTTP8()) == 0) + { + aScheme.Set(scheme); + + //separator test + position = aUrl.FindC(UpnpHTTP::KSchemeSeparator()); + if (position != KErrNotFound) + { + if ((up.IsPresent(EUriHost)) && (host != KNullDesC8())) + { + if( ExtractUrlPathHost(aUrl, aParseError ) ) + { + TUint portdef(0); + TLex8 lex = TLex8(port); + TInt error = lex.Val(portdef, EDecimal); + if((up.IsPresent(EUriPort)) && (port != KNullDesC8()) && (error == KErrNone) ) + { + urlPath.Set(path); + } + else + { + return KNullDesC8(); + } + } + else + { + return KNullDesC8(); + } + } + else + { + return KNullDesC8(); + } + } + else + { + return KNullDesC8(); + } + + } + else + { + return KNullDesC8(); + } + } + else + { + TInt posOfFirstSlashnohttp( 0 ); + posOfFirstSlashnohttp = path.FindC( UpnpString::KSlash() ); + + if( (posOfFirstSlashnohttp < KErrNone ) || (posOfFirstSlashnohttp != 0)) + { + return KNullDesC8(); + } + else + { + urlPath.Set(aUrl); + } + } + + TInt posOfFirstSlash( 0 ); + TInt posOfLastSlash( 0 ); + posOfFirstSlash = urlPath.FindC( UpnpString::KSlash() ); + + if( posOfFirstSlash < KErrNone ) + { + return KNullDesC8(); + } + else + { + TInt posOfTwoSlashes( 0 ); + posOfTwoSlashes = urlPath.FindC(UpnpString::KDoubleSlash()); + if((posOfTwoSlashes == KErrNone ) || (posOfTwoSlashes> KErrNone) ) + { + return KNullDesC8(); + } + posOfLastSlash = urlPath.LocateReverse( UpnpString::KSlash()[0] ); + if( posOfLastSlash == posOfFirstSlash ) + { + aFilename.Set( urlPath.Mid( posOfLastSlash + UpnpString::KSlash().Length()) ); + return KNullDesC8(); + } + else + { + aFilename.Set( urlPath.Mid( posOfLastSlash + UpnpString::KSlash().Length()) ); + urlPath.Set( urlPath.Mid( posOfFirstSlash + UpnpString::KSlash().Length() ) ); + urlPath.Set( urlPath.Left( posOfLastSlash - UpnpString::KSlash().Length() ) ); + return urlPath; + + } + } + } + + // ----------------------------------------------------------------------------- + // ExtractUrlPath + // ----------------------------------------------------------------------------- + // + EXPORT_C TPtrC8 ExtractUrlPath(const TDesC8& aUrl, TInt& aParseError ) + { + TPtrC8 fileName; + TPtrC8 scheme; + return ExtractUrlPath(aUrl, fileName, scheme, aParseError ); + } + // ----------------------------------------------------------------------------- + // ExtractUrlPath + // ----------------------------------------------------------------------------- + // + EXPORT_C TPtrC8 ExtractUrlPath(const TDesC8& aUrl, TPtrC8& aFilename, TInt& aParseError) + { + TPtrC8 scheme; + return ExtractUrlPath(aUrl, aFilename, scheme, aParseError ); + } + + // ----------------------------------------------------------------------------- + // ConvertUrlToFolder + // ----------------------------------------------------------------------------- + // + EXPORT_C HBufC8* SwitchToBackSlashL(const TDesC8& aUrl) + { + TInt position( 0 ); + + HBufC8* result = HBufC8::NewL(aUrl.Length() + aUrl.Length()/2); + + TPtr8 ptrResult(result->Des()); + ptrResult.Copy(aUrl); + + // replace / with '\\' + while ( ( position = ptrResult.Locate( UpnpString::KSlash()[0] ) ) != KErrNotFound ) + { + ptrResult.Replace( position, 1, UpnpString::KDoubleBackSlash() ); + } + return result; + + } + // ----------------------------------------------------------------------------- + // ConvertUrlToFolder + // ----------------------------------------------------------------------------- + // + EXPORT_C HBufC* SwitchToBackSlashL(const TDesC& aUrl) + { + TInt position( 0 ); + + HBufC* result = HBufC::NewL(aUrl.Length() + aUrl.Length()/2); + + TPtr ptrResult(result->Des()); + ptrResult.Copy(aUrl); + + // replace / with '\\' + while ( ( position = ptrResult.Locate( UpnpString::KSlash()[0] ) ) != KErrNotFound ) + { + ptrResult.Replace( position, 1, UpnpString::KDoubleBackSlash16() ); + } + return result; + + } + // ----------------------------------------------------------------------------- + // Checks if the disk is short of the space requested + // ----------------------------------------------------------------------------- + // + EXPORT_C TBool CheckDiskSpaceShortL( const TDesC16& aPath, TInt aSize, RFs& aFs ) + { + TInt drive_num = UpnpFileUtil::DriveNumberFromPath( aPath, aFs ); + return SysUtil::DiskSpaceBelowCriticalLevelL ( &aFs, aSize, drive_num ); + } + + // ----------------------------------------------------------------------------- + // Checks if the disk is short of the space requested + // ----------------------------------------------------------------------------- + // + EXPORT_C TBool CheckDiskSpaceShortL( TDriveNumber aDriveNumber, TInt aSize ) + { + RFs fs; + User::LeaveIfError( fs.Connect() ); + CleanupClosePushL( fs ); + TBool result = SysUtil::DiskSpaceBelowCriticalLevelL ( &fs, aSize, aDriveNumber ); + CleanupStack::PopAndDestroy( &fs ); + return result; + } + + // ----------------------------------------------------------------------------- + // Parses uri + // ----------------------------------------------------------------------------- + // + EXPORT_C TInt ParseUri( const TDesC8& aUrl ) + { + TUriParser8 up; + return up.Parse( aUrl ); + } + + + } + +// End of File