persistentstorage/store/UFILE/UF_STOR.CPP
changeset 0 08ec8eefde2f
equal deleted inserted replaced
-1:000000000000 0:08ec8eefde2f
       
     1 // Copyright (c) 1998-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 //
       
    15 
       
    16 #include "UF_STD.H"
       
    17 
       
    18 const TFileStoreFactoryFunction KDefaultFileStoreFactory[]=
       
    19 	{
       
    20 	KDirectFileStoreFactoryFunction,
       
    21 	KPermanentFileStoreFactoryFunction,
       
    22 	NULL
       
    23 	};
       
    24 
       
    25 EXPORT_C CFileStore* CFileStore::OpenL(RFs& aFs,const TDesC& aName,TUint aFileMode)
       
    26 /** Opens a file containing a store and constructs an appropriate file store object.
       
    27 
       
    28 The resulting file store object is of concrete type, i.e. either CDirectFileStore 
       
    29 or CPermanentFileStore. The specific type is determined from the layout information 
       
    30 held in the file store.
       
    31 
       
    32 @param aFs Handle to a file server session.
       
    33 @param aName The full path name of the file containing the store.
       
    34 @param aFileMode The mode in which the file is to be accessed. The mode is 
       
    35 defined by the TFileMode type.
       
    36 @return A pointer to the new file store object. 
       
    37 @see TFileMode
       
    38 @see CFileStore::Layout() */
       
    39 	{
       
    40 	return OpenL(aFs,aName,aFileMode,KDefaultFileStoreFactory);
       
    41 	}
       
    42 
       
    43 EXPORT_C CFileStore* CFileStore::OpenLC(RFs& aFs,const TDesC& aName,TUint aFileMode)
       
    44 /** Opens a file containing a store, constructs an appropriate file store object 
       
    45 and places the pointer onto the cleanup stack.
       
    46 
       
    47 The resulting file store object is of concrete type, i.e. either CDirectFileStore 
       
    48 or CPermanentFileStore. The specific type is determined from the layout information 
       
    49 held in the file store.
       
    50 
       
    51 @param aFs Handle to a file server session. 
       
    52 @param aName The full path name of the file containing the store. 
       
    53 @param aFileMode The mode in which the file is to be accessed. The mode is 
       
    54 defined by the TFileMode type. 
       
    55 @return A pointer to the new file store object. 
       
    56 @see TFileMode
       
    57 @see CFileStore::Layout() */
       
    58 	{
       
    59 	return OpenLC(aFs,aName,aFileMode,KDefaultFileStoreFactory);
       
    60 	}
       
    61 
       
    62 EXPORT_C CFileStore* CFileStore::FromL(RFile& aFile)
       
    63 /** Constructs a file store object from an opened file.
       
    64 
       
    65 The file must already be open before calling this function.
       
    66 
       
    67 The resulting file store object is of concrete type, i.e. either CDirectFileStore 
       
    68 or CPermanentFileStore. The specific type is determined from the layout information 
       
    69 held in the file store.
       
    70 
       
    71 Note that ownership of the file passes to the store. The referenced RFile 
       
    72 is cleared and is no longer valid:
       
    73 
       
    74 @param aFile A reference to the opened file. 
       
    75 @return A pointer to the new file store object. 
       
    76 @see CFileStore::Layout() */
       
    77 	{
       
    78 	return FromL(aFile,KDefaultFileStoreFactory);
       
    79 	}
       
    80 
       
    81 EXPORT_C CFileStore* CFileStore::FromLC(RFile& aFile)
       
    82 /** Constructs a file store object from an opened file, and places the pointer 
       
    83 onto the cleanup stack.
       
    84 
       
    85 The file must already be open before calling this function.
       
    86 
       
    87 The resulting file store object is of concrete type, i.e. either CDirectFileStore 
       
    88 or CPermanentFileStore. The specific type is determined from the layout information 
       
    89 held in the file store.
       
    90 
       
    91 Note that ownership of the file passes to the store. The referenced RFile 
       
    92 is cleared and is no longer valid:
       
    93 
       
    94 @param aFile A reference to the opened file. 
       
    95 @return A pointer to the new file store object. 
       
    96 @see CFileStore::Layout() */
       
    97 	{
       
    98 	return FromLC(aFile,KDefaultFileStoreFactory);
       
    99 	}
       
   100 
       
   101 EXPORT_C CFileStore* CFileStore::OpenL(RFs& aFs,const TDesC& aName,TUint aFileMode,const TFileStoreFactoryFunction aFactory[])
       
   102 //
       
   103 // Open a file store of any of the types supported by aFactory.
       
   104 //
       
   105 	{
       
   106 	RFile file;
       
   107 	__LEAVE_IF_ERROR(file.Open(aFs,aName,aFileMode));
       
   108 	return FromL(file,aFactory);
       
   109 	}
       
   110 
       
   111 EXPORT_C CFileStore* CFileStore::OpenLC(RFs& aFs,const TDesC& aName,TUint aFileMode,const TFileStoreFactoryFunction aFactory[])
       
   112 //
       
   113 // Open and leave on cleanup stack.
       
   114 //
       
   115 	{
       
   116 	CFileStore* store=OpenL(aFs,aName,aFileMode,aFactory);
       
   117 	CleanupStack::PushL(store);
       
   118 	return store;
       
   119 	}
       
   120 
       
   121 EXPORT_C CFileStore* CFileStore::FromL(RFile& aFile,const TFileStoreFactoryFunction aFactory[])
       
   122 //
       
   123 // Read the file header and let every factory function in turn try to open it.
       
   124 //
       
   125 	{
       
   126 	RFileBuf buf;
       
   127 	buf.Attach(aFile);
       
   128 	buf.PushL();
       
   129 	RReadStream stream(&buf);
       
   130 	TCheckedUid chk;
       
   131 	stream>>chk;
       
   132 	if (chk.UidType().IsValid())
       
   133 		{
       
   134 		const TFileStoreFactoryFunction* iter=&aFactory[0];
       
   135 		TFileStoreFactoryFunction func;
       
   136 		while ((func=*iter++)!=NULL)
       
   137 			{
       
   138 			CFileStore* store=(*func)(buf,chk.UidType());
       
   139 			if (store!=NULL)
       
   140 				{
       
   141 				CleanupStack::Pop(2);
       
   142 				return store;
       
   143 				}
       
   144 			}
       
   145 		}
       
   146 //
       
   147 	__LEAVE(KErrNotSupported);
       
   148 	return NULL;
       
   149 	}
       
   150 
       
   151 EXPORT_C CFileStore* CFileStore::FromLC(RFile& aFile,const TFileStoreFactoryFunction aFactory[])
       
   152 //
       
   153 // Open and leave on cleanup stack.
       
   154 //
       
   155 	{
       
   156 	CFileStore* store=FromL(aFile,aFactory);
       
   157 	CleanupStack::PushL(store);
       
   158 	return store;
       
   159 	}
       
   160 
       
   161 EXPORT_C void CFileStore::SetTypeL(const TUidType& aType)
       
   162 /** Sets the UID type of the file store.
       
   163 
       
   164 The first UID, i.e. the first TUid component, of the TUidType must be the 
       
   165 file store type as returned by CFileStore::Layout(), otherwise the function 
       
   166 raises a STORE-File 9 panic.
       
   167 
       
   168 @param aType The UID type object containing the file store type. 
       
   169 @see TUid */
       
   170 	{
       
   171 	__ASSERT_ALWAYS(aType[0]==Layout(),Panic(EFileStoreBadType));
       
   172 	TCheckedUid chk(aType);
       
   173 	if (iHost.IsActive())
       
   174 		{
       
   175 		RShareWriteStream stream(iHost);
       
   176 		stream.PushL();
       
   177 		stream<<chk; // failure may mean the file's type information is lost
       
   178 		CleanupStack::PopAndDestroy();
       
   179 		}
       
   180 	else
       
   181 		{
       
   182 		TInt size=iBuf.SizeL();
       
   183 		RWriteStream stream(&iBuf);
       
   184 		stream<<chk;
       
   185 		if (size==0)
       
   186 			{
       
   187 			ExternalizeL(stream);
       
   188 			iHost.Share(&iBuf);
       
   189 			}
       
   190 		}
       
   191 	iType=aType;
       
   192 	}
       
   193 
       
   194 EXPORT_C void CFileStore::MarshalL()
       
   195 //
       
   196 // Second-phase construction for opening existing file stores.
       
   197 //
       
   198 	{
       
   199 	__ASSERT_DEBUG(!iHost.IsActive()&&(!iType.IsValid()||iType[0]==Layout()),User::Invariant());
       
   200 	RReadStream stream(&iBuf);
       
   201 	InternalizeL(stream);
       
   202 	iHost.Share(&iBuf);
       
   203 	}
       
   204 
       
   205 EXPORT_C CFileStore::~CFileStore()
       
   206 /** Frees resources owned by the object, prior to its destruction. In particular, 
       
   207 it closes the associated file. */
       
   208 	{
       
   209 	Destruct();
       
   210 	iBuf.Close();
       
   211 	}
       
   212 
       
   213 EXPORT_C CFileStore* CFileStore::OpenL(RFs& aFs,const TDesC& aName,TUint aFileMode,TFileStoreFactoryFunction aFunction)
       
   214 //
       
   215 // Open a file store using aFunction.
       
   216 //
       
   217 	{
       
   218 	RFile file;
       
   219 	__LEAVE_IF_ERROR(file.Open(aFs,aName,aFileMode));
       
   220 	return FromL(file,aFunction);
       
   221 	}
       
   222 
       
   223 EXPORT_C CFileStore* CFileStore::OpenLC(RFs& aFs,const TDesC& aName,TUint aFileMode,TFileStoreFactoryFunction aFunction)
       
   224 //
       
   225 // Open and leave on cleanup stack.
       
   226 //
       
   227 	{
       
   228 	CFileStore* store=OpenL(aFs,aName,aFileMode,aFunction);
       
   229 	CleanupStack::PushL(store);
       
   230 	return store;
       
   231 	}
       
   232 
       
   233 EXPORT_C CFileStore* CFileStore::CreateL(RFs& aFs,const TDesC& aName,TUint aFileMode,TNewFunction aFunction)
       
   234 //
       
   235 // Create a file store using aFunction. Must not already exist.
       
   236 //
       
   237 	{
       
   238 	RFile file;
       
   239 	__LEAVE_IF_ERROR(file.Create(aFs,aName,aFileMode));
       
   240 	return DoNewL(file,aFunction);
       
   241 	}
       
   242 
       
   243 EXPORT_C CFileStore* CFileStore::CreateLC(RFs& aFs,const TDesC& aName,TUint aFileMode,TNewFunction aFunction)
       
   244 //
       
   245 // Create and leave on cleanup stack.
       
   246 //
       
   247 	{
       
   248 	CFileStore* store=CreateL(aFs,aName,aFileMode,aFunction);
       
   249 	CleanupStack::PushL(store);
       
   250 	return store;
       
   251 	}
       
   252 
       
   253 EXPORT_C CFileStore* CFileStore::ReplaceL(RFs& aFs,const TDesC& aName,TUint aFileMode,TNewFunction aFunction)
       
   254 //
       
   255 // Replace a file store using aFunction. May exist already.
       
   256 //
       
   257 	{
       
   258 	RFile file;
       
   259 	__LEAVE_IF_ERROR(file.Replace(aFs,aName,aFileMode));
       
   260 	return DoNewL(file,aFunction);
       
   261 	}
       
   262 
       
   263 EXPORT_C CFileStore* CFileStore::ReplaceLC(RFs& aFs,const TDesC& aName,TUint aFileMode,TNewFunction aFunction)
       
   264 //
       
   265 // Replace and leave on cleanup stack.
       
   266 //
       
   267 	{
       
   268 	CFileStore* store=ReplaceL(aFs,aName,aFileMode,aFunction);
       
   269 	CleanupStack::PushL(store);
       
   270 	return store;
       
   271 	}
       
   272 
       
   273 EXPORT_C CFileStore* CFileStore::TempL(RFs& aFs,const TDesC& aPath,TFileName& aName,TUint aFileMode,TNewFunction aFunction)
       
   274 //
       
   275 // Create a temporary file store using aFunction.
       
   276 //
       
   277 	{
       
   278 	RFile file;
       
   279 	__LEAVE_IF_ERROR(file.Temp(aFs,aPath,aName,aFileMode));
       
   280 	return DoNewL(file,aFunction);
       
   281 	}
       
   282 
       
   283 EXPORT_C CFileStore* CFileStore::TempLC(RFs& aFs,const TDesC& aPath,TFileName& aName,TUint aFileMode,TNewFunction aFunction)
       
   284 //
       
   285 // Create temporary and leave on cleanup stack.
       
   286 //
       
   287 	{
       
   288 	CFileStore* store=TempL(aFs,aPath,aName,aFileMode,aFunction);
       
   289 	CleanupStack::PushL(store);
       
   290 	return store;
       
   291 	}
       
   292 
       
   293 EXPORT_C CFileStore* CFileStore::FromL(RFile& aFile,TFileStoreFactoryFunction aFunction)
       
   294 //
       
   295 // Open a file store using aFunction, given its file handle.
       
   296 //
       
   297 	{
       
   298 	RFileBuf buf;
       
   299 	buf.Attach(aFile);
       
   300 	buf.PushL();
       
   301 	RReadStream stream(&buf);
       
   302 	TCheckedUid chk;
       
   303 	stream>>chk;
       
   304 	CFileStore* store=(*aFunction)(buf,chk.UidType());
       
   305 	if (store==NULL) 
       
   306 		{
       
   307 		aFile.Close();
       
   308 		__LEAVE(KErrNotSupported);
       
   309 		}
       
   310 //
       
   311 	CleanupStack::Pop(2);
       
   312 	return store;
       
   313 	}
       
   314 
       
   315 EXPORT_C CFileStore* CFileStore::FromLC(RFile& aFile,TFileStoreFactoryFunction aFunction)
       
   316 //
       
   317 // Open and leave on cleanup stack.
       
   318 //
       
   319 	{
       
   320 	CFileStore* store=FromL(aFile,aFunction);
       
   321 	CleanupStack::PushL(store);
       
   322 	return store;
       
   323 	}
       
   324 
       
   325 EXPORT_C CFileStore* CFileStore::NewL(RFile& aFile,TNewFunction aFunction)
       
   326 //
       
   327 // Create a file store using aFunction, given its file handle.
       
   328 //
       
   329 	{
       
   330 	TInt r=aFile.SetSize(0);
       
   331 	if (r!=KErrNone)
       
   332 		{
       
   333 		aFile.Close();
       
   334 		__LEAVE(r);
       
   335 		}
       
   336 	return DoNewL(aFile,aFunction);
       
   337 	}
       
   338 
       
   339 EXPORT_C CFileStore* CFileStore::NewLC(RFile& aFile,TNewFunction aFunction)
       
   340 //
       
   341 // Create and leave on cleanup stack.
       
   342 //
       
   343 	{
       
   344 	CFileStore* store=NewL(aFile,aFunction);
       
   345 	CleanupStack::PushL(store);
       
   346 	return store;
       
   347 	}
       
   348 
       
   349 EXPORT_C CFileStore::CFileStore(RFile& aFile)
       
   350 //
       
   351 // Constructor creating a new file store.
       
   352 //
       
   353 	{
       
   354 	iBuf.Attach(aFile);
       
   355 	iBuf.iExt = 0;
       
   356 	}
       
   357 
       
   358 EXPORT_C CFileStore::CFileStore(RFileBuf& aBuf,const TUidType& aType)
       
   359 //
       
   360 // Constructor opening an existing file store.
       
   361 //
       
   362 	: iBuf(Capture(aBuf)),iType(aType)
       
   363 	{}
       
   364 
       
   365 EXPORT_C void CFileStore::Destruct()
       
   366 //
       
   367 // Early destruction, for derived classes overriding DoRevertL().
       
   368 //
       
   369 	{
       
   370 	if (iHost.IsActive())
       
   371 		{
       
   372 		iHost.Release();
       
   373 		}
       
   374 	}
       
   375 
       
   376 EXPORT_C void CFileStore::SynchL()
       
   377 //
       
   378 // Synchronise this file store's file buffer.
       
   379 //
       
   380 	{
       
   381 	TStreamExchange& host=iHost;
       
   382 	if (host.IsActive())
       
   383 		{
       
   384 		MStreamBuf* buf=host.HostL();
       
   385 		__ASSERT_DEBUG(IsHost(buf),User::Invariant());
       
   386 		host.Release(); // make sure no writes fail silently by shutting down on failure
       
   387 		buf->SynchL();
       
   388 		host.Share(buf);
       
   389 		}
       
   390 	else
       
   391 		iBuf.SynchL();
       
   392 	}
       
   393 
       
   394 EXPORT_C void CFileStore::ChangedL()
       
   395 //
       
   396 // Re-write this file store's structure.
       
   397 //
       
   398 	{
       
   399 	__ASSERT_DEBUG(iHost.IsActive(),User::Invariant());
       
   400 	RShareWriteStream stream(iHost,KFileStoreStart);
       
   401 	stream.PushL();
       
   402 	ExternalizeL(stream);
       
   403 	CleanupStack::PopAndDestroy();
       
   404 	}
       
   405 
       
   406 EXPORT_C void CFileStore::RefreshL()
       
   407 //
       
   408 // Re-read this file store's structure.
       
   409 //
       
   410 	{
       
   411 	if (iHost.IsActive())
       
   412 		{
       
   413 		RShareReadStream stream(iHost,KFileStoreStart);
       
   414 		stream.PushL();
       
   415 		InternalizeL(stream);
       
   416 		CleanupStack::PopAndDestroy();
       
   417 		}
       
   418 	else
       
   419 		{
       
   420 		iBuf.SeekL(iBuf.ERead,KFileStoreStart);
       
   421 		MarshalL();
       
   422 		}
       
   423 	}
       
   424 
       
   425 EXPORT_C void CFileStore::DoCommitL()
       
   426 //
       
   427 // Default implementation just synchronising.
       
   428 //
       
   429 	{
       
   430 	SynchL();
       
   431 	}
       
   432 
       
   433 EXPORT_C void CFileStore::DoRevertL()
       
   434 //
       
   435 // Default implementation failing after synchronisation.
       
   436 //
       
   437 	{
       
   438 	SynchL();
       
   439 	__LEAVE(KErrNotSupported);
       
   440 	}
       
   441 
       
   442 CFileStore* CFileStore::DoNewL(RFile& aFile,TNewFunction aFunction)
       
   443 	{
       
   444 	CleanupClosePushL(aFile);
       
   445 	CFileStore* store=(*aFunction)(aFile);
       
   446 	CleanupStack::Pop();
       
   447 	return store;
       
   448 	}
       
   449