--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/email/pop3andsmtpmtm/clientmtms/src/MIUTATCH.CPP Thu Dec 17 08:44:11 2009 +0200
@@ -0,0 +1,386 @@
+// Copyright (c) 1998-2009 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:
+//
+
+#if !defined (__E32STD_H__)
+#include <e32std.h>
+#endif
+
+#if !defined (__MIUTATCH_H__)
+#include "MIUTATCH.H"
+#endif
+
+void TImAttachmentFile::Reset()
+ {
+ iWritingToFile = EFalse;
+ iSpaceOnCache = 0;
+ iPositionInCache = 0;
+ iDataLine.SetLength(0);
+ }
+
+EXPORT_C TImAttachmentFile::TImAttachmentFile(RFs& aFileSession)
+ : iFileSession(aFileSession)
+ {
+ Reset();
+ }
+EXPORT_C TImAttachmentFile::~TImAttachmentFile()
+ {
+ iFile.Close();
+ }
+
+EXPORT_C TInt TImAttachmentFile::MakeDir (const TDesC& aDirPath)
+ {
+ // Create that directory
+ // Nb directory name must be terminated with '\\' character
+ return (iFileSession.MkDir(aDirPath));
+ }
+
+EXPORT_C TInt TImAttachmentFile::OpenFile (const TDesC& aDirPath, const TDesC& aFileName)
+
+ {
+ TInt err(AppendValidFile(aDirPath, aFileName, iFullFilePath));
+ if (err!=KErrNone)
+ return err;
+ Reset();
+ iWritingToFile = EFalse;
+ return (iFile.Open(iFileSession, iFullFilePath, EFileShareExclusive|EFileStream));
+ }
+
+EXPORT_C TInt TImAttachmentFile::CreateFile (const TDesC& aDirPath, const TDesC& aFileName)
+ {
+ // Initialise buffer used to store attachment data, prior to writing to file
+ iDataLine.FillZ();
+ Reset();
+
+ // Create a file for the attachment data
+ // If the file already exists in this path, generate a new file name
+ // with the path: "\aDirPath\aFileName(i)" where "i">0
+
+ TInt error=MakeDir(aDirPath); // make directory for the attachment
+ if (error!=KErrAlreadyExists && error!=KErrNone)
+ return error;
+
+ error=AppendValidFile(aDirPath, aFileName, iFullFilePath);
+ if (error!=KErrNone)
+ return error;
+
+ error=iFile.Create(iFileSession, iFullFilePath, EFileWrite|EFileShareExclusive|EFileStream);
+
+ if (error==KErrNone)
+ {
+ iWritingToFile = ETrue;
+ return error;
+ }
+ if (error!=KErrAlreadyExists)
+ return error;
+
+ TParsePtr filenamePPtr(iFullFilePath);
+ TFileName newFileName;
+
+ TInt index=0;
+ do
+ {
+ TPtrC filename=filenamePPtr.Name();
+ TPtrC extension=filenamePPtr.Ext();
+ iFullFilePath.Format(KImcvAttachFormatStr,&filename,++index,&extension);
+ error=AppendValidFile(aDirPath, iFullFilePath, newFileName);
+ if (error!=KErrNone)
+ error=iFile.Create(iFileSession, newFileName, EFileWrite|EFileShareExclusive|EFileStream);
+ }
+ while (error==KErrAlreadyExists);
+ return error;
+ }
+
+EXPORT_C TInt TImAttachmentFile::ReadFile (TDes8& rBuffer,TInt aLength)
+ {
+ // Only read from file once in a while, put into an intermediate buffer.
+ // Pass out data from buffer. Copy aLength of data from iDataLine to rBuffer
+
+ TInt err = 0; // Error returned by file read.
+ TInt bufLength = aLength; // Length yet to be copied.
+
+ // Is there anything in the buffer?
+ TInt dataLineLength = iDataLine.Length();
+ if (dataLineLength==0)
+ {
+ // Is length<buffer size?
+ if (bufLength<KDataLineBufferLength)
+ {
+ // Fill buffer
+ err = iFile.Read(iDataLine, KDataLineBufferLength);
+ dataLineLength = iDataLine.Length();
+
+ // Inititialise
+ iPositionInCache = 0;
+ iSpaceOnCache = dataLineLength;
+
+ // Read 'length' bytes from the data
+ rBuffer = SelectFileData(bufLength, iSpaceOnCache);
+ bufLength = 0;
+ }
+ else
+ {
+ // Don't use intermediate buffer
+ // Read 'length' bytes from file to rBuffer
+ err = iFile.Read(rBuffer,bufLength);
+ bufLength = 0;
+ }
+ }
+ else
+ // Is 'length'<data available in buffer
+ if (bufLength<iSpaceOnCache)
+ {
+ rBuffer = SelectFileData(bufLength, dataLineLength);
+ bufLength = 0;
+ }
+ else
+ {
+ // Read length bytes from the buffer to rBuffer
+ rBuffer = SelectFileData(iSpaceOnCache, dataLineLength);
+ bufLength -= rBuffer.Length();
+
+ if (bufLength>0)
+ {
+ if (bufLength<KDataLineBufferLength)
+ {
+ // Fill buffer
+ err = iFile.Read(iDataLine, KDataLineBufferLength);
+ dataLineLength = iDataLine.Length();
+
+ // Inititialise
+ iPositionInCache = 0;
+ iSpaceOnCache = dataLineLength;
+
+ // Read 'length' bytes from the data
+ rBuffer.Append(SelectFileData(bufLength, dataLineLength));
+ }
+ else
+ {
+ // read in remaining data to the rBuffer
+ TInt bufiPositionInCache = aLength-bufLength;
+ rBuffer.SetLength(bufiPositionInCache+1); // need this because otherwise get a panic!
+ TPtr8 ptr(&rBuffer[bufiPositionInCache], bufLength);
+ err = iFile.Read(ptr);
+ TInt ptrLength = ptr.Length();
+ rBuffer.SetLength(bufiPositionInCache+ptrLength); // set the original length
+ bufLength = 0;
+ }
+ }
+ }
+ return err;
+ }
+
+
+TPtrC8 TImAttachmentFile::SelectFileData(TInt& aBufLen, TInt& aDataLen)
+ {
+ // Read length bytes from the buffer to rBuffer
+ TInt size = aBufLen<aDataLen ? aBufLen : aDataLen;
+
+ TPtrC8 rBuf = iDataLine.Mid(iPositionInCache,size);
+ iPositionInCache += size;
+ iSpaceOnCache -= size;
+ return rBuf;
+ }
+
+
+TInt TImAttachmentFile::ReadFile ()
+ {
+ return iFile.Read(iDataLine);
+ }
+
+EXPORT_C void TImAttachmentFile::SetFileHandle(RFile& aFile,TImFileOpenMode aFileMode)
+ {
+ if(aFileMode == EImFileRead)
+ iWritingToFile = EFalse;
+ else if(aFileMode == EImFileWrite)
+ iWritingToFile = ETrue;
+
+ iFile = aFile;
+ }
+
+EXPORT_C TInt TImAttachmentFile::WriteFile (const TDesC8& aBuffer)
+ {
+ // Write data from aBuffer to file using an intermediate buffer, iDataLine.
+ // This is to reduce the number of file writes. 'Large' files can be written
+ // directly to the file.
+
+ TInt err(KErrNone);
+
+ TInt atchDataSize = aBuffer.Length();
+ TInt bufferSize = iDataLine.Length();
+ TInt spaceOnBuffer = 0;
+ TInt bufPos = 0;
+ // Fill buffer
+ spaceOnBuffer = KDataLineBufferLength - bufferSize;
+
+ // if incoming data is bigger than buffer
+ // we can write it directly to file if packing is not done earier
+ if (atchDataSize >= KDataLineBufferLength && spaceOnBuffer == KDataLineBufferLength)
+ {
+ err=iFile.Write(aBuffer.Mid(bufPos));
+ atchDataSize=0;
+ return err;
+ }
+
+ if (atchDataSize > spaceOnBuffer)
+ {
+ // The remaining size of the atch is greater than the buffer
+ // Append as much data from the atch than will fit in the buffer
+ iDataLine.Append(aBuffer.Mid(bufPos,spaceOnBuffer));
+
+ bufPos += spaceOnBuffer;
+ atchDataSize -= spaceOnBuffer;
+
+ // Flush buffer to file
+ err = WriteFile();
+ iDataLine.SetLength(0);
+ bufferSize = 0;
+
+ // if the size of the attachment is 'large' then write the whole file
+ if (atchDataSize >= KDataLineBufferLength)
+ {
+ err=iFile.Write(aBuffer.Mid(bufPos));
+ atchDataSize=0;
+ }
+ else
+ {
+ iDataLine.Append(aBuffer.Mid(bufPos,atchDataSize));
+ bufPos += atchDataSize;
+ atchDataSize -= atchDataSize; // atchDataSize should be 0!
+ }
+ }
+ else
+ {
+ iDataLine.Append(aBuffer.Mid(bufPos,atchDataSize));
+ bufPos += atchDataSize;
+ atchDataSize -= atchDataSize; // atchDataSize should be 0!
+ }
+
+ return err;
+ }
+
+EXPORT_C TInt TImAttachmentFile::WriteFile (const TDesC16& aBuffer)
+ {
+ // Write data from aBuffer to file using an intermediate buffer, iDataLine.
+ // This is to reduce the number of file writes. 'Large' files can be written
+ // directly to the file.
+
+ iFileText.Set(iFile);
+ TInt err (KErrNone);
+
+ TInt atchDataSize = aBuffer.Length();
+ TInt bufferSize = iDataLine.Length();
+ TInt spaceOnBuffer = 0;
+ TInt bufPos = 0;
+ // Fill buffer
+ spaceOnBuffer = KDataLineBufferLength - bufferSize;
+
+ // if incoming data is bigger than buffer
+ // we can write it directly to file if packing is not done earier
+ if (atchDataSize >= KDataLineBufferLength && spaceOnBuffer == KDataLineBufferLength)
+ {
+ err=iFileText.Write(aBuffer.Mid(bufPos));
+ atchDataSize=0;
+ return err;
+ }
+
+ if (atchDataSize > spaceOnBuffer)
+ {
+ // The remaining size of the atch is greater than the buffer
+ // Append as much data from the atch than will fit in the buffer
+ iDataLine.Append(aBuffer.Mid(bufPos,spaceOnBuffer));
+
+ bufPos += spaceOnBuffer;
+ atchDataSize -= spaceOnBuffer;
+
+ // Flush buffer to file
+ err = WriteFile();
+ iDataLine.SetLength(0);
+ bufferSize = 0;
+
+ // if the size of the attachment is 'large' then write the whole file
+ if (atchDataSize >= KDataLineBufferLength)
+ {
+ err=iFileText.Write(aBuffer.Mid(bufPos));
+ atchDataSize=0;
+ }
+ else
+ {
+ iDataLine.Append(aBuffer.Mid(bufPos,atchDataSize));
+ bufPos += atchDataSize;
+ atchDataSize -= atchDataSize; // atchDataSize should be 0!
+ }
+ }
+ else
+ {
+ iDataLine.Append(aBuffer.Mid(bufPos,atchDataSize));
+ bufPos += atchDataSize;
+ atchDataSize -= atchDataSize; // atchDataSize should be 0!
+ }
+
+ return err;
+ }
+
+
+TInt TImAttachmentFile::WriteFile ()
+ {
+ return iFile.Write(iDataLine);
+ }
+
+EXPORT_C TInt TImAttachmentFile::CloseFile()
+ {
+ // Check if writing to a file, in which case make sure iDataLine buffer..
+ // has been flushed.
+ TInt err = KErrNone;
+ if (iWritingToFile)
+ err = FlushFile();
+ Reset();
+ iFile.Close();
+ return err;
+ }
+
+TInt TImAttachmentFile::FlushFile()
+ {
+ if (iDataLine.Length() > 0)
+ {
+ WriteFile();
+ }
+ return iFile.Flush();
+ }
+
+EXPORT_C TInt TImAttachmentFile::DeleteAttachment(const TDesC& aDirPath, const TDesC& aFileName)
+ {
+ TInt err(AppendValidFile(aDirPath, aFileName, iFullFilePath));
+ if (err!=KErrNone)
+ return err;
+ return (iFileSession.Delete(iFullFilePath));
+ }
+
+TInt TImAttachmentFile::AppendValidFile(const TDesC& aDirPath, const TDesC& aFileName, TFileName& rFullFilePath)
+ {
+ // if the resultant filename is too long, report it,
+ // trimming the filename is not an option, apparently.
+
+ rFullFilePath=aDirPath;
+ if (aDirPath.Length() + aFileName.Length() > KMaxFileName)
+ {
+ return KErrBadName;
+ }
+ else
+ {
+ rFullFilePath.Append(aFileName);
+ }
+ return KErrNone;
+ }
+