예제 #1
0
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();
}
예제 #2
0
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;
}
예제 #3
0
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;
}