obex/obexprotocol/obex/src/obexasyncfilewriter.cpp
changeset 0 d0791faffa3f
equal deleted inserted replaced
-1:000000000000 0:d0791faffa3f
       
     1 // Copyright (c) 2003-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 /**
       
    17  @file
       
    18  @internalComponent
       
    19 */
       
    20 
       
    21 #include <f32file.h>
       
    22 #include "obexasyncfilewriter.h"
       
    23 #include "logger.h"
       
    24 
       
    25 #ifdef __FLOG_ACTIVE
       
    26 _LIT8(KLogComponent, "OBEX");
       
    27 #endif
       
    28 
       
    29 //
       
    30 // Panic category for CObexAsyncFileWriter
       
    31 //
       
    32 _LIT(KObexAsyncFileWriterPanic, "Obex-AFW");
       
    33 
       
    34 /**
       
    35 Panic codes for CObexAsyncFileWriter
       
    36 
       
    37 @internalComponent
       
    38 @released
       
    39 */
       
    40 enum TAsyncObexFileWriterPanic
       
    41 	{
       
    42 	/** Null buffer pointer */
       
    43 	ENullBufferPointer
       
    44 	};
       
    45 
       
    46 //
       
    47 // Implementation of CObexAsyncFileWriter
       
    48 //
       
    49 
       
    50 /**
       
    51 Factory function
       
    52 
       
    53 Note that we return a pointer to the interface class, so
       
    54 that this class can only be used through this interface.
       
    55 This class in an implementation of a strategy as part of
       
    56 a Strategy pattern.  CObexSyncFileWriter provides an
       
    57 alternative strategy implementation, with CObexBufObject
       
    58 as the context for these strategies.
       
    59 
       
    60 @see MObexFileWriter
       
    61 @see CObexSyncFileWriter
       
    62 @see CObexBufObject
       
    63 
       
    64 @internalComponent
       
    65 @released
       
    66 
       
    67 @param aFile The file we're writing to
       
    68 @return An MObexFileWriter for writing to file
       
    69 */
       
    70 MObexFileWriter* CObexAsyncFileWriter::NewL(RFile& aFile)
       
    71 	{
       
    72 	CObexAsyncFileWriter* self = new(ELeave) CObexAsyncFileWriter(aFile);
       
    73 	CleanupStack::PushL(self);
       
    74 	self->ConstructL();
       
    75 	CleanupStack::Pop(self);
       
    76 	return self;
       
    77 	}
       
    78 
       
    79 /**
       
    80 Constructor
       
    81 
       
    82 @internalComponent
       
    83 @released
       
    84 
       
    85 @param aFile The file we're writing to
       
    86 */
       
    87 CObexAsyncFileWriter::CObexAsyncFileWriter(RFile& aFile)
       
    88 	: CActive(EPriorityStandard), iFile(aFile), iBufPtr(NULL, 0)
       
    89 	{
       
    90 	CActiveScheduler::Add(this);
       
    91 	}
       
    92 
       
    93 /**
       
    94 2nd phase constructor
       
    95 
       
    96 @internalComponent
       
    97 @released
       
    98 */	
       
    99 void CObexAsyncFileWriter::ConstructL()
       
   100 	{
       
   101 	}
       
   102 
       
   103 /**
       
   104 AO cancellation
       
   105 
       
   106 @internalComponent
       
   107 @released
       
   108 */
       
   109 void CObexAsyncFileWriter::DoCancel()
       
   110 	{
       
   111 	iFile.Flush();
       
   112 	}
       
   113 
       
   114 /**
       
   115 AO request completion
       
   116 
       
   117 @internalComponent
       
   118 @released
       
   119 */
       
   120 void CObexAsyncFileWriter::RunL()
       
   121 	{
       
   122 	// Just ignore completions; the status is picked up next time
       
   123 	// a service function is called
       
   124 	}
       
   125 
       
   126 /**
       
   127 Normal asynchronous write to file
       
   128 
       
   129 @internalComponent
       
   130 @released
       
   131 
       
   132 @param aPos The file position
       
   133 @param aBuf The buffer we're to write. We use this buffer by copying the pointer
       
   134             and return the buffer we previously wrote to the caller by updating
       
   135             the pointer.  If an error occurs, the buffers are not swapped and
       
   136             the pointer is not updated.  Note that this class never owns any
       
   137             buffers and that passing a buffer to this function does not imply a
       
   138             transfer of ownership.
       
   139 @return Symbian OS error code
       
   140 */
       
   141 TInt CObexAsyncFileWriter::Write(TInt aPos, CBufBase*& aBuf)
       
   142 	{
       
   143 	__ASSERT_ALWAYS(aBuf, PANIC(KObexAsyncFileWriterPanic, ENullBufferPointer));
       
   144 
       
   145 	// If last write to file has not completed...
       
   146 	if (IsActive())
       
   147 		{
       
   148 		// wait for it to complete
       
   149 		User::WaitForRequest(iStatus);
       
   150 		
       
   151 		// if we had an error on the last write
       
   152 		if (iStatus.Int())
       
   153 			{
       
   154 			// Signal ourselves again with the error
       
   155 			TRequestStatus* status = &iStatus;
       
   156 			User::RequestComplete(status, iStatus.Int());
       
   157 			// and then de-activate ourselves by cancelling
       
   158 			Cancel();
       
   159 			}
       
   160 		// if we didn't have an error on the last write,
       
   161 		// we've consumed the completion of the write and
       
   162 		// hence are still active
       
   163 		}
       
   164 
       
   165 	if (!iStatus.Int())
       
   166 	// if the last write completed successfully...
       
   167 		{
       
   168 		// Swap our and the caller's pointers to show we
       
   169 		// have swapped which buffers we are using.  Note
       
   170 		// that the ownership of the buffers is not changed
       
   171 		// by this and the caller must deallocate any buffers
       
   172 		// it owns which are passed to this function.
       
   173 		CBufBase* buf = iBuffer;
       
   174 		iBuffer = aBuf;
       
   175 		aBuf = buf;
       
   176 
       
   177 		// Set up the descriptor to be passed to the file write
       
   178 		iBufPtr.Set(iBuffer->Ptr(0));
       
   179 
       
   180 		// We'll need to be active to service another write
       
   181 		if (!IsActive())
       
   182 			{
       
   183 			SetActive();
       
   184 			}
       
   185 
       
   186 		// kick off writing the next block
       
   187 		iFile.Write(aPos, iBufPtr, iStatus);
       
   188 
       
   189 		// and we're happy...
       
   190 		return KErrNone;
       
   191 		}
       
   192 	else
       
   193 	// the last write did not complete successfully
       
   194 		{
       
   195 		// Signal Obex error
       
   196 		return iStatus.Int();
       
   197 		}
       
   198 
       
   199 	}
       
   200 	
       
   201 /**
       
   202 Final, synchronous write to file
       
   203 
       
   204 @internalComponent
       
   205 @released
       
   206 
       
   207 @param aPos The file position
       
   208 @param aBuf The buffer we're to write. We use this buffer by copying the pointer
       
   209             and return the buffer we previously wrote to the caller by updating
       
   210             the pointer.  If an error occurs, the buffers are not swapped and
       
   211             the pointer is not updated.  Note that this class never owns any
       
   212             buffers and that passing a buffer to this function does not imply a
       
   213             transfer of ownership.
       
   214 @param aLength The amount of the buffer to write
       
   215 @return Symbian OS error code
       
   216 */
       
   217 TInt CObexAsyncFileWriter::FinalWrite(TInt aPos, CBufBase*& aBuf, TInt aLength)
       
   218 	{
       
   219 	__ASSERT_ALWAYS(aBuf, PANIC(KObexAsyncFileWriterPanic, ENullBufferPointer));
       
   220 
       
   221 	// If last write to file has not completed...
       
   222 	if (IsActive())
       
   223 		{
       
   224 		// wait for it to complete
       
   225 		User::WaitForRequest(iStatus);
       
   226 		
       
   227 		// Signal ourselves again with the request status
       
   228 		TRequestStatus* status = &iStatus;
       
   229 		User::RequestComplete(status, iStatus.Int());
       
   230 
       
   231 		// and then de-activate ourselves by cancelling
       
   232 		Cancel();
       
   233 		}
       
   234 
       
   235 	// if the last write completed successfully...
       
   236 	if (!iStatus.Int())
       
   237 		{
       
   238 		// Swap our and the caller's pointers to show we
       
   239 		// have swapped which buffers we are using.  Note
       
   240 		// that the ownership of the buffers is not changed
       
   241 		// by this and the caller must deallocate any buffers
       
   242 		// it owns which are passed to this function.
       
   243 		CBufBase* buf = iBuffer;
       
   244 		iBuffer = aBuf;
       
   245 		aBuf = buf;
       
   246 
       
   247 		// Set up the descriptor to be passed to the file write
       
   248 		iBufPtr.Set(iBuffer->Ptr(0));
       
   249 		iBufPtr.SetLength(aLength);
       
   250 		
       
   251 		// write the final block and return the error
       
   252 		TInt err = iFile.Write(aPos, iBufPtr);
       
   253 		if (err == KErrNone)
       
   254 			{
       
   255 			//flush the buffer, commit the write
       
   256 			return iFile.Flush();
       
   257 			}
       
   258 		else
       
   259 			{
       
   260 			return err;
       
   261 			}
       
   262 		}
       
   263 	else
       
   264 	// the last write did not complete successfully
       
   265 		{	
       
   266 		// Signal Obex error
       
   267 		return iStatus.Int();
       
   268 		}
       
   269 	}
       
   270 
       
   271 /**
       
   272 Destructor
       
   273 
       
   274 @internalComponent
       
   275 @released
       
   276 */
       
   277 CObexAsyncFileWriter::~CObexAsyncFileWriter()
       
   278 	{
       
   279 	Cancel();
       
   280 	}