--- /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 <e32base.h>
+#include <charconv.h>
+#include <f32file.h>
+#include <apgcli.h>
+#include <apmrec.h>
+#include <sysutil.h>
+#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<KMaxName> 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<KMaxName> 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 )<KErrNone )
+ {
+ drive_num=EDriveC;
+ }
+ return drive_num;
+ }
+
+ // -----------------------------------------------------------------------------
+ // ExtractUrlPathHost
+ // -----------------------------------------------------------------------------
+ //
+ TBool ExtractUrlPathHost(const TDesC8& aUrl, TInt& aParseError )
+ {
+ TUriParser8 up;
+ aParseError = up.Parse(aUrl);
+ if ( aParseError != KErrNone )
+ {
+ return EFalse;
+ }
+
+ TPtrC8 hostt(up.Extract(EUriHost));
+ TInt posOfFirstDot( 0 );
+ TInt posOfSecondDot( 0 );
+ TInt posOfThirdDot( 0 );
+
+ posOfFirstDot = hostt.FindC( UpnpString::KDot8() );
+
+ //position of the first dot in IP address must be from 1 to 3
+ if( (posOfFirstDot < KErrNone ) || ((posOfFirstDot> 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