// Copyright © 2015 The CefSharp Authors. All rights reserved.
//
// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
#pragma once
#include "Stdafx.h"
#include "include\cef_request.h"
#include "PostDataElement.h"
#include "Internals\TypeConversion.h"
#include "Internals\CefWrapper.h"
using namespace System::Collections::Generic;
using namespace System::Collections::ObjectModel;
namespace CefSharp
{
///
/// Form Post Data
///
///
public ref class PostData : public IPostData, public CefWrapper
{
MCefRefPtr _postData;
List^ _postDataElements;
internal:
PostData(CefRefPtr &postData) :
_postData(postData)
{
}
///
/// Finalizer.
///
!PostData()
{
_postData = nullptr;
}
///
/// Destructor.
///
~PostData()
{
this->!PostData();
if (_postDataElements != nullptr)
{
//Make sure the unmanaged resources are handled
for each (IPostDataElement^ element in _postDataElements)
{
delete element;
}
_postDataElements = nullptr;
}
_disposed = true;
}
///
/// Throw exception if Readonly
///
/// Thrown when an exception error condition occurs.
void ThrowIfReadOnly()
{
if (IsReadOnly)
{
throw gcnew Exception(gcnew String(L"This IPostDataWrapper is readonly and cannot be modified."));
}
}
public:
///
/// Default constructor.
///
PostData()
{
_postData = CefPostData::Create();
}
///
/// Returns true if this object is read-only.
///
virtual property bool IsReadOnly
{
bool get()
{
ThrowIfDisposed();
return _postData->IsReadOnly();
}
}
///
/// Retrieve the post data elements.
///
virtual property IList^ Elements
{
IList^ get()
{
ThrowIfDisposed();
if (_postDataElements == nullptr)
{
_postDataElements = gcnew List();
auto elementCount = _postData.get() ? _postData->GetElementCount() : 0;
if (elementCount == 0)
{
return gcnew ReadOnlyCollection(_postDataElements);
}
CefPostData::ElementVector ev;
_postData->GetElements(ev);
for (CefPostData::ElementVector::iterator it = ev.begin(); it != ev.end(); ++it)
{
CefPostDataElement *el = it->get();
_postDataElements->Add(gcnew PostDataElement(el));
}
}
return gcnew ReadOnlyCollection(_postDataElements);
}
}
///
/// Add the specified .
///
/// element to be added.
/// Returns true if the add succeeds.
virtual bool AddElement(IPostDataElement^ element)
{
ThrowIfDisposed();
ThrowIfReadOnly();
//Access the Elements collection to initialize the underlying _postDataElements collection
auto elements = Elements;
//If the element has already been added then don't add it again
if (elements->Contains(element))
{
return false;
}
_postDataElements->Add(element);
auto elementWrapper = (PostDataElement^)element;
return _postData->AddElement(elementWrapper);
}
///
/// Remove the specified .
///
/// element to be removed.
/// Returns true if the add succeeds.
virtual bool RemoveElement(IPostDataElement^ element)
{
ThrowIfDisposed();
ThrowIfReadOnly();
//Access the Elements collection to initialize the underlying _postDataElements collection
auto elements = Elements;
if (!elements->Contains(element))
{
return false;
}
_postDataElements->Remove(element);
auto elementWrapper = (PostDataElement^)element;
return _postData->RemoveElement(elementWrapper);
}
///
/// Remove all existing post data elements.
///
virtual void RemoveElements()
{
ThrowIfDisposed();
ThrowIfReadOnly();
_postData->RemoveElements();
}
///
/// Create a new instance
///
/// PostDataElement
virtual IPostDataElement^ CreatePostDataElement()
{
auto element = CefPostDataElement::Create();
return gcnew PostDataElement(element);
}
///
/// Returns true if the underlying POST data includes elements that are not
/// represented by this IPostData object (for example, multi-part file upload
/// data). Modifying IPostData objects with excluded elements may result in
/// the request failing.
///
virtual property bool HasExcludedElements
{
bool get()
{
ThrowIfDisposed();
return _postData->HasExcludedElements();
}
}
operator CefRefPtr()
{
if (this == nullptr)
{
return NULL;
}
return _postData.get();
}
};
}