// static already_AddRefed<ReadStream> ReadStream::Create(const CacheReadStream& aReadStream) { // The parameter may or may not be for a Cache created stream. The way we // tell is by looking at the stream control actor. If the actor exists, // then we know the Cache created it. if (!aReadStream.controlChild() && !aReadStream.controlParent()) { return nullptr; } MOZ_ASSERT(!aReadStream.pushStreamChild()); MOZ_ASSERT(!aReadStream.pushStreamParent()); // Control is guaranteed to survive this method as ActorDestroy() cannot // run on this thread until we complete. StreamControl* control; if (aReadStream.controlChild()) { auto actor = static_cast<CacheStreamControlChild*>(aReadStream.controlChild()); control = actor; } else { auto actor = static_cast<CacheStreamControlParent*>(aReadStream.controlParent()); control = actor; } MOZ_ASSERT(control); AutoTArray<FileDescriptor, 4> fds; control->DeserializeFds(aReadStream, fds); nsCOMPtr<nsIInputStream> stream = DeserializeInputStream(aReadStream.params(), fds); MOZ_ASSERT(stream); // Currently we expect all cache read streams to be blocking file streams. #ifdef DEBUG nsCOMPtr<nsIAsyncInputStream> asyncStream = do_QueryInterface(stream); MOZ_ASSERT(!asyncStream); #endif RefPtr<Inner> inner = new Inner(control, aReadStream.id(), stream); RefPtr<ReadStream> ref = new ReadStream(inner); return ref.forget(); }
void TypeUtils::SerializeCacheStream(nsIInputStream* aStream, CacheReadStreamOrVoid* aStreamOut, ErrorResult& aRv) { *aStreamOut = void_t(); if (!aStream) { return; } // Option 1: Send a cache-specific ReadStream if we can. nsRefPtr<ReadStream> controlled = do_QueryObject(aStream); if (controlled) { controlled->Serialize(aStreamOut); return; } CacheReadStream readStream; readStream.controlChild() = nullptr; readStream.controlParent() = nullptr; readStream.pushStreamChild() = nullptr; readStream.pushStreamParent() = nullptr; // Option 2: Do normal stream serialization if its supported. nsCOMPtr<nsIIPCSerializableInputStream> serial = do_QueryInterface(aStream); if (serial) { SerializeNormalStream(aStream, readStream); // Option 3: As a last resort push data across manually. Should only be // needed for nsPipe input stream. Only works for async, // non-blocking streams. } else { SerializePushStream(aStream, readStream, aRv); if (NS_WARN_IF(aRv.Failed())) { return; } } *aStreamOut = readStream; }