webengine/osswebengine/WebCore/platform/network/symbian/HttpPostDataSupplier.cpp
changeset 0 dd21522fd290
child 38 4917f9bf7995
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/webengine/osswebengine/WebCore/platform/network/symbian/HttpPostDataSupplier.cpp	Mon Mar 30 12:54:55 2009 +0300
@@ -0,0 +1,238 @@
+/*
+* Copyright (c) 2006 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of the License "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:  Implementation of HttpPostDataSupplier
+*
+*/
+
+
+// INCLUDE FILES
+#include "config.h"
+
+#include <e32std.h>
+#include <e32base.h>
+#include "HttpPostDataSupplier.h"
+#include "PostDataItem.h"
+#include "FormData.h"
+#include "brctl.h"
+
+using namespace WebCore;
+
+// EXTERNAL DATA STRUCTURES
+
+// EXTERNAL FUNCTION PROTOTYPES
+
+// CONSTANTS
+// The post is transmitted in parts. A buffer is allocated of max size to
+// contain the next part to be transmitted. 
+const TInt KPartMaxSize = 10240;
+
+// MACROS
+
+// LOCAL CONSTANTS AND MACROS
+
+// MODULE DATA STRUCTURES
+
+// LOCAL FUNCTION PROTOTYPES
+
+// FORWARD DECLARATIONS
+
+// ============================= LOCAL FUNCTIONS ===============================
+
+
+// ============================ MEMBER FUNCTIONS ===============================
+
+
+void HttpPostDataSupplier::initL(FormData* formData)
+{
+    m_firstPart = true;
+    m_lastPart = false;
+    m_dataPart = NULL;
+    m_totalSize = 0;
+    m_postItemIndex = 0;
+    m_refCount = 0;
+
+    PostDataItem* postDataItem = NULL;
+    //iterate thru the post items and create CPostDataItem instance for each data
+    size_t n = formData->elements().size();
+    for (size_t index = 0; index < n; ++index) {
+        const FormDataElement& formDataElement = formData->elements()[index];
+        if (formDataElement.m_type == FormDataElement::data) {
+            postDataItem = new (ELeave) PostDataItem;
+            // No CleanupStack support for a class that is not based on CBase.
+            m_postData.append(postDataItem);
+            postDataItem->initL(&formDataElement);
+        }
+        else {
+            ASSERT(formDataElement.m_type == FormDataElement::encodedFile);
+            // if a file read failed, just ignore the form element and instead
+            // post rest of the content
+            postDataItem = new(ELeave) FileDataItem;
+            m_postData.append(postDataItem);
+            TRAPD(error, postDataItem->initL(&formDataElement));
+            if (error != KErrNone) {
+                m_postData.removeLast();
+                delete postDataItem;
+                if(error == KErrNoMemory) {
+                    User::Leave(error);
+                }
+                continue;
+            }
+        }
+        // get the size of the data and add to the total size 
+        m_totalSize += postDataItem->pendingContentSize();
+    }
+}
+
+
+// -----------------------------------------------------------------------------
+// HttpPostDataSupplier::HttpPostDataSupplier
+// C++ default constructor can NOT contain any code, that
+// might leave.
+// -----------------------------------------------------------------------------
+//
+HttpPostDataSupplier::HttpPostDataSupplier(RHTTPTransaction* transaction, CBrCtl* brctl) 
+:m_transaction(transaction), m_brctl(brctl)
+{
+}
+
+
+HttpPostDataSupplier::~HttpPostDataSupplier()
+{
+    deleteAllValues(m_postData);
+}
+
+// -----------------------------------------------------------------------------
+// HttpPostDataSupplier::ReleaseData
+// 
+// -----------------------------------------------------------------------------
+//
+void HttpPostDataSupplier::ReleaseData()
+{
+    delete m_dataPart;
+    m_dataPart = NULL;
+    if(!m_lastPart) {
+        TRAP_IGNORE(m_transaction->NotifyNewRequestBodyPartL());
+    }
+}
+
+// -----------------------------------------------------------------------------
+// HttpPostDataSupplier::OverallDataSize
+// 
+// -----------------------------------------------------------------------------
+//
+TInt HttpPostDataSupplier::OverallDataSize() 
+{
+    return m_totalSize; 
+}
+
+// -----------------------------------------------------------------------------
+// HttpPostDataSupplier::OverallDataSize
+// 
+// -----------------------------------------------------------------------------
+//
+TInt HttpPostDataSupplier::Reset() 
+{
+    m_firstPart = true;
+    m_postItemIndex = 0;
+    m_lastPart = false;
+    //iterate thru the post items and create CPostDataItem instance for each data
+    size_t n = m_postData.size();
+    for (int index  = 0 ; index < m_postData.size(); index++) {
+        PostDataItem* postDataItem = m_postData[index];     
+        postDataItem->reset();
+    }
+    delete m_dataPart;
+    m_dataPart = NULL;
+    return KErrNone; 
+}
+
+// -----------------------------------------------------------------------------
+// HttpPostDataSupplier::getNextDataPartL
+// Accessor function to the request body. Return the body in one chunk.
+// -----------------------------------------------------------------------------
+//
+void HttpPostDataSupplier::getNextDataPartL(TPtrC8& aDataPart)
+{
+    if(m_totalSize > KPartMaxSize && m_firstPart /*&& iBrCtlLoadEventObserver*/) {
+        m_brctl->HandleBrowserLoadEventL( 
+            TBrCtlDefs::EEventUploadStart, m_totalSize / 1000, 0) ;            
+        m_firstPart = false;
+    }
+    // release previous part if it is still valid
+    delete m_dataPart;
+    m_dataPart = NULL;
+    int partSize = 0;
+    int partPostItems = m_postItemIndex;
+    // find out the amount of memory that needs to be allocated for this part
+    while (partPostItems < m_postData.size()) {
+        PostDataItem* postDataItem = m_postData[partPostItems];
+        if((partSize += postDataItem->pendingContentSize()) > KPartMaxSize ) {
+            partSize = KPartMaxSize;
+            break;
+        }
+        partPostItems++;
+    }    
+    // read the content of the items 
+    m_dataPart = HBufC8::NewL(partSize);
+    for (int index = m_postItemIndex; index < m_postData.size() && index <= partPostItems; index++) {
+        PostDataItem* postDataItem = m_postData[index];
+        HBufC8* itemContent = postDataItem->dataL(partSize - m_dataPart->Length());
+        m_dataPart->Des().Append( *itemContent );
+        delete itemContent;
+    } 
+    // if all the items have been read 
+    if(partPostItems == m_postData.size()) {
+        m_lastPart = true;
+    }
+    else {
+    // if the last part has more data to be posted , set m_postItemIndex to that index else advance the index
+        if(m_postData[partPostItems]->pendingContentSize()) {
+            m_postItemIndex = partPostItems;
+        }
+        // advance to the next item
+        else {
+            m_postItemIndex = partPostItems + 1;    
+        }
+    }    
+    aDataPart.Set(m_dataPart->Des());
+    if(m_totalSize > KPartMaxSize) {
+        if(!m_lastPart) {
+            m_brctl->HandleBrowserLoadEventL( 
+                TBrCtlDefs::EEventUploadIncrement, aDataPart.Length()/1000, 0) ;            
+        }
+        else {
+            m_brctl->HandleBrowserLoadEventL( 
+                TBrCtlDefs::EEventUploadFinished, aDataPart.Length()/1000, 0) ;            
+        }
+    }
+}
+
+// -----------------------------------------------------------------------------
+// HttpPostDataSupplier::GetNextDataPart
+// Accessor function to the request body. Return the body in one chunk.
+// -----------------------------------------------------------------------------
+//
+TBool HttpPostDataSupplier::GetNextDataPart(TPtrC8& aDataPart)
+{
+    if(!m_lastPart) {
+        TRAP_IGNORE( getNextDataPartL(aDataPart));
+        // TODO:how should the error be handled ????, should the transaction be cancelled
+    }
+    else {
+        aDataPart.Set(KNullDesC8);
+    }
+    return m_lastPart;
+}
+
+//  End of File