ImagePrint/ImagePrintEngine/DeviceProtocols/upnpprotocolfw2/src/cupprintercontainer.cpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/ImagePrint/ImagePrintEngine/DeviceProtocols/upnpprotocolfw2/src/cupprintercontainer.cpp Thu Dec 17 08:45:53 2009 +0200
@@ -0,0 +1,775 @@
+/*
+* Copyright (c) 2002-2007 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: Declares CUPPrinterContainer class
+*
+*/
+
+
+#include "cupprintercontainer.h"
+#include "cuplogger.h"
+#include "upconsts.h"
+
+_LIT(KUPnPPrinterCache, "printers.txt");
+
+#define KMaxCacheFileSize 512
+
+// Public functions
+
+//--------------------------------------------------------------------------------------------
+//
+// CUPPrinterContainer::~CUPPrinterContainer
+//
+//--------------------------------------------------------------------------------------------
+CUPPrinterContainer::~CUPPrinterContainer()
+{
+ iPrinters.ResetAndDestroy();
+ iPrinters.Close();
+ iFsSession.Close();
+ if(iCacheBuffer)
+ delete iCacheBuffer;
+}
+
+//--------------------------------------------------------------------------------------------
+//
+// CUPPrinterContainer::NewL
+//
+//--------------------------------------------------------------------------------------------
+CUPPrinterContainer* CUPPrinterContainer::NewL()
+{
+ CUPPrinterContainer* self = new (ELeave) CUPPrinterContainer();
+ CleanupStack::PushL(self);
+ self->ConstructL();
+ CleanupStack::Pop(); // self
+ return self;
+}
+
+//--------------------------------------------------------------------------------------------
+//
+// CUPPrinterContainer::Printer
+//
+//--------------------------------------------------------------------------------------------
+CUPPrinter* CUPPrinterContainer::Printer(CUpnpDevice& aDevice)
+{
+ TInt index = PrinterIndex(aDevice);
+ if(KErrNotFound != index)
+ {
+ return PrinterByIndex(index);
+ }
+ else
+ return NULL;
+}
+
+//--------------------------------------------------------------------------------------------
+//
+// CUPPrinterContainer::Printer
+//
+//--------------------------------------------------------------------------------------------
+CUPPrinter* CUPPrinterContainer::Printer(TInt aId)
+{
+ TInt index = PrinterIndex(aId);
+ if(KErrNotFound != index)
+ {
+ return PrinterByIndex(index);
+ }
+ else
+ return NULL;
+}
+
+
+//--------------------------------------------------------------------------------------------
+//
+// CUPPrinterContainer::ToTPrinter
+//
+//--------------------------------------------------------------------------------------------
+TPrinter CUPPrinterContainer::ToTPrinter(CUpnpDevice& aDevice)
+{
+ TInt index = PrinterIndex(aDevice);
+ return ToTPrinter(index);
+}
+
+//--------------------------------------------------------------------------------------------
+//
+// CUPPrinterContainer::ToTPrinter
+//
+//--------------------------------------------------------------------------------------------
+TPrinter CUPPrinterContainer::ToTPrinter(TInt aIndex)
+{
+ if (aIndex >= iPrinters.Count() )
+ {
+ TPrinter nullPrinter;
+ nullPrinter.iPrinterID = KErrNotFound;
+ nullPrinter.iProtocol = 0;
+ nullPrinter.iProperties = TPrinter::Cached;
+ return nullPrinter;
+ }
+
+ return iPrinters[aIndex]->ToTPrinter();
+}
+
+//--------------------------------------------------------------------------------------------
+//
+// CUPPrinterContainer::PrinterCount
+//
+//--------------------------------------------------------------------------------------------
+TInt CUPPrinterContainer::PrinterCount()
+{
+ return iPrinters.Count();
+}
+
+
+//--------------------------------------------------------------------------------------------
+//
+// CUPPrinterContainer::AddPrinterL
+//
+//--------------------------------------------------------------------------------------------
+void CUPPrinterContainer::AddPrinterL(CUpnpDevice& aDevice, TInt& aId)
+{
+ aId = KErrNotFound;
+
+ // Check if the discovered printer is cached/ disappeared
+ for (TInt i=0; i < iPrinters.Count(); i++)
+ {
+ if (iPrinters[i]->UId().Compare(aDevice.Uuid()) == 0)
+ {
+ // Printer already in array - update pointer
+ iPrinters[i]->SetDevice(&aDevice);
+ if (iPrinters[i]->IsDisappeared())
+ {
+ // remove disappeared flag
+ iPrinters[i]->SetDisappeared(EFalse);
+ }
+ aId = iPrinters[i]->Id();
+ User::Leave(KErrAlreadyExists);
+ }
+ }
+
+ // New printer - append to list
+ TInt id = GenerateId();
+ CUPPrinter* newPrinter = CUPPrinter::NewL(aDevice, id);
+ CleanupStack::PushL(newPrinter);
+ iPrinters.AppendL(newPrinter);
+ CleanupStack::Pop(newPrinter);
+ aId = id;
+}
+
+
+//--------------------------------------------------------------------------------------------
+//
+// CUPPrinterContainer::RemovePrinter
+//
+//--------------------------------------------------------------------------------------------
+TInt CUPPrinterContainer::RemovePrinter(CUpnpDevice& aDevice)
+{
+ TInt index = PrinterIndex(aDevice);
+ if(KErrNotFound != index)
+ {
+ return RemovePrinter(index);
+ }
+ else
+ return index;
+}
+
+//--------------------------------------------------------------------------------------------
+//
+// CUPPrinterContainer::RemovePrinter
+//
+//--------------------------------------------------------------------------------------------
+TInt CUPPrinterContainer::RemovePrinter(TInt aIndex)
+{
+ if (aIndex >= iPrinters.Count() || aIndex < 0)
+ return KErrArgument;
+ CUPPrinter* temp = iPrinters[aIndex];
+ iPrinters.Remove(aIndex);
+ if (temp)
+ {
+ delete temp;
+ temp = NULL;
+ }
+ return KErrNone;
+}
+//--------------------------------------------------------------------------------------------
+//
+// CUPPrinterContainer::RemovePrinter
+//
+//--------------------------------------------------------------------------------------------
+TInt CUPPrinterContainer::RemoveCachedDeviceL(TInt aDeviceID)
+{
+ TInt err = KErrNone;
+ TBool cached = EFalse;
+
+ for (TInt i=0; i < iPrinters.Count(); i++)
+ {
+ if (iPrinters[i]->Id() == aDeviceID)
+ {
+ cached = iPrinters[i]->Cached();
+ iPrinters[i]->SetCached(EFalse);
+ break;
+ }
+ }
+
+ if(!cached)
+ return KErrNone;
+
+ ReadCacheFileL();
+
+ TInt startPos = 0;
+ TInt endPos = 0;
+
+ FindCachedPrinterL(aDeviceID, startPos, endPos);
+
+ LOG1("[CUPPrinterContainer::RemoveCachedDeviceL]\t startPos:\t%d", startPos);
+ LOG1("[CUPPrinterContainer::RemoveCachedDeviceL]\t endPos:\t%d", endPos);
+
+ if(0 < endPos)
+ {
+ //Remove printer form the buffer
+ iCacheBuffer->Des().Delete(startPos, endPos-startPos);
+
+ //Write buffer in file
+ RFile cacheFile;
+ CleanupClosePushL(cacheFile);
+ TInt err = cacheFile.Replace( iFsSession, KUPnPPrinterCache, EFileWrite);
+ if (err == KErrNone)
+ {
+ err = cacheFile.Write(iCacheBuffer->Des());
+ }
+ CleanupStack::PopAndDestroy(&cacheFile);
+ }
+
+ delete iCacheBuffer;
+ iCacheBuffer = NULL;
+
+ return err;
+}
+
+//--------------------------------------------------------------------------------------------
+//
+// CUPPrinterContainer::Printer
+//
+//--------------------------------------------------------------------------------------------
+CUPPrinter* CUPPrinterContainer::PrinterByIndex(TInt aIndex)
+{
+ if (aIndex >= iPrinters.Count() || aIndex < 0)
+ return NULL;
+ return iPrinters[aIndex];
+}
+
+
+//--------------------------------------------------------------------------------------------
+//
+// CUPPrinterContainer::PrinterIndex
+//
+//--------------------------------------------------------------------------------------------
+TInt CUPPrinterContainer::PrinterIndex(CUpnpDevice& aDevice)
+{
+ TPtrC8 uuid = aDevice.Uuid();
+ TInt count = iPrinters.Count();
+ for (TInt i=0; i<count; i++)
+ {
+ TPtrC8 tempUuid = KNullDesC8();
+ if(!iPrinters[i]->IsDisappeared())
+ tempUuid.Set( (iPrinters[i])->Device()->Uuid() );
+
+ if (uuid.Compare(tempUuid) == 0)
+ return i;
+ }
+ return KErrNotFound;
+}
+
+
+//--------------------------------------------------------------------------------------------
+//
+// CUPPrinterContainer::PrinterIndex
+//
+//--------------------------------------------------------------------------------------------
+TInt CUPPrinterContainer::PrinterIndex(TInt aId)
+{
+ TInt count = iPrinters.Count();
+ for (TInt i=0; i<count; i++)
+ {
+ if (aId == iPrinters[i]->Id())
+ return i;
+ }
+
+ return KErrNotFound;
+}
+
+
+//--------------------------------------------------------------------------------------------
+//
+// CUPPrinterContainer::PrinterDisappeared
+//
+//--------------------------------------------------------------------------------------------
+void CUPPrinterContainer::PrinterDisappeared(CUpnpDevice& aDevice)
+{
+ // Check if device is found from iPrinters array. If so add to disappeared array.
+ TInt index = PrinterIndex(aDevice);
+ if ( index >=0 )
+ {
+ iPrinters[index]->SetDisappeared(ETrue);
+ }
+}
+
+
+//--------------------------------------------------------------------------------------------
+//
+// CUPPrinterContainer::SyncPrinterArray
+//
+//--------------------------------------------------------------------------------------------
+void CUPPrinterContainer::SyncPrinterArray()
+{
+ for(TInt i=0; i<iPrinters.Count(); i++)
+ {
+ if (iPrinters[i]->IsDisappeared())
+ {
+ RemovePrinter(i);
+ i--;
+ }
+ }
+}
+
+//--------------------------------------------------------------------------------------------
+//
+// CUPPrinterContainer::UpdateCache
+//
+//--------------------------------------------------------------------------------------------
+void CUPPrinterContainer::UpdateCacheL()
+{
+ // Calculate size for buffer
+ TInt bufSize = 0;
+ for (TInt i=0; i < iPrinters.Count(); i++)
+ {
+ bufSize += 3; // Separators and line feed
+
+ TBuf8<10> id;
+ id.AppendNum(iPrinters[i]->Id());
+ TBuf8<10> vendor;
+ vendor.AppendNum(iPrinters[i]->Vendor());
+
+ bufSize += id.Length();
+ bufSize += iPrinters[i]->DisplayName().Length();
+ bufSize += vendor.Length();
+ bufSize += iPrinters[i]->UId().Length();
+ }
+
+ // Create buffer
+ if(iCacheBuffer)
+ {
+ delete iCacheBuffer;
+ iCacheBuffer = NULL;
+ }
+
+ iCacheBuffer = HBufC8::NewL(bufSize);
+
+ // Write buffer
+ for (TInt i=0; i < iPrinters.Count(); i++)
+ {
+ iCacheBuffer->Des().AppendNum(iPrinters[i]->Id());
+ iCacheBuffer->Des().Append(KUPnPComma());
+ iCacheBuffer->Des().Append(iPrinters[i]->DisplayName());
+ iCacheBuffer->Des().Append(KUPnPComma());
+ iCacheBuffer->Des().AppendNum(iPrinters[i]->Vendor());
+ iCacheBuffer->Des().Append(KUPnPComma());
+ iCacheBuffer->Des().Append(iPrinters[i]->UId());
+ iCacheBuffer->Des().Append(KUPnPLineFeed8());
+ }
+
+ // Write buffer to file
+ RFile cacheFile;
+ TInt err = cacheFile.Replace( iFsSession, KUPnPPrinterCache, EFileWrite);
+ if (err == KErrNone)
+ {
+ err = cacheFile.Write(iCacheBuffer->Des());
+ }
+ cacheFile.Close();
+ User::LeaveIfError(err);
+}
+
+//--------------------------------------------------------------------------------------------
+//
+// CUPPrinterContainer::UpdateCache
+//
+//--------------------------------------------------------------------------------------------
+void CUPPrinterContainer::UpdateCacheL(TInt aDeviceId)
+{
+
+ // Get correct printer
+ CUPPrinter* printer = NULL;
+ for (TInt i=0; i < iPrinters.Count(); i++)
+ {
+ if(iPrinters[i]->Id() == aDeviceId)
+ {
+ printer = iPrinters[i];
+ break;
+ }
+ }
+
+ // Calculate size for buffer
+ TInt bufSize = 0;
+ if(!printer->Cached())
+ {
+ TBuf8<10> id;
+ id.AppendNum(printer->Id());
+
+ TBuf8<10> vendor;
+ vendor.AppendNum(printer->Vendor());
+ vendor.Append(_L8(" "));
+
+ bufSize += id.Length();
+ bufSize += KUPnPComma().Length();
+ bufSize += printer->DisplayName().Length();
+ bufSize += KUPnPComma().Length();
+ bufSize += vendor.Length();
+ bufSize += KUPnPComma().Length();
+ bufSize += printer->UId().Length();
+ bufSize += KUPnPLineFeed().Length();
+
+ // Create buffer
+ HBufC8* fileBuffer = HBufC8::NewL(bufSize);
+ CleanupStack::PushL(fileBuffer);
+
+ fileBuffer->Des().AppendNum(printer->Id());
+ fileBuffer->Des().Append(KUPnPComma());
+ fileBuffer->Des().Append(printer->DisplayName());
+ fileBuffer->Des().Append(KUPnPComma());
+ fileBuffer->Des().Append(vendor);
+ fileBuffer->Des().Append(KUPnPComma());
+ fileBuffer->Des().Append(printer->UId());
+ fileBuffer->Des().Append(KUPnPLineFeed());
+
+
+ RFile cacheFile;
+ CleanupClosePushL(cacheFile);
+ TInt fSize = 0;
+ // Find end of file to write if exists
+ TInt err = cacheFile.Open( iFsSession, KUPnPPrinterCache, EFileWrite);
+ if (err == KErrNone)
+ {
+ cacheFile.Size(fSize);
+ ++fSize;
+ }
+ else
+ {
+ // Write buffer to file
+ User::LeaveIfError(cacheFile.Replace( iFsSession, KUPnPPrinterCache, EFileWrite));
+ }
+ User::LeaveIfError(cacheFile.Write(fSize, fileBuffer->Des()));
+ printer->SetCached(ETrue);
+
+ CleanupStack::PopAndDestroy(2); // fileBuffer, cacheFile
+ }
+}
+
+//--------------------------------------------------------------------------------------------
+//
+// CUPPrinterContainer::GetDisappearedPrinters
+//
+//--------------------------------------------------------------------------------------------
+void CUPPrinterContainer::GetDisappearedPrinters(RPointerArray<CUPPrinter>& aArray)
+{
+ for (TInt i=0; i < iPrinters.Count(); i++)
+ {
+ if (iPrinters[i]->IsDisappeared())
+ {
+ aArray.Append(iPrinters[i]);
+ }
+ }
+}
+
+///////////////////////////
+// Protected functions
+///////////////////////////
+//--------------------------------------------------------------------------------------------
+//
+// CUPPrinterContainer::ConstructL
+//
+//--------------------------------------------------------------------------------------------
+void CUPPrinterContainer::ConstructL()
+{
+ iCacheBuffer = NULL;
+
+ // Init file server session
+ User::LeaveIfError( iFsSession.Connect() );
+
+ TInt err = iFsSession.MkDirAll( KUPnPDataPath );
+ if (err != KErrNone && err != KErrAlreadyExists)
+ {
+ User::Leave(err);
+ }
+
+ User::LeaveIfError(iFsSession.SetSessionPath( KUPnPDataPath ));
+}
+
+///////////////////////////
+// Private functions
+///////////////////////////
+//--------------------------------------------------------------------------------------------
+//
+// CUPPrinterContainer::CUPPrinterContainer
+//
+//--------------------------------------------------------------------------------------------
+CUPPrinterContainer::CUPPrinterContainer()
+{
+ iIdCounter = 0;
+}
+
+
+//--------------------------------------------------------------------------------------------
+//
+// CUPPrinterContainer::ToCDevice
+//
+//--------------------------------------------------------------------------------------------
+CUpnpDevice* CUPPrinterContainer::ToCDevice(TInt aIndex)
+{
+ if (aIndex >= iPrinters.Count() || aIndex < 0 || iPrinters[aIndex]->IsDisappeared())
+ return NULL;
+ return iPrinters[aIndex]->Device();
+}
+
+//--------------------------------------------------------------------------------------------
+//
+// CUPPrinterContainer::ReadCacheL
+//
+//--------------------------------------------------------------------------------------------
+void CUPPrinterContainer::ReadCacheL()
+{
+ LOG("[CUPPrinterContainer::ReadCacheL]\t");
+
+ ReadCacheFileL();
+
+ TPtr8 bufferPtr( iCacheBuffer->Des() );
+
+ // Add cached devices.
+ while (bufferPtr.Find(KUPnPLineFeed8()) >= 0)
+ {
+ // Read id
+ TInt separPos = bufferPtr.Find(KUPnPComma());
+ TInt lfPos = bufferPtr.Find(KUPnPLineFeed8());
+
+ if (lfPos < 1 || lfPos < separPos)
+ {
+ break; // No id could be read
+ }
+
+ TPtrC8 idStr = bufferPtr.Left(separPos);
+ TInt id;
+ TLex8 lex(idStr);
+ TInt error = lex.Val(id);
+ User::LeaveIfError( error );
+
+ bufferPtr = bufferPtr.Right(bufferPtr.Length()-separPos-1);
+
+ // Read display name
+ separPos = bufferPtr.Find(KUPnPComma());
+ lfPos = bufferPtr.Find(KUPnPLineFeed8());
+
+ if (lfPos < 1 || lfPos < separPos)
+ {
+ break; // No name could be read
+ }
+
+ TPtrC8 name = bufferPtr.Left(separPos);
+ TBuf8<100> dispName;
+ dispName.Copy(name);
+ bufferPtr = bufferPtr.Right(bufferPtr.Length()-separPos-1);
+
+ // Read vendor
+ separPos = bufferPtr.Find(KUPnPComma());
+ lfPos = bufferPtr.Find(KUPnPLineFeed8());
+
+ if (lfPos < 1 || lfPos < separPos)
+ {
+ break; // No vendor could be read
+ }
+
+ TPtrC8 vendorStr = bufferPtr.Left(separPos);
+ TInt vendor;
+ TLex8 lexV(vendorStr);
+ TInt err = lexV.Val(vendor);
+
+ // FIX: if error reading vendor, use default 0 and return err to none
+ if ( err != KErrNone )
+ {
+ vendor = 0;
+ err = KErrNone;
+ }
+
+ bufferPtr = bufferPtr.Right(bufferPtr.Length()-separPos-1);
+
+ //Read uid
+ separPos = bufferPtr.Find(KUPnPComma());
+ lfPos = bufferPtr.Find(KUPnPLineFeed8());
+
+ if ( (lfPos < 1) || (lfPos > separPos && separPos >= 0 ) )
+ {
+ break; // No uid could be read
+ }
+
+ TPtrC8 uid = bufferPtr.Left(lfPos);
+
+ // Add cached printer
+ if (err == KErrNone)
+ {
+ AddCachedPrinterL(id, uid, dispName, vendor);
+ }
+
+ bufferPtr = bufferPtr.Right(bufferPtr.Length()-lfPos-1);
+
+ }
+}
+
+//--------------------------------------------------------------------------------------------
+//
+// CUPPrinterContainer::FindCachedPrinterL
+//
+//--------------------------------------------------------------------------------------------
+TPtrC8 CUPPrinterContainer::FindCachedPrinterL(TInt aId, TInt& aStartPos, TInt& aEndPos)
+{
+ LOG("[CUPPrinterContainer::FindCachedPrinterL]\t");
+
+ User::LeaveIfNull(iCacheBuffer);
+ TPtrC8 bufferPtr( iCacheBuffer->Des() );
+
+ TBuf8<10> reqId;
+ reqId.AppendNum(aId);
+
+ aStartPos = 0;
+ aEndPos = 0;
+
+ // Find cached device.
+ while (bufferPtr.Find(KUPnPLineFeed8()) >= 0)
+ {
+ aStartPos = aEndPos;
+
+ // Read id
+ TInt separPos = bufferPtr.Find(KUPnPComma());
+ TInt lfPos = bufferPtr.Find(KUPnPLineFeed8());
+
+ if (lfPos < 1 || lfPos < separPos)
+ {
+ break; // No id could be read
+ }
+
+ aEndPos += lfPos+1;
+
+ LOG81("[CUPPrinterContainer::FindCachedPrinterL]\t bufferPtr: %S", &bufferPtr);
+
+ //Find next printer if id doesn't match
+ if(0 != reqId.Compare(bufferPtr.Left(separPos)))
+ {
+ bufferPtr.Set(bufferPtr.Right(bufferPtr.Length()-lfPos-1));
+ continue;
+ }
+ else
+ {
+ return bufferPtr.Left(aEndPos);
+ }
+ }
+
+ return NULL;
+}
+
+//--------------------------------------------------------------------------------------------
+//
+// CUPPrinterContainer::ReadCacheFileLC
+//
+//--------------------------------------------------------------------------------------------
+void CUPPrinterContainer::ReadCacheFileL()
+{
+ LOG("[CUPPrinterContainer::ReadCacheFileL]\t");
+
+ RFile cacheFile;
+ CleanupClosePushL(cacheFile);
+
+ TInt err = cacheFile.Open( iFsSession, KUPnPPrinterCache, EFileRead );
+
+ if (err == KErrNone)
+ {
+
+ TInt fileSize = 0;
+ err = cacheFile.Size(fileSize);
+ if(err != KErrNone)
+ fileSize = KMaxCacheFileSize;
+
+ iCacheBuffer = HBufC8::NewL(fileSize);
+
+ TPtr8 bufferPtr( iCacheBuffer->Des() );
+ bufferPtr.Zero();
+
+ err = cacheFile.Read(bufferPtr);
+ }
+
+ if (err != KErrNone)
+ {
+ // Problem in opening or reading cache file
+ if (iCacheBuffer)
+ {
+ delete iCacheBuffer;
+ iCacheBuffer = NULL;
+ }
+ iCacheBuffer = HBufC8::NewL(0);
+ // printer not found from cache, leave!
+ User::Leave( KErrNotFound );
+ }
+
+ CleanupStack::PopAndDestroy(); //cacheFile
+}
+
+
+
+//--------------------------------------------------------------------------------------------
+//
+// CUPPrinterContainer::GenerateIdL
+//
+//--------------------------------------------------------------------------------------------
+TInt CUPPrinterContainer::GenerateId()
+{
+ TInt id = -1;
+ for (TInt i=1; i < iPrinters.Count()+2; i++)
+ {
+ TInt j;
+ for (j=0; j < iPrinters.Count(); j++)
+ {
+ if (iPrinters[j]->Id() == i)
+ {
+ break;
+ }
+ }
+
+ if (j == iPrinters.Count())
+ {
+ id = i;
+ break;
+ }
+ }
+
+ return id;
+}
+
+//--------------------------------------------------------------------------------------------
+//
+// CUPPrinterContainer::AddCachedPrinterL
+//
+//--------------------------------------------------------------------------------------------
+void CUPPrinterContainer::AddCachedPrinterL(TInt aId, TDesC8& aUPnPUId, TDesC8& aDisplayName, TInt aVendor)
+{
+ LOG("[CUPPrinterContainer::AddCachedPrinterL]");
+ CUPPrinter* newPrinter = CUPPrinter::NewL(aId, aUPnPUId, aDisplayName, aVendor);
+ newPrinter->SetCached(ETrue);
+ CleanupStack::PushL(newPrinter);
+ iPrinters.AppendL(newPrinter);
+ CleanupStack::Pop(newPrinter);
+}
+
+// End of File