ImagePrint/ImagePrintEngine/DeviceProtocols/upnpprotocolfw2/src/cupprintercontainer.cpp
changeset 0 d11fb78c4374
child 2 acc370d7f2f6
--- /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