mtpfws/mtpfw/datatypes/src/cmtptypestring.cpp
changeset 0 d0791faffa3f
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mtpfws/mtpfw/datatypes/src/cmtptypestring.cpp	Tue Feb 02 01:11:40 2010 +0200
@@ -0,0 +1,295 @@
+// Copyright (c) 2006-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
+ @publishedPartner
+*/
+
+#include <mtp/cmtptypestring.h>
+#include <mtp/mtpdatatypeconstants.h>
+
+#include "mtpdatatypespanic.h"
+
+// String type constants
+const TUint KMTPAlignmentOffset(0);
+const TUint KMTPAlignmentSize(1);
+const TUint KMTPNumCharsOffset(KMTPAlignmentOffset + KMTPAlignmentSize);
+const TUint KMTPNumCharsSize(KMTPTypeUINT8Size);
+const TUint KMTPStringCharactersOffset(KMTPNumCharsOffset + KMTPNumCharsSize);
+
+/**
+MTP string data type factory method. This method is used to create a 
+zero-length MTP string.
+@return A pointer to a zero-length MTP string data type. Ownership IS 
+transfered.
+@leave One of the system wide error codes, if unsuccessful.
+*/   
+EXPORT_C CMTPTypeString* CMTPTypeString::NewL()
+    {
+	CMTPTypeString* self = NewLC(); 
+	CleanupStack::Pop(self);
+	return self; 
+    }
+
+/**
+MTP string data type factory method. This method is used to create an 
+MTP string with the specified value.
+@param aString The initial string value.
+@return A pointer to the MTP string data type. Ownership IS transfered.
+@leave One of the system wide error codes, if unsuccessful.
+*/     
+EXPORT_C CMTPTypeString* CMTPTypeString::NewL(const TDesC& aString)
+    {
+	CMTPTypeString* self = NewLC(aString);
+	CleanupStack::Pop(self);
+	return self;
+    }
+
+/**
+MTP string data type factory method. This method is used to create a 
+zero-length MTP string. A pointer to the MTP string data type is placed on the
+cleanup stack.
+@return A pointer to a zero-length MTP string data type. Ownership IS 
+transfered.
+@leave One of the system wide error codes, if unsuccessful.
+*/   
+EXPORT_C CMTPTypeString* CMTPTypeString::NewLC()
+    {
+	CMTPTypeString* self = NewLC(KNullDesC);
+	return self;    
+    }
+
+/**
+MTP string data type factory method. This method is used to create an MTP 
+string with the specified value. A pointer to the MTP string data type is 
+placed on the cleanup stack.
+@param aString The initial string value.
+@return A pointer to the MTP string data type. Ownership IS transfered.
+@leave One of the system wide error codes, if unsuccessful.
+*/      
+EXPORT_C CMTPTypeString* CMTPTypeString::NewLC(const TDesC& aString)
+    {
+	CMTPTypeString* self = new(ELeave) CMTPTypeString;
+	CleanupStack::PushL(self);
+    self->ConstructL(aString);
+	return self;
+    }
+
+/**
+Destructor
+*/
+EXPORT_C CMTPTypeString::~CMTPTypeString()
+    {
+    iBuffer.Close();
+    }
+    
+/**
+Provides the number of unicode characters making up the MTP string.
+@return The number of unicode characters making up the MTP string.
+*/    
+EXPORT_C TUint8 CMTPTypeString::NumChars() const
+    {
+    return iBuffer[KMTPNumCharsOffset];
+    }
+
+/**
+Provides a non-modifiable reference to the MTP String Characters data. The data
+provided does not include the terminating null character.
+@return A non-modifiable MTP string data reference.
+*/  
+EXPORT_C const TDesC& CMTPTypeString::StringChars() const
+    {
+    return iStringChars;
+    }
+    
+/**
+Sets the MTP string data type to the specified value.
+@param aString The type's new value.
+@leave One of the system wide error codes, if a processing error occurs.
+*/     
+EXPORT_C void CMTPTypeString::SetL(const TDesC& aString)
+    {
+    ConstructL(aString);
+    }
+	
+EXPORT_C TInt CMTPTypeString::FirstReadChunk(TPtrC8& aChunk) const
+    {
+	aChunk.Set(&iBuffer[KMTPNumCharsOffset], (iBuffer.Length() - KMTPAlignmentSize));
+    return KMTPChunkSequenceCompletion;
+    }
+	
+EXPORT_C TInt CMTPTypeString::NextReadChunk(TPtrC8& aChunk) const
+    {
+    aChunk.Set(NULL, 0);
+    return KErrNotReady;
+    }
+	
+EXPORT_C TInt CMTPTypeString::FirstWriteChunk(TPtr8& aChunk)
+    {
+    TInt ret(KErrNone);
+    aChunk.Set(&iBuffer[KMTPNumCharsOffset], 0, KMTPNumCharsSize);
+    iWriteSequenceState = ENumChars;        
+    return ret;
+    }
+	
+EXPORT_C TInt CMTPTypeString::NextWriteChunk(TPtr8& aChunk)
+    {
+    TInt ret(KMTPChunkSequenceCompletion);
+    
+    if (iWriteSequenceState != ENumChars)
+        {
+        ret = KErrNotReady;
+        }
+    else
+        {
+        const TUint numChars(NumChars());
+        __ASSERT_ALWAYS((numChars <= KMTPMaxStringLength), Panic(EMTPTypeSizeMismatch));
+        if (numChars > 0)
+            {
+        	aChunk.Set(&iBuffer[KMTPStringCharactersOffset], 0, (iBuffer.MaxLength() - KMTPAlignmentSize - KMTPNumCharsSize));
+            }
+        else
+            {
+            aChunk.Set(NULL, 0, 0);
+            }
+            
+        iWriteSequenceState = EStringChars;
+        }
+        
+    return ret;
+    }
+    
+EXPORT_C TUint64 CMTPTypeString::Size() const
+    {
+	return (iBuffer.Size() - KMTPAlignmentSize);
+    }
+    
+EXPORT_C TUint CMTPTypeString::Type() const
+	{
+	return EMTPTypeString;
+	}
+
+EXPORT_C TBool CMTPTypeString::CommitRequired() const
+    {
+    return ETrue;
+    }
+
+EXPORT_C MMTPType* CMTPTypeString::CommitChunkL(TPtr8& aChunk)
+    {
+    switch (iWriteSequenceState)
+        {
+    case ENumChars:
+        /* 
+        The first chunk specifies the NumChars field, and is used to re-size 
+        the array buffer. 
+        */
+        ReAllocBufferL(NumChars());  
+        break;
+        
+    case EStringChars:
+        // Check that the correct number of characters has been received.
+        {
+        TUint len(aChunk.Length());
+        if ((len % KMTPCharSize) ||
+            ((len / KMTPCharSize) != NumChars()))
+            {
+            iValidationState = KMTPDataTypeInvalid;
+            User::Leave(iValidationState);
+            }
+        iWriteSequenceState = EIdle;
+        }
+        break;
+        
+    case EIdle:
+    default:
+        break;
+        }
+    return NULL;
+    }
+    
+EXPORT_C TInt CMTPTypeString::Validate() const
+    {
+    return iValidationState;
+    }
+
+CMTPTypeString::CMTPTypeString() :
+    iBuffer(),
+    iStringChars(NULL, 0)
+    {
+
+    }
+
+void CMTPTypeString::ConstructL(const TDesC& aString)
+    {
+    if (aString.Length() > KMTPMaxStringCharactersLength)
+        {
+        User::Leave(KErrArgument);            
+        }
+    
+    // Allocate string storage.
+    TUint numChars(aString.Length());
+    if (numChars)
+        {
+        numChars += KMTPNullCharLen;   
+        }
+    ReAllocBufferL(numChars);
+    
+    // Append the String Characters.
+    if (numChars > 0)
+        {
+        iStringChars.Copy(aString);
+        }
+    }
+
+void CMTPTypeString::ReAllocBufferL(TUint aNumNullTerminatedChars)
+    {
+    if (aNumNullTerminatedChars > KMTPMaxStringLength)
+        {
+        User::Leave(KErrOverflow);            
+        }
+        
+    // Delete the current buffer
+    iBuffer.Close();
+    iStringChars.Set(NULL, 0, 0);
+    
+    // Allocate a new buffer.
+    if (aNumNullTerminatedChars > 0)
+        {  
+        /*
+        Allocate storage for both the NumChars and String Characters fields. A single 
+        alignment byte is pre-pended to force String Characters to be 16-bit aligned.
+        */
+        iBuffer.CreateMaxL(KMTPAlignmentSize + KMTPNumCharsSize + (aNumNullTerminatedChars * KMTPCharSize));
+        
+        // Insert the terminating NULL character.
+        TUint numChars(aNumNullTerminatedChars - KMTPNullCharLen);
+        memcpy(&iBuffer[KMTPStringCharactersOffset + (numChars * KMTPCharSize)], &KMTPNullChar, KMTPCharSize);
+        
+        // Set the String Characters pointer.
+        iStringChars.Set(reinterpret_cast<TUint16*>(&iBuffer[KMTPStringCharactersOffset]), numChars, numChars);
+        }
+    else
+        {       
+        /*
+        Allocate storage for the NumChars field only. A single alignment byte 
+        is pre-pended to force String Characters to be 16-bit aligned.
+        */
+        iBuffer.CreateMaxL(KMTPNumCharsSize + KMTPAlignmentSize);
+        }
+        
+    // Insert the NumChars value
+    iBuffer[KMTPNumCharsOffset] = aNumNullTerminatedChars;
+    }