os/ossrv/genericservices/httputils/Test/Integration/TestFileUriSuite/TestFileUriServer.cpp
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/ossrv/genericservices/httputils/Test/Integration/TestFileUriSuite/TestFileUriServer.cpp Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,393 @@
1.4 +// Copyright (c) 2004-2009 Nokia Corporation and/or its subsidiary(-ies).
1.5 +// All rights reserved.
1.6 +// This component and the accompanying materials are made available
1.7 +// under the terms of "Eclipse Public License v1.0"
1.8 +// which accompanies this distribution, and is available
1.9 +// at the URL "http://www.eclipse.org/legal/epl-v10.html".
1.10 +//
1.11 +// Initial Contributors:
1.12 +// Nokia Corporation - initial contribution.
1.13 +//
1.14 +// Contributors:
1.15 +//
1.16 +// Description:
1.17 +//
1.18 +
1.19 +/**
1.20 + @file
1.21 + @internalTechnology
1.22 +*/
1.23 +
1.24 +// System Include
1.25 +#include <escapeutils.h>
1.26 +
1.27 +// User Includes
1.28 +#include "TestFileUriServer.h"
1.29 +#include "TestCreateFileStep.h"
1.30 +#include "TestGetFileNameFromUriStep.h"
1.31 +#include "TestGenerateFileUriStep.h"
1.32 +#include "TestDeleteFileStep.h"
1.33 +#include "TestForAllFilesStep.h"
1.34 +
1.35 +// The system-wide unique name for the test-server
1.36 +_LIT(KServerName, "TestFileUriServer");
1.37 +
1.38 +TBuf<KMaxDrives> CTestFileUriServer::iRemovableDrives(KNullDesC);
1.39 +
1.40 +/**
1.41 +Static factory constructor. Creates and returns instance of the test server
1.42 +@return A pointer to the newly created CTestFileUriServer object
1.43 +*/
1.44 +CTestFileUriServer* CTestFileUriServer::NewL()
1.45 + {
1.46 + // Construct the server
1.47 + CTestFileUriServer* server = new(ELeave) CTestFileUriServer();
1.48 + CleanupStack::PushL(server);
1.49 +
1.50 + // CServer base class call
1.51 + // Name the server using the system-wide unique string
1.52 + // Clients use this to create server sessions.
1.53 + server->StartL(KServerName);
1.54 +
1.55 + CleanupStack::Pop(server);
1.56 + return server;
1.57 + }
1.58 +
1.59 +
1.60 +#if (!defined EKA2)
1.61 +
1.62 +/**
1.63 +Creates the Active Scheduler, then creates the test-server, synchronises the
1.64 +thread with the client and then enters the active scheduler.
1.65 +
1.66 +This is EKA1 version of MainL(). Uses sempahore to sync with client
1.67 +as Rendezvous calls are not available
1.68 +*/
1.69 +LOCAL_C void MainL()
1.70 + {
1.71 + // Create and install the active scheduler.
1.72 + CActiveScheduler* sched = NULL;
1.73 + sched = new(ELeave) CActiveScheduler;
1.74 + CleanupStack::PushL(sched);
1.75 + CActiveScheduler::Install(sched);
1.76 +
1.77 + // Create the server inside trap harness
1.78 + CTestFileUriServer *server = NULL;
1.79 + TRAPD(err, server = CTestFileUriServer::NewL());
1.80 + if (!err)
1.81 + {
1.82 + CleanupStack::PushL(server);
1.83 + RSemaphore sem;
1.84 +
1.85 + // The client API of TestExecute will already have created the
1.86 + // semaphore and will be waiting on it.
1.87 + User::LeaveIfError(sem.OpenGlobal(KServerName));
1.88 +
1.89 + CleanupStack::Pop(server);
1.90 +
1.91 + // Signal the client
1.92 + sem.Signal();
1.93 + sem.Close();
1.94 +
1.95 + // Enter the active scheduler
1.96 + sched->Start();
1.97 + }
1.98 + CleanupStack::Pop(sched);
1.99 + delete server;
1.100 + delete sched;
1.101 + }
1.102 +#else
1.103 +/**
1.104 +EKA2 version of MainL()
1.105 +Uses the new Rendezvous call isntead of the older semaphore.
1.106 +*/
1.107 +LOCAL_C void MainL()
1.108 + {
1.109 + // For platform security
1.110 +#if (defined __DATA_CAGING__)
1.111 + RProcess().DataCaging(RProcess::EDataCagingOn);
1.112 + RProcess().SecureApi(RProcess::ESecureApiOn);
1.113 +#endif
1.114 + CActiveScheduler* sched = NULL;
1.115 + sched = new(ELeave) CActiveScheduler;
1.116 + CActiveScheduler::Install(sched);
1.117 + CTestFileUriServer* server = NULL;
1.118 +
1.119 + // Create the test-server
1.120 + TRAPD(err, server = CTestFileUriServer::NewL());
1.121 +
1.122 + if(!err)
1.123 + {
1.124 + // Sync with the client and enter the active scheduler
1.125 + RProcess::Rendezvous(KErrNone);
1.126 + sched->Start();
1.127 + }
1.128 + delete server;
1.129 + delete sched;
1.130 + }
1.131 +#endif // #if (!defined EKA2)
1.132 +
1.133 +
1.134 +#if (defined __WINS__ && !defined EKA2)
1.135 +/**
1.136 +DLL entry-point for EKA1 emulator builds.
1.137 +*/
1.138 +GLDEF_C TInt E32Dll(enum TDllReason /*aDllReason*/)
1.139 + {
1.140 + return KErrNone;
1.141 + }
1.142 +
1.143 +#else
1.144 +/**
1.145 +Exe entry point code, for EKA1 hardware and EKA2 builds.
1.146 +*/
1.147 +GLDEF_C TInt E32Main()
1.148 + {
1.149 + __UHEAP_MARK;
1.150 + CTrapCleanup *cleanup = CTrapCleanup::New();
1.151 + if (cleanup == NULL)
1.152 + {
1.153 + return KErrNoMemory;
1.154 + }
1.155 + TInt err = KErrNone;
1.156 + TRAP(err, MainL());
1.157 + delete cleanup;
1.158 + __UHEAP_MARKEND;
1.159 + return KErrNone;
1.160 + }
1.161 +#endif // #if (defined __WINS__ && !defined EKA2)
1.162 +
1.163 +#if (defined __WINS__ && !defined EKA2)
1.164 +/**
1.165 +For EKA1 emulator builds. This function is called when the thread is first
1.166 +resumed. Has the standard thread entry siganture.
1.167 +*/
1.168 +TInt ThreadFunc (TAny* /*aParam*/)
1.169 + {
1.170 + __UHEAP_MARK;
1.171 + CTrapCleanup* cleanup = CTrapCleanup::New();
1.172 + if (cleanup == NULL)
1.173 + {
1.174 + return KErrNoMemory;
1.175 + }
1.176 + TInt err = KErrNone;
1.177 + TRAP(err, MainL());
1.178 + delete cleanup;
1.179 + __UHEAP_MARKEND;
1.180 + return KErrNone;
1.181 + }
1.182 +
1.183 +/**
1.184 +For EKA1 emulator builds. Creates and starts a thread for the server to run.
1.185 +*/
1.186 +EXPORT_C TInt NewServer()
1.187 + {
1.188 + _LIT(KThread, "Thread");
1.189 + RThread thread;
1.190 +
1.191 + // Name the thread as "<Server-Name>Thread" making it hopefully unique
1.192 + TBuf<KMaxTestExecuteNameLength> threadName(KServerName);
1.193 + threadName.Append(KThread);
1.194 +
1.195 + const TInt KMaxHeapSize = 0x1000000;
1.196 +
1.197 + // Create the thread
1.198 + TInt err = thread.Create(threadName, ThreadFunc, KDefaultStackSize,
1.199 + KMinHeapSize, KMaxHeapSize, NULL, EOwnerProcess);
1.200 + if (err != KErrNone)
1.201 + {
1.202 + return err;
1.203 + }
1.204 +
1.205 + // Start the thread -> effectively calls ThreadFunc
1.206 + thread.Resume();
1.207 +
1.208 + thread.Close();
1.209 + return KErrNone;
1.210 + }
1.211 +
1.212 +#endif // #if (defined __WINS__ && !defined EKA2)
1.213 +
1.214 +
1.215 +/**
1.216 +Base class pure virtual
1.217 +@return - Instance of the test step
1.218 +*/
1.219 +CTestStep* CTestFileUriServer::CreateTestStep(const TDesC& aStepName)
1.220 + {
1.221 + CTestStep *testStep = NULL;
1.222 +
1.223 + if (aStepName == KTestCreateFileStep)
1.224 + {
1.225 + testStep = new (ELeave) CTestCreateFileStep;
1.226 + }
1.227 + else if (aStepName == KTestGetFileNameFromUriStep)
1.228 + {
1.229 + testStep = new (ELeave) CTestGetFileNameFromUriStep;
1.230 + }
1.231 + else if (aStepName == KTestGenerateFileUriStep)
1.232 + {
1.233 + testStep = new (ELeave) CTestGenerateFileUriStep;
1.234 + }
1.235 + else if (aStepName == KTestDeleteFileStep)
1.236 + {
1.237 + testStep = new (ELeave) CTestDeleteFileStep;
1.238 + }
1.239 + else if (aStepName == KTestForAllFilesStep)
1.240 + {
1.241 + testStep = new (ELeave) CTestForAllFilesStep();
1.242 + }
1.243 + return testStep;
1.244 + }
1.245 +
1.246 +/**
1.247 +Returns the equivalent drive number of a drive
1.248 +*/
1.249 +void CTestFileUriServer::GetDriveNumber(const TDesC& aDrive, TDriveNumber& aDriveNum)
1.250 + {
1.251 + TBuf<1> driveLetter(aDrive.Left(1));
1.252 + driveLetter.LowerCase();
1.253 + aDriveNum = static_cast <TDriveNumber> (driveLetter[0] - KLetterA);
1.254 + }
1.255 +
1.256 +/**
1.257 +Checks whether a specific drive is a removable drive
1.258 +*/
1.259 +TInt CTestFileUriServer::IsRemovableDrive(const TDriveNumber& aDriveNum, TBool& aResult)
1.260 + {
1.261 + TInt err = KErrNone;
1.262 + TDriveInfo driveInfo;
1.263 + RFs fs;
1.264 + aResult = EFalse;
1.265 + err = fs.Connect();
1.266 + if(err == KErrNone)
1.267 + {
1.268 + err = fs.Drive(driveInfo, aDriveNum);
1.269 + if (err == KErrNone && driveInfo.iDriveAtt & KDriveAttRemovable)
1.270 + {
1.271 + aResult = ETrue;
1.272 + }
1.273 + fs.Close();
1.274 + }
1.275 + return err;
1.276 + }
1.277 +
1.278 +/**
1.279 +Replaces the drive placeholder <drive> with the actual drive
1.280 +*/
1.281 +HBufC16* CTestFileUriServer::CheckAndFillDriveNameL(const TPtrC& aFileUri, const TPtrC& aDrive)
1.282 + {
1.283 + HBufC16* expectedUriWithDrive = aFileUri.AllocL();
1.284 + TInt placeHolderPos = aFileUri.Find(KDrivePlaceHolder);
1.285 + if(placeHolderPos >= KErrNone)
1.286 + {
1.287 + if(aDrive == KExtMedia)
1.288 + {// Create a descriptor that is big enough
1.289 + // Just in case ReAllocL leaves
1.290 + CleanupStack::PushL(expectedUriWithDrive);
1.291 + expectedUriWithDrive = expectedUriWithDrive->ReAllocL(aFileUri.Length() + (KExtMedia().Length() - KDrivePlaceHolder().Length()));
1.292 + CleanupStack::Pop(); // expectedUriWithDrive
1.293 + }
1.294 + expectedUriWithDrive->Des().Replace(placeHolderPos, KDrivePlaceHolder().Length(), aDrive);
1.295 + }
1.296 + return expectedUriWithDrive;
1.297 + }
1.298 +
1.299 +/**
1.300 +Private function used to find the remobale drives and populate iRemovableDrives
1.301 +*/
1.302 +TInt CTestFileUriServer::PopulateRemovableDrivesBuf(const RFs& aFs)
1.303 + {
1.304 + TInt err = KErrNone;
1.305 + TDriveInfo driveInfo;
1.306 + TInt driveNum;
1.307 + for (driveNum = EDriveA; driveNum <= EDriveZ; driveNum++)
1.308 + {
1.309 + // Populate iRemovableDrives with all removable drives in alphabetical order
1.310 + err = aFs.Drive(driveInfo, driveNum);
1.311 + if (err == KErrNone && (driveInfo.iDriveAtt & KDriveAttRemovable))
1.312 + {
1.313 + iRemovableDrives.Append(TInt16('a' + driveNum));
1.314 + }
1.315 + }
1.316 + return err;
1.317 + }
1.318 +
1.319 +/**
1.320 +Searches whether a file with same name and path exists in any other removable drive
1.321 +*/
1.322 +TInt CTestFileUriServer::FirstRemovableDriveWithSameFileName(const TDesC& aFileName, TBuf<1>& aCorrectDrive)
1.323 + {
1.324 + aCorrectDrive = aFileName.Left(1);
1.325 + TInt err = KErrNone;
1.326 + RFs fs;
1.327 + if((err = fs.Connect()) != KErrNone)
1.328 + {
1.329 + return err;
1.330 + }
1.331 +
1.332 + if(iRemovableDrives == KNullDesC)
1.333 + {
1.334 + if((err = PopulateRemovableDrivesBuf(fs)) != KErrNone)
1.335 + {
1.336 + return err;
1.337 + }
1.338 + }
1.339 + TInt index;
1.340 + HBufC* tempFileName = NULL;
1.341 + if((tempFileName = aFileName.Alloc()) == NULL)
1.342 + {
1.343 + return KErrGeneral;
1.344 + }
1.345 + for(index = 0; index < iRemovableDrives.Length(); ++index)
1.346 + {
1.347 + TUint attValue;
1.348 + // change the drive in the filename and check whether such a file exists
1.349 + tempFileName->Des()[0] = iRemovableDrives[index];
1.350 + err = fs.Att(tempFileName->Des(), attValue);
1.351 + if(err == KErrNone)
1.352 + {
1.353 + aCorrectDrive[0] = iRemovableDrives[index];
1.354 + break;
1.355 + }
1.356 + }
1.357 + if(index >= iRemovableDrives.Length())
1.358 + {// File not found on any removable drive
1.359 + aCorrectDrive = KNullDesC;
1.360 + }
1.361 + delete tempFileName;
1.362 + fs.Close();
1.363 + return KErrNone;
1.364 + }
1.365 +
1.366 +/**
1.367 +Obtains the private directory of the application and appends it along with the
1.368 +relative filename and drive to create the fully qualified filename
1.369 +*/
1.370 +TInt CTestFileUriServer::CreateFullyQualifiedName(const TPtrC& aRelativeName, const TPtrC& aDrive, TFileName& aFullyQualifiedName)
1.371 + {
1.372 + RFs fs;
1.373 + TInt err = fs.Connect();
1.374 + if(err != KErrNone)
1.375 + {
1.376 + return err;
1.377 + }
1.378 + // Get private dir name
1.379 + err = fs.PrivatePath(aFullyQualifiedName);
1.380 + fs.Close();
1.381 + if(err != KErrNone)
1.382 + {
1.383 + return err;
1.384 + }
1.385 + // Construct fully-qualified filename
1.386 + aFullyQualifiedName.Insert(0, KDriveSeparator);
1.387 + aFullyQualifiedName.Insert(0, aDrive);
1.388 + TInt position = 0;
1.389 + // If backslash already exists dont include again
1.390 + if(aRelativeName.Left(1) == KBackSlash)
1.391 + {
1.392 + ++position;
1.393 + }
1.394 + aFullyQualifiedName.Append(aRelativeName.Right(aRelativeName.Length() - position));
1.395 + return KErrNone;
1.396 + }