commsfwsupport/commselements/NetMeta/src/MetaContainer.cpp
changeset 0 dfb7c4ff071f
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/commsfwsupport/commselements/NetMeta/src/MetaContainer.cpp	Thu Dec 17 09:22:25 2009 +0200
@@ -0,0 +1,183 @@
+// Copyright (c) 2004-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:
+//
+
+/**
+ @file 
+ @internalTechnology
+*/
+
+#include <elements/metacontainer.h>
+#include <elements/metadata.h>
+
+namespace Meta
+{
+const TInt KContainerUid = 0x10205A04;
+}
+
+using namespace Meta;
+
+
+EXPORT_C RMetaDataContainerBase::RMetaDataContainerBase()
+/**
+ * Constructor
+ */
+    {	
+    }
+
+EXPORT_C STypeId RMetaDataContainerBase::GetTypeId() const
+	{
+	return STypeId::CreateSTypeId( KContainerUid, KNetMetaTypeAny );
+	}
+
+EXPORT_C void RMetaDataContainerBase::Copy(const RMetaDataContainerBase& aMetaContainer)
+/**
+ * Copies a content of a meta container into this container.
+ * Copies only pointers (does not do a deep copy).
+ */
+	{
+	TUint count = aMetaContainer.Count();
+
+	for (TUint i = 0; i < count; ++i)
+		{
+		Append(aMetaContainer[i]);
+		}
+	}
+
+EXPORT_C TInt RMetaDataContainerBase::Store(TDes8& aDes) const
+/**
+ * Stores the content of this container in a descriptor.
+ */
+    {
+	if (aDes.MaxLength()-aDes.Length() < this->Length())
+		{
+		return KErrArgument;
+		}
+
+	const STypeId& typeId = GetTypeId();
+	aDes.Append((TUint8*)&typeId,sizeof(STypeId)); //store TID
+
+    TInt count = Count();
+	TInt length = Length();
+	aDes.Append((TUint8*)&length, sizeof(TInt32));	// Store Length of container
+
+    for (TInt i = 0; i < count; ++i)
+        {
+		SMetaData* element = (*this)[i];
+		if (element)
+			{
+	        TInt ret = element->Store(aDes);    //store the object
+			if (ret != KErrNone)
+				{
+				return ret;
+				}
+			}
+		else
+			{
+			if (aDes.MaxLength() - aDes.Length() < (TInt) sizeof(TUint32))
+				{
+				return KErrOverflow;
+				}
+			const TUint32 KNullInt = 0;
+			aDes.Append((TUint8*)&KNullInt, sizeof(TUint32));
+			}
+        }
+	return KErrNone;
+    }
+
+EXPORT_C TInt RMetaDataContainerBase::Load(TPtrC8& aDes)
+/**
+ * Loads a content from a descriptor into this container.
+ */
+	{
+	ResetAndDestroy();
+    TInt32 containerLength;
+    Mem::Copy(&containerLength, aDes.Ptr() ,sizeof(TInt32));
+
+	if (containerLength < 0 || (containerLength - sizeof(STypeId))> aDes.Length())
+		{
+		// Fatal error, descriptor is corrupt
+		return KErrArgument;
+		}
+
+	// Construct a buffer to work on for this container
+	TPtrC8 containerBuffer(aDes.Ptr() + sizeof(TInt32),	
+		containerLength - sizeof (STypeId) - sizeof (TInt32));
+
+	// Move descriptor pointer past the container buffer
+	aDes.Set(aDes.Ptr() + containerLength - sizeof (STypeId), aDes.Length() - containerLength + sizeof (STypeId));
+
+	while (containerBuffer.Length() > 0)
+		{
+		if (containerBuffer.Length() < (TInt) sizeof(TUint32))
+			{
+			return KErrArgument;
+			}
+
+		// Check for a NULL pointer when stored (First four bytes == 0)
+		TUint32 firstFourBytes;
+        Mem::Copy(&firstFourBytes, containerBuffer.Ptr(), sizeof(TUint32));
+		if (firstFourBytes == 0)
+			{
+			// The pointer was NULL when it was stored
+			containerBuffer.Set(containerBuffer.Ptr() + sizeof(TUint32), containerBuffer.Length() - sizeof(TUint32));
+			TRAPD(error, AppendL(NULL));
+			if (error != KErrNone)
+				{
+				return error;
+				}
+			}
+		else
+			{
+			SMetaData* containerItem = NULL;
+			TRAPD(error, containerItem = LoadElementL(containerBuffer));
+			if (error == KErrNone)
+				{
+				TRAP(error, AppendL(containerItem));
+				}
+			if (error != KErrNone && error != KErrNotFound)
+				{
+				delete containerItem;
+				return error;
+				}
+			}
+		}
+	return KErrNone;
+	}
+
+EXPORT_C TInt RMetaDataContainerBase::Length() const
+/**
+ * Returns the length of the content of this container if it was to be stored.
+ */
+	{
+    TInt length = 0, count = this->Count();
+    for (TInt i = 0; i < count; ++i)
+		{
+		SMetaData* element = (*this)[i];
+		if (element)
+			{
+			// UID + Object Type Id + Length Parameter + Length of Data
+			length += element->Length();
+			}
+		else
+			{
+			// Add length of null word (Used to represent a NULL pointer)
+			length += sizeof(TUint32);
+			}
+		}
+	return length + sizeof(TInt32) + sizeof(STypeId);
+	}
+
+
+