forked from mirrors/gecko-dev
		
	 9c12bdf9af
			
		
	
	
		9c12bdf9af
		
	
	
	
	
		
			
			This moves it near the cross-process `PContent` actor, and makes it more clear that this actor is only intended to be used for DOM things. Differential Revision: https://phabricator.services.mozilla.com/D80581
		
			
				
	
	
		
			263 lines
		
	
	
	
		
			8.3 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			263 lines
		
	
	
	
		
			8.3 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 | |
| /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 | |
| /* This Source Code Form is subject to the terms of the Mozilla Public
 | |
|  * License, v. 2.0. If a copy of the MPL was not distributed with this
 | |
|  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 | |
| 
 | |
| #include "PropertyBagUtils.h"
 | |
| 
 | |
| #include "mozilla/SimpleEnumerator.h"
 | |
| #include "mozilla/dom/DOMTypes.h"
 | |
| #include "nsCOMPtr.h"
 | |
| #include "nsHashPropertyBag.h"
 | |
| #include "nsID.h"
 | |
| #include "nsIProperty.h"
 | |
| #include "nsIURI.h"
 | |
| #include "nsVariant.h"
 | |
| 
 | |
| using namespace IPC;
 | |
| using namespace mozilla::dom;
 | |
| 
 | |
| namespace mozilla {
 | |
| namespace ipc {
 | |
| 
 | |
| void IPDLParamTraits<nsIVariant*>::Write(Message* aMsg, IProtocol* aActor,
 | |
|                                          nsIVariant* aParam) {
 | |
|   IDPLVariant variant;
 | |
| 
 | |
|   variant.type() = aParam->GetDataType();
 | |
| 
 | |
|   switch (variant.type()) {
 | |
|     case nsIDataType::VTYPE_INT8:
 | |
|     case nsIDataType::VTYPE_UINT8:
 | |
|     case nsIDataType::VTYPE_CHAR: {
 | |
|       uint8_t value;
 | |
|       MOZ_ALWAYS_SUCCEEDS(aParam->GetAsUint8(&value));
 | |
|       variant.data() = value;
 | |
|       break;
 | |
|     }
 | |
|     case nsIDataType::VTYPE_WCHAR:
 | |
|     case nsIDataType::VTYPE_INT16: {
 | |
|       int16_t value;
 | |
|       MOZ_ALWAYS_SUCCEEDS(aParam->GetAsInt16(&value));
 | |
|       variant.data() = value;
 | |
|       break;
 | |
|     }
 | |
|     case nsIDataType::VTYPE_UINT16: {
 | |
|       uint16_t value;
 | |
|       MOZ_ALWAYS_SUCCEEDS(aParam->GetAsUint16(&value));
 | |
|       variant.data() = value;
 | |
|       break;
 | |
|     }
 | |
|     case nsIDataType::VTYPE_INT32: {
 | |
|       int32_t value;
 | |
|       MOZ_ALWAYS_SUCCEEDS(aParam->GetAsInt32(&value));
 | |
|       variant.data() = value;
 | |
|       break;
 | |
|     }
 | |
|     case nsIDataType::VTYPE_UINT32: {
 | |
|       uint32_t value;
 | |
|       MOZ_ALWAYS_SUCCEEDS(aParam->GetAsUint32(&value));
 | |
|       variant.data() = value;
 | |
|       break;
 | |
|     }
 | |
|     case nsIDataType::VTYPE_FLOAT: {
 | |
|       float value;
 | |
|       MOZ_ALWAYS_SUCCEEDS(aParam->GetAsFloat(&value));
 | |
|       variant.data() = value;
 | |
|       break;
 | |
|     }
 | |
|     case nsIDataType::VTYPE_DOUBLE: {
 | |
|       double value;
 | |
|       MOZ_ALWAYS_SUCCEEDS(aParam->GetAsDouble(&value));
 | |
|       variant.data() = value;
 | |
|       break;
 | |
|     }
 | |
|     case nsIDataType::VTYPE_BOOL: {
 | |
|       bool value;
 | |
|       MOZ_ALWAYS_SUCCEEDS(aParam->GetAsBool(&value));
 | |
|       variant.data() = value;
 | |
|       break;
 | |
|     }
 | |
|     case nsIDataType::VTYPE_ID: {
 | |
|       nsID value;
 | |
|       MOZ_ALWAYS_SUCCEEDS(aParam->GetAsID(&value));
 | |
|       variant.data() = value;
 | |
|       break;
 | |
|     }
 | |
|     case nsIDataType::VTYPE_ASTRING:
 | |
|     case nsIDataType::VTYPE_WCHAR_STR:
 | |
|     case nsIDataType::VTYPE_WSTRING_SIZE_IS: {
 | |
|       nsString value;
 | |
|       MOZ_ALWAYS_SUCCEEDS(aParam->GetAsAString(value));
 | |
|       variant.data() = value;
 | |
|       break;
 | |
|     }
 | |
|     case nsIDataType::VTYPE_CSTRING:
 | |
|     case nsIDataType::VTYPE_CHAR_STR:
 | |
|     case nsIDataType::VTYPE_STRING_SIZE_IS:
 | |
|     case nsIDataType::VTYPE_UTF8STRING: {
 | |
|       nsCString value;
 | |
|       MOZ_ALWAYS_SUCCEEDS(aParam->GetAsACString(value));
 | |
|       variant.data() = value;
 | |
|       break;
 | |
|     }
 | |
|     case nsIDataType::VTYPE_INTERFACE:
 | |
|     case nsIDataType::VTYPE_INTERFACE_IS: {
 | |
|       nsIID* iid;
 | |
|       nsCOMPtr<nsISupports> value;
 | |
|       MOZ_ALWAYS_SUCCEEDS(aParam->GetAsInterface(&iid, getter_AddRefs(value)));
 | |
|       free(iid);
 | |
|       // We only accept nsIURI and nsIPrincipal interface types, patch welcome.
 | |
|       if (nsCOMPtr<nsIURI> uri = do_QueryInterface(value)) {
 | |
|         variant.data() = uri;
 | |
|       } else if (nsCOMPtr<nsIPrincipal> principal = do_QueryInterface(value)) {
 | |
|         variant.data() = principal;
 | |
|       } else if (value) {
 | |
|         variant.type() = nsIDataType::VTYPE_EMPTY;
 | |
|         variant.data() = false;  // because we need something.
 | |
|       } else {
 | |
|         // Let's pretend like we had a null URI, though how do we know
 | |
|         // it wasn't a null principal?
 | |
|         variant.data() = (nsIURI*)nullptr;
 | |
|       }
 | |
|       break;
 | |
|     }
 | |
|     case nsIDataType::VTYPE_VOID:
 | |
|     case nsIDataType::VTYPE_EMPTY:
 | |
|       variant.data() = false;  // because we need something.
 | |
|       break;
 | |
|     default:
 | |
|       MOZ_CRASH("Non handled variant type, patch welcome");
 | |
|       break;
 | |
|   }
 | |
|   WriteIPDLParam(aMsg, aActor, variant);
 | |
| }
 | |
| 
 | |
| bool IPDLParamTraits<nsIVariant*>::Read(const Message* aMsg,
 | |
|                                         PickleIterator* aIter,
 | |
|                                         IProtocol* aActor,
 | |
|                                         RefPtr<nsIVariant>* aResult) {
 | |
|   IDPLVariant value;
 | |
|   if (!ReadIPDLParam(aMsg, aIter, aActor, &value)) {
 | |
|     return false;
 | |
|   }
 | |
| 
 | |
|   auto variant = MakeRefPtr<nsVariant>();
 | |
| 
 | |
|   switch (value.type()) {
 | |
|     case nsIDataType::VTYPE_INT8:
 | |
|     case nsIDataType::VTYPE_UINT8:
 | |
|       if (value.type() == nsIDataType::VTYPE_INT8) {
 | |
|         variant->SetAsInt8(value.data().get_uint8_t());
 | |
|       } else {
 | |
|         variant->SetAsUint8(value.data().get_uint8_t());
 | |
|       }
 | |
|       break;
 | |
|     case nsIDataType::VTYPE_INT16:
 | |
|       variant->SetAsInt16(value.data().get_int16_t());
 | |
|       break;
 | |
|     case nsIDataType::VTYPE_INT32:
 | |
|       variant->SetAsInt32(value.data().get_int32_t());
 | |
|       break;
 | |
|     case nsIDataType::VTYPE_UINT16:
 | |
|       variant->SetAsUint16(value.data().get_uint16_t());
 | |
|       break;
 | |
|     case nsIDataType::VTYPE_UINT32:
 | |
|       variant->SetAsUint32(value.data().get_uint32_t());
 | |
|       break;
 | |
|     case nsIDataType::VTYPE_FLOAT:
 | |
|       variant->SetAsFloat(value.data().get_float());
 | |
|       break;
 | |
|     case nsIDataType::VTYPE_DOUBLE:
 | |
|       variant->SetAsDouble(value.data().get_double());
 | |
|       break;
 | |
|     case nsIDataType::VTYPE_BOOL:
 | |
|       variant->SetAsBool(value.data().get_bool());
 | |
|       break;
 | |
|     case nsIDataType::VTYPE_CHAR:
 | |
|       variant->SetAsChar(value.data().get_uint8_t());
 | |
|       break;
 | |
|     case nsIDataType::VTYPE_WCHAR:
 | |
|       variant->SetAsWChar(value.data().get_int16_t());
 | |
|       break;
 | |
|     case nsIDataType::VTYPE_ID:
 | |
|       variant->SetAsID(value.data().get_nsID());
 | |
|       break;
 | |
|     case nsIDataType::VTYPE_ASTRING:
 | |
|     case nsIDataType::VTYPE_WCHAR_STR:
 | |
|     case nsIDataType::VTYPE_WSTRING_SIZE_IS:
 | |
|       variant->SetAsAString(value.data().get_nsString());
 | |
|       break;
 | |
|     case nsIDataType::VTYPE_CSTRING:
 | |
|     case nsIDataType::VTYPE_CHAR_STR:
 | |
|     case nsIDataType::VTYPE_STRING_SIZE_IS:
 | |
|       variant->SetAsACString(value.data().get_nsCString());
 | |
|       break;
 | |
|     case nsIDataType::VTYPE_UTF8STRING:
 | |
|       variant->SetAsAUTF8String(value.data().get_nsCString());
 | |
|       break;
 | |
|     case nsIDataType::VTYPE_INTERFACE:
 | |
|     case nsIDataType::VTYPE_INTERFACE_IS:
 | |
|       if (value.data().type() == IPDLVariantValue::TnsIURI) {
 | |
|         variant->SetAsISupports(value.data().get_nsIURI());
 | |
|       } else if (value.data().type() == IPDLVariantValue::TnsIPrincipal) {
 | |
|         variant->SetAsISupports(value.data().get_nsIPrincipal());
 | |
|       } else {
 | |
|         MOZ_CRASH("Unexpected interface type");
 | |
|       }
 | |
|       break;
 | |
|     case nsIDataType::VTYPE_VOID:
 | |
|       variant->SetAsVoid();
 | |
|       break;
 | |
|     case nsIDataType::VTYPE_EMPTY:
 | |
|       break;
 | |
|     default:
 | |
|       MOZ_CRASH("Non handled variant type, patch welcome");
 | |
|       return false;
 | |
|   }
 | |
|   *aResult = std::move(variant);
 | |
|   return true;
 | |
| }
 | |
| 
 | |
| void IPDLParamTraits<nsIPropertyBag2*>::Write(Message* aMsg, IProtocol* aActor,
 | |
|                                               nsIPropertyBag2* aParam) {
 | |
|   // We send a nsIPropertyBag as an array of IPDLProperty
 | |
|   nsTArray<IPDLProperty> bag;
 | |
| 
 | |
|   nsCOMPtr<nsISimpleEnumerator> enumerator;
 | |
|   if (aParam &&
 | |
|       NS_SUCCEEDED(aParam->GetEnumerator(getter_AddRefs(enumerator)))) {
 | |
|     for (auto& property : SimpleEnumerator<nsIProperty>(enumerator)) {
 | |
|       nsString name;
 | |
|       nsCOMPtr<nsIVariant> value;
 | |
|       MOZ_ALWAYS_SUCCEEDS(property->GetName(name));
 | |
|       MOZ_ALWAYS_SUCCEEDS(property->GetValue(getter_AddRefs(value)));
 | |
|       bag.AppendElement(IPDLProperty{name, value});
 | |
|     }
 | |
|   }
 | |
|   WriteIPDLParam(aMsg, aActor, bag);
 | |
| }
 | |
| 
 | |
| bool IPDLParamTraits<nsIPropertyBag2*>::Read(const Message* aMsg,
 | |
|                                              PickleIterator* aIter,
 | |
|                                              IProtocol* aActor,
 | |
|                                              RefPtr<nsIPropertyBag2>* aResult) {
 | |
|   nsTArray<IPDLProperty> bag;
 | |
|   if (!ReadIPDLParam(aMsg, aIter, aActor, &bag)) {
 | |
|     return false;
 | |
|   }
 | |
| 
 | |
|   auto properties = MakeRefPtr<nsHashPropertyBag>();
 | |
| 
 | |
|   for (auto& entry : bag) {
 | |
|     nsCOMPtr<nsIVariant> variant = std::move(entry.value());
 | |
|     MOZ_ALWAYS_SUCCEEDS(
 | |
|         properties->SetProperty(std::move(entry.name()), variant));
 | |
|   }
 | |
|   *aResult = std::move(properties);
 | |
|   return true;
 | |
| }
 | |
| 
 | |
| }  // namespace ipc
 | |
| }  // namespace mozilla
 |