PassOwnPtr<MessagePortChannelArray> MessagePort::disentanglePorts(const MessagePortArray* ports, ExceptionState& exceptionState) { if (!ports || !ports->size()) return nullptr; // HashSet used to efficiently check for duplicates in the passed-in array. HashSet<MessagePort*> portSet; // Walk the incoming array - if there are any duplicate ports, or null ports or cloned ports, throw an error (per section 8.3.3 of the HTML5 spec). for (unsigned i = 0; i < ports->size(); ++i) { MessagePort* port = (*ports)[i].get(); if (!port || port->isNeutered() || portSet.contains(port)) { String type; if (!port) type = "null"; else if (port->isNeutered()) type = "already neutered"; else type = "a duplicate"; exceptionState.throwDOMException(DataCloneError, "Port at index " + String::number(i) + " is " + type + "."); return nullptr; } portSet.add(port); } // Passed-in ports passed validity checks, so we can disentangle them. OwnPtr<MessagePortChannelArray> portArray = adoptPtr(new MessagePortChannelArray(ports->size())); for (unsigned i = 0; i < ports->size(); ++i) (*portArray)[i] = (*ports)[i]->disentangle(); return portArray.release(); }
std::unique_ptr<MessagePortChannelArray> MessagePort::disentanglePorts(const MessagePortArray* ports, ExceptionCode& ec) { if (!ports || !ports->size()) return nullptr; // HashSet used to efficiently check for duplicates in the passed-in array. HashSet<MessagePort*> portSet; // Walk the incoming array - if there are any duplicate ports, or null ports or cloned ports, throw an error (per section 8.3.3 of the HTML5 spec). for (unsigned int i = 0; i < ports->size(); ++i) { MessagePort* port = (*ports)[i].get(); if (!port || port->isNeutered() || portSet.contains(port)) { ec = DATA_CLONE_ERR; return nullptr; } portSet.add(port); } // Passed-in ports passed validity checks, so we can disentangle them. auto portArray = std::make_unique<MessagePortChannelArray>(ports->size()); for (unsigned int i = 0 ; i < ports->size() ; ++i) { std::unique_ptr<MessagePortChannel> channel = (*ports)[i]->disentangle(); (*portArray)[i] = std::move(channel); } return portArray; }
std::unique_ptr<MessagePortChannelArray> MessagePort::disentanglePorts( ExecutionContext* context, const MessagePortArray& ports, ExceptionState& exceptionState) { if (!ports.size()) return nullptr; HeapHashSet<Member<MessagePort>> visited; // Walk the incoming array - if there are any duplicate ports, or null ports // or cloned ports, throw an error (per section 8.3.3 of the HTML5 spec). for (unsigned i = 0; i < ports.size(); ++i) { MessagePort* port = ports[i]; if (!port || port->isNeutered() || visited.contains(port)) { String type; if (!port) type = "null"; else if (port->isNeutered()) type = "already neutered"; else type = "a duplicate"; exceptionState.throwDOMException( DataCloneError, "Port at index " + String::number(i) + " is " + type + "."); return nullptr; } visited.add(port); } UseCounter::count(context, UseCounter::MessagePortsTransferred); // Passed-in ports passed validity checks, so we can disentangle them. std::unique_ptr<MessagePortChannelArray> portArray = wrapUnique(new MessagePortChannelArray(ports.size())); for (unsigned i = 0; i < ports.size(); ++i) (*portArray)[i] = ports[i]->disentangle(); return portArray; }