void WithSingleChunkDecode(const ImageTestCase& aTestCase, const Maybe<IntSize>& aOutputSize, Func aResultChecker) { nsCOMPtr<nsIInputStream> inputStream = LoadFile(aTestCase.mPath); ASSERT_TRUE(inputStream != nullptr); // Figure out how much data we have. uint64_t length; nsresult rv = inputStream->Available(&length); ASSERT_TRUE(NS_SUCCEEDED(rv)); // Write the data into a SourceBuffer. NotNull<RefPtr<SourceBuffer>> sourceBuffer = WrapNotNull(new SourceBuffer()); sourceBuffer->ExpectLength(length); rv = sourceBuffer->AppendFromInputStream(inputStream, length); ASSERT_TRUE(NS_SUCCEEDED(rv)); sourceBuffer->Complete(NS_OK); // Create a decoder. DecoderType decoderType = DecoderFactory::GetDecoderType(aTestCase.mMimeType); RefPtr<Decoder> decoder = DecoderFactory::CreateAnonymousDecoder(decoderType, sourceBuffer, aOutputSize, DefaultSurfaceFlags()); ASSERT_TRUE(decoder != nullptr); RefPtr<IDecodingTask> task = new AnonymousDecodingTask(WrapNotNull(decoder)); // Run the full decoder synchronously. task->Run(); // Call the lambda to verify the expected results. aResultChecker(decoder); }
/* static */ void IDecodingTask::NotifyProgress(NotNull<RasterImage*> aImage, NotNull<Decoder*> aDecoder) { MOZ_ASSERT(aDecoder->HasProgress() && !aDecoder->IsMetadataDecode()); // Capture the decoder's state. If we need to notify asynchronously, it's // important that we don't wait until the lambda actually runs to capture the // state that we're going to notify. That would both introduce data races on // the decoder's state and cause inconsistencies between the NotifyProgress() // calls we make off-main-thread and the notifications that RasterImage // actually receives, which would cause bugs. Progress progress = aDecoder->TakeProgress(); IntRect invalidRect = aDecoder->TakeInvalidRect(); Maybe<uint32_t> frameCount = aDecoder->TakeCompleteFrameCount(); SurfaceFlags surfaceFlags = aDecoder->GetSurfaceFlags(); // Synchronously notify if we can. if (NS_IsMainThread() && !(aDecoder->GetDecoderFlags() & DecoderFlags::ASYNC_NOTIFY)) { aImage->NotifyProgress(progress, invalidRect, frameCount, surfaceFlags); return; } // We're forced to notify asynchronously. NotNull<RefPtr<RasterImage>> image = aImage; NS_DispatchToMainThread(NS_NewRunnableFunction([=]() -> void { image->NotifyProgress(progress, invalidRect, frameCount, surfaceFlags); })); }
static void NotifyProgress(NotNull<Decoder*> aDecoder) { MOZ_ASSERT(aDecoder->HasProgress() && !aDecoder->IsMetadataDecode()); Progress progress = aDecoder->TakeProgress(); IntRect invalidRect = aDecoder->TakeInvalidRect(); Maybe<uint32_t> frameCount = aDecoder->TakeCompleteFrameCount(); SurfaceFlags surfaceFlags = aDecoder->GetSurfaceFlags(); // Synchronously notify if we can. if (NS_IsMainThread() && !(aDecoder->GetDecoderFlags() & DecoderFlags::ASYNC_NOTIFY)) { aDecoder->GetImage()->NotifyProgress(progress, invalidRect, frameCount, surfaceFlags); return; } // We're forced to notify asynchronously. NotNull<RefPtr<Decoder>> decoder = aDecoder; NS_DispatchToMainThread(NS_NewRunnableFunction([=]() -> void { decoder->GetImage()->NotifyProgress(progress, invalidRect, frameCount, surfaceFlags); })); }
IPCResult IPCResult::Fail(NotNull<IProtocol*> actor, const char* where, const char* why) { // Calls top-level protocol to handle the error. nsPrintfCString errorMsg("%s::%s %s\n", actor->ProtocolName(), where, why); actor->GetIPCChannel()->Listener()->ProcessingError( HasResultCodes::MsgProcessingError, errorMsg.get()); return IPCResult(false); }
void MsaaIdGenerator::ReleaseID(NotNull<AccessibleWrap*> aAccWrap) { if (!ReleaseID(aAccWrap->GetExistingID())) { // This may happen if chrome holds a proxy whose ID was originally generated // by a content process. Since ReleaseID only has meaning in the process // that originally generated that ID, we ignore ReleaseID calls for any ID // that did not come from the current process. MOZ_ASSERT(aAccWrap->IsProxy()); } }
DecodedSurfaceProvider::DecodedSurfaceProvider(NotNull<RasterImage*> aImage, const SurfaceKey& aSurfaceKey, NotNull<Decoder*> aDecoder) : ISurfaceProvider(ImageKey(aImage.get()), aSurfaceKey, AvailabilityState::StartAsPlaceholder()) , mImage(aImage.get()) , mMutex("mozilla::image::DecodedSurfaceProvider") , mDecoder(aDecoder.get()) { MOZ_ASSERT(!mDecoder->IsMetadataDecode(), "Use MetadataDecodingTask for metadata decodes"); MOZ_ASSERT(mDecoder->IsFirstFrameDecode(), "Use AnimationSurfaceProvider for animation decodes"); }
/* static */ already_AddRefed<Decoder> DecoderFactory::CreateDecoderForICOResource(DecoderType aType, SourceBufferIterator&& aIterator, NotNull<nsICODecoder*> aICODecoder, bool aIsMetadataDecode, const Maybe<IntSize>& aExpectedSize, const Maybe<uint32_t>& aDataOffset /* = Nothing() */) { // Create the decoder. RefPtr<Decoder> decoder; switch (aType) { case DecoderType::BMP: MOZ_ASSERT(aDataOffset); decoder = new nsBMPDecoder(aICODecoder->GetImageMaybeNull(), *aDataOffset); break; case DecoderType::PNG: MOZ_ASSERT(!aDataOffset); decoder = new nsPNGDecoder(aICODecoder->GetImageMaybeNull()); break; default: MOZ_ASSERT_UNREACHABLE("Invalid ICO resource decoder type"); return nullptr; } MOZ_ASSERT(decoder); // Initialize the decoder, copying settings from @aICODecoder. decoder->SetMetadataDecode(aIsMetadataDecode); decoder->SetIterator(Forward<SourceBufferIterator>(aIterator)); if (!aIsMetadataDecode) { decoder->SetOutputSize(aICODecoder->OutputSize()); } if (aExpectedSize) { decoder->SetExpectedSize(*aExpectedSize); } decoder->SetDecoderFlags(aICODecoder->GetDecoderFlags()); decoder->SetSurfaceFlags(aICODecoder->GetSurfaceFlags()); decoder->SetFinalizeFrames(false); if (NS_FAILED(decoder->Init())) { return nullptr; } return decoder.forget(); }
/* static */ already_AddRefed<IDecodingTask> DecoderFactory::CreateAnimationDecoder(DecoderType aType, NotNull<RasterImage*> aImage, NotNull<SourceBuffer*> aSourceBuffer, DecoderFlags aDecoderFlags, SurfaceFlags aSurfaceFlags) { if (aType == DecoderType::UNKNOWN) { return nullptr; } MOZ_ASSERT(aType == DecoderType::GIF || aType == DecoderType::PNG, "Calling CreateAnimationDecoder for non-animating DecoderType"); RefPtr<Decoder> decoder = GetDecoder(aType, aImage, /* aIsRedecode = */ true); MOZ_ASSERT(decoder, "Should have a decoder now"); // Initialize the decoder. decoder->SetMetadataDecode(false); decoder->SetIterator(aSourceBuffer->Iterator()); decoder->SetDecoderFlags(aDecoderFlags | DecoderFlags::IS_REDECODE); decoder->SetSurfaceFlags(aSurfaceFlags); decoder->Init(); if (NS_FAILED(decoder->GetDecoderError())) { return nullptr; } RefPtr<IDecodingTask> task = new DecodingTask(WrapNotNull(decoder)); return task.forget(); }
/* static */ already_AddRefed<IDecodingTask> DecoderFactory::CreateMetadataDecoder(DecoderType aType, NotNull<RasterImage*> aImage, NotNull<SourceBuffer*> aSourceBuffer, int aSampleSize) { if (aType == DecoderType::UNKNOWN) { return nullptr; } RefPtr<Decoder> decoder = GetDecoder(aType, aImage, /* aIsRedecode = */ false); MOZ_ASSERT(decoder, "Should have a decoder now"); // Initialize the decoder. decoder->SetMetadataDecode(true); decoder->SetIterator(aSourceBuffer->Iterator()); decoder->SetSampleSize(aSampleSize); decoder->Init(); if (NS_FAILED(decoder->GetDecoderError())) { return nullptr; } RefPtr<IDecodingTask> task = new MetadataDecodingTask(WrapNotNull(decoder)); return task.forget(); }
static void NotifyDecodeComplete(NotNull<Decoder*> aDecoder) { // Synchronously notify if we can. if (NS_IsMainThread() && !(aDecoder->GetDecoderFlags() & DecoderFlags::ASYNC_NOTIFY)) { aDecoder->GetImage()->FinalizeDecoder(aDecoder); return; } // We're forced to notify asynchronously. NotNull<RefPtr<Decoder>> decoder = aDecoder; NS_DispatchToMainThread(NS_NewRunnableFunction([=]() -> void { decoder->GetImage()->FinalizeDecoder(decoder.get()); })); }
IAccessibleHolder CreateHolderFromAccessible(NotNull<Accessible*> aAccToWrap) { MOZ_ASSERT(NS_IsMainThread()); STAUniquePtr<IAccessible> iaToProxy; aAccToWrap->GetNativeInterface(mscom::getter_AddRefs(iaToProxy)); MOZ_DIAGNOSTIC_ASSERT(iaToProxy); if (!iaToProxy) { return nullptr; } static const bool useHandler = Preferences::GetBool("accessibility.handler.enabled", false) && IsHandlerRegistered(); RefPtr<HandlerProvider> payload; if (useHandler) { payload = new HandlerProvider(IID_IAccessible, mscom::ToInterceptorTargetPtr(iaToProxy)); } ProxyUniquePtr<IAccessible> intercepted; HRESULT hr = MainThreadHandoff::WrapInterface(Move(iaToProxy), payload, (IAccessible**) mscom::getter_AddRefs(intercepted)); MOZ_ASSERT(SUCCEEDED(hr)); if (FAILED(hr)) { return nullptr; } return IAccessibleHolder(Move(intercepted)); }
void MsaaIdGenerator::ReleaseID(NotNull<sdnAccessible*> aSdnAcc) { Maybe<uint32_t> id = aSdnAcc->ReleaseUniqueID(); if (id.isSome()) { DebugOnly<bool> released = ReleaseID(id.value()); MOZ_ASSERT(released); } }
static void CheckDecoderMultiChunk(const ImageTestCase& aTestCase) { nsCOMPtr<nsIInputStream> inputStream = LoadFile(aTestCase.mPath); ASSERT_TRUE(inputStream != nullptr); // Figure out how much data we have. uint64_t length; nsresult rv = inputStream->Available(&length); ASSERT_TRUE(NS_SUCCEEDED(rv)); // Create a SourceBuffer and a decoder. NotNull<RefPtr<SourceBuffer>> sourceBuffer = WrapNotNull(new SourceBuffer()); sourceBuffer->ExpectLength(length); DecoderType decoderType = DecoderFactory::GetDecoderType(aTestCase.mMimeType); RefPtr<Decoder> decoder = DecoderFactory::CreateAnonymousDecoder(decoderType, sourceBuffer, Nothing(), DefaultSurfaceFlags()); ASSERT_TRUE(decoder != nullptr); RefPtr<IDecodingTask> task = new AnonymousDecodingTask(WrapNotNull(decoder)); for (uint64_t read = 0; read < length ; ++read) { uint64_t available = 0; rv = inputStream->Available(&available); ASSERT_TRUE(available > 0); ASSERT_TRUE(NS_SUCCEEDED(rv)); rv = sourceBuffer->AppendFromInputStream(inputStream, 1); ASSERT_TRUE(NS_SUCCEEDED(rv)); task->Run(); } sourceBuffer->Complete(NS_OK); task->Run(); CheckDecoderResults(aTestCase, decoder); }
/* static */ already_AddRefed<IDecodingTask> DecoderFactory::CreateDecoder(DecoderType aType, NotNull<RasterImage*> aImage, NotNull<SourceBuffer*> aSourceBuffer, const IntSize& aIntrinsicSize, const IntSize& aOutputSize, DecoderFlags aDecoderFlags, SurfaceFlags aSurfaceFlags) { if (aType == DecoderType::UNKNOWN) { return nullptr; } // Create an anonymous decoder. Interaction with the SurfaceCache and the // owning RasterImage will be mediated by DecodedSurfaceProvider. RefPtr<Decoder> decoder = GetDecoder(aType, nullptr, bool(aDecoderFlags & DecoderFlags::IS_REDECODE)); MOZ_ASSERT(decoder, "Should have a decoder now"); // Initialize the decoder. decoder->SetMetadataDecode(false); decoder->SetIterator(aSourceBuffer->Iterator()); decoder->SetOutputSize(aOutputSize); decoder->SetDecoderFlags(aDecoderFlags | DecoderFlags::FIRST_FRAME_ONLY); decoder->SetSurfaceFlags(aSurfaceFlags); if (NS_FAILED(decoder->Init())) { return nullptr; } // Create a DecodedSurfaceProvider which will manage the decoding process and // make this decoder's output available in the surface cache. SurfaceKey surfaceKey = RasterSurfaceKey(aOutputSize, aSurfaceFlags, PlaybackType::eStatic); auto provider = MakeNotNull<RefPtr<DecodedSurfaceProvider>>( aImage, surfaceKey, WrapNotNull(decoder)); if (aDecoderFlags & DecoderFlags::CANNOT_SUBSTITUTE) { provider->Availability().SetCannotSubstitute(); } // Attempt to insert the surface provider into the surface cache right away so // we won't trigger any more decoders with the same parameters. if (SurfaceCache::Insert(provider) != InsertOutcome::SUCCESS) { return nullptr; } // Return the surface provider in its IDecodingTask guise. RefPtr<IDecodingTask> task = provider.get(); return task.forget(); }
/* static */ already_AddRefed<IDecodingTask> DecoderFactory::CreateAnimationDecoder(DecoderType aType, NotNull<RasterImage*> aImage, NotNull<SourceBuffer*> aSourceBuffer, const IntSize& aIntrinsicSize, DecoderFlags aDecoderFlags, SurfaceFlags aSurfaceFlags) { if (aType == DecoderType::UNKNOWN) { return nullptr; } MOZ_ASSERT(aType == DecoderType::GIF || aType == DecoderType::PNG, "Calling CreateAnimationDecoder for non-animating DecoderType"); // Create an anonymous decoder. Interaction with the SurfaceCache and the // owning RasterImage will be mediated by AnimationSurfaceProvider. RefPtr<Decoder> decoder = GetDecoder(aType, nullptr, /* aIsRedecode = */ true); MOZ_ASSERT(decoder, "Should have a decoder now"); // Initialize the decoder. decoder->SetMetadataDecode(false); decoder->SetIterator(aSourceBuffer->Iterator()); decoder->SetDecoderFlags(aDecoderFlags | DecoderFlags::IS_REDECODE); decoder->SetSurfaceFlags(aSurfaceFlags); if (NS_FAILED(decoder->Init())) { return nullptr; } // Create an AnimationSurfaceProvider which will manage the decoding process // and make this decoder's output available in the surface cache. SurfaceKey surfaceKey = RasterSurfaceKey(aIntrinsicSize, aSurfaceFlags, PlaybackType::eAnimated); auto provider = MakeNotNull<RefPtr<AnimationSurfaceProvider>>( aImage, surfaceKey, WrapNotNull(decoder)); // Attempt to insert the surface provider into the surface cache right away so // we won't trigger any more decoders with the same parameters. if (SurfaceCache::Insert(provider) != InsertOutcome::SUCCESS) { return nullptr; } // Return the surface provider in its IDecodingTask guise. RefPtr<IDecodingTask> task = provider.get(); return task.forget(); }
/* static */ already_AddRefed<Decoder> DecoderFactory::CreateAnonymousDecoder(DecoderType aType, NotNull<SourceBuffer*> aSourceBuffer, const Maybe<IntSize>& aTargetSize, SurfaceFlags aSurfaceFlags) { if (aType == DecoderType::UNKNOWN) { return nullptr; } RefPtr<Decoder> decoder = GetDecoder(aType, /* aImage = */ nullptr, /* aIsRedecode = */ false); MOZ_ASSERT(decoder, "Should have a decoder now"); // Initialize the decoder. decoder->SetMetadataDecode(false); decoder->SetIterator(aSourceBuffer->Iterator()); // Anonymous decoders are always transient; we don't want to optimize surfaces // or do any other expensive work that might be wasted. DecoderFlags decoderFlags = DecoderFlags::IMAGE_IS_TRANSIENT; // Without an image, the decoder can't store anything in the SurfaceCache, so // callers will only be able to retrieve the most recent frame via // Decoder::GetCurrentFrame(). That means that anonymous decoders should // always be first-frame-only decoders, because nobody ever wants the *last* // frame. decoderFlags |= DecoderFlags::FIRST_FRAME_ONLY; decoder->SetDecoderFlags(decoderFlags); decoder->SetSurfaceFlags(aSurfaceFlags); // Set a target size for downscale-during-decode if applicable. if (aTargetSize) { DebugOnly<nsresult> rv = decoder->SetTargetSize(*aTargetSize); MOZ_ASSERT(NS_SUCCEEDED(rv), "Bad downscale-during-decode target size?"); } decoder->Init(); if (NS_FAILED(decoder->GetDecoderError())) { return nullptr; } return decoder.forget(); }
/* static */ already_AddRefed<IDecodingTask> DecoderFactory::CreateDecoder(DecoderType aType, NotNull<RasterImage*> aImage, NotNull<SourceBuffer*> aSourceBuffer, const Maybe<IntSize>& aTargetSize, DecoderFlags aDecoderFlags, SurfaceFlags aSurfaceFlags, int aSampleSize) { if (aType == DecoderType::UNKNOWN) { return nullptr; } RefPtr<Decoder> decoder = GetDecoder(aType, aImage, bool(aDecoderFlags & DecoderFlags::IS_REDECODE)); MOZ_ASSERT(decoder, "Should have a decoder now"); // Initialize the decoder. decoder->SetMetadataDecode(false); decoder->SetIterator(aSourceBuffer->Iterator()); decoder->SetDecoderFlags(aDecoderFlags | DecoderFlags::FIRST_FRAME_ONLY); decoder->SetSurfaceFlags(aSurfaceFlags); decoder->SetSampleSize(aSampleSize); // Set a target size for downscale-during-decode if applicable. if (aTargetSize) { DebugOnly<nsresult> rv = decoder->SetTargetSize(*aTargetSize); MOZ_ASSERT(NS_SUCCEEDED(rv), "Bad downscale-during-decode target size?"); } decoder->Init(); if (NS_FAILED(decoder->GetDecoderError())) { return nullptr; } RefPtr<IDecodingTask> task = new DecodingTask(WrapNotNull(decoder)); return task.forget(); }
/* static */ already_AddRefed<Decoder> DecoderFactory::CreateAnonymousMetadataDecoder(DecoderType aType, NotNull<SourceBuffer*> aSourceBuffer) { if (aType == DecoderType::UNKNOWN) { return nullptr; } RefPtr<Decoder> decoder = GetDecoder(aType, /* aImage = */ nullptr, /* aIsRedecode = */ false); MOZ_ASSERT(decoder, "Should have a decoder now"); // Initialize the decoder. decoder->SetMetadataDecode(true); decoder->SetIterator(aSourceBuffer->Iterator()); decoder->SetDecoderFlags(DecoderFlags::FIRST_FRAME_ONLY); if (NS_FAILED(decoder->Init())) { return nullptr; } return decoder.forget(); }
void nsThreadManager::Shutdown() { MOZ_ASSERT(NS_IsMainThread(), "shutdown not called from main thread"); // Prevent further access to the thread manager (no more new threads!) // // What happens if shutdown happens before NewThread completes? // We Shutdown() the new thread, and return error if we've started Shutdown // between when NewThread started, and when the thread finished initializing // and registering with ThreadManager. // mInitialized = false; // Empty the main thread event queue before we begin shutting down threads. NS_ProcessPendingEvents(mMainThread); // We gather the threads from the hashtable into a list, so that we avoid // holding the hashtable lock while calling nsIThread::Shutdown. nsThreadArray threads; { OffTheBooksMutexAutoLock lock(mLock); for (auto iter = mThreadsByPRThread.Iter(); !iter.Done(); iter.Next()) { RefPtr<nsThread>& thread = iter.Data(); threads.AppendElement(WrapNotNull(thread)); iter.Remove(); } } // It's tempting to walk the list of threads here and tell them each to stop // accepting new events, but that could lead to badness if one of those // threads is stuck waiting for a response from another thread. To do it // right, we'd need some way to interrupt the threads. // // Instead, we process events on the current thread while waiting for threads // to shutdown. This means that we have to preserve a mostly functioning // world until such time as the threads exit. // Shutdown all threads that require it (join with threads that we created). for (uint32_t i = 0; i < threads.Length(); ++i) { NotNull<nsThread*> thread = threads[i]; if (thread->ShutdownRequired()) { thread->Shutdown(); } } // NB: It's possible that there are events in the queue that want to *start* // an asynchronous shutdown. But we have already shutdown the threads above, // so there's no need to worry about them. We only have to wait for all // in-flight asynchronous thread shutdowns to complete. mMainThread->WaitForAllAsynchronousShutdowns(); // In case there are any more events somehow... NS_ProcessPendingEvents(mMainThread); // There are no more background threads at this point. // Clear the table of threads. { OffTheBooksMutexAutoLock lock(mLock); mThreadsByPRThread.Clear(); } // Normally thread shutdown clears the observer for the thread, but since the // main thread is special we do it manually here after we're sure all events // have been processed. mMainThread->SetObserver(nullptr); mMainThread->ClearObservers(); // Release main thread object. mMainThread = nullptr; // Remove the TLS entry for the main thread. PR_SetThreadPrivate(mCurThreadIndex, nullptr); }
/* static */ void IDecodingTask::NotifyProgress(NotNull<Decoder*> aDecoder) { MOZ_ASSERT(aDecoder->HasProgress() && !aDecoder->IsMetadataDecode()); // Synchronously notify if we can. if (NS_IsMainThread() && !(aDecoder->GetDecoderFlags() & DecoderFlags::ASYNC_NOTIFY)) { aDecoder->GetImage()->NotifyProgress(aDecoder->TakeProgress(), aDecoder->TakeInvalidRect(), aDecoder->GetSurfaceFlags()); return; } // We're forced to notify asynchronously. NotNull<RefPtr<Decoder>> decoder = aDecoder; NS_DispatchToMainThread(NS_NewRunnableFunction([=]() -> void { decoder->GetImage()->NotifyProgress(decoder->TakeProgress(), decoder->TakeInvalidRect(), decoder->GetSurfaceFlags()); })); }
/* static */ void IDecodingTask::NotifyDecodeComplete(NotNull<RasterImage*> aImage, NotNull<Decoder*> aDecoder) { MOZ_ASSERT(aDecoder->HasError() || !aDecoder->InFrame(), "Decode complete in the middle of a frame?"); // Capture the decoder's state. DecoderFinalStatus finalStatus = aDecoder->FinalStatus(); ImageMetadata metadata = aDecoder->GetImageMetadata(); DecoderTelemetry telemetry = aDecoder->Telemetry(); Progress progress = aDecoder->TakeProgress(); IntRect invalidRect = aDecoder->TakeInvalidRect(); Maybe<uint32_t> frameCount = aDecoder->TakeCompleteFrameCount(); SurfaceFlags surfaceFlags = aDecoder->GetSurfaceFlags(); // Synchronously notify if we can. if (NS_IsMainThread() && !(aDecoder->GetDecoderFlags() & DecoderFlags::ASYNC_NOTIFY)) { aImage->NotifyDecodeComplete(finalStatus, metadata, telemetry, progress, invalidRect, frameCount, surfaceFlags); return; } // We're forced to notify asynchronously. NotNull<RefPtr<RasterImage>> image = aImage; NS_DispatchToMainThread(NS_NewRunnableFunction([=]() -> void { image->NotifyDecodeComplete(finalStatus, metadata, telemetry, progress, invalidRect, frameCount, surfaceFlags); })); }
void TestNotNullWithMyPtr() { int i4 = 4; int i5 = 5; MyPtr<int> my4 = &i4; MyPtr<int> my5 = &i5; NotNull<int*> nni4 = WrapNotNull(&i4); NotNull<int*> nni5 = WrapNotNull(&i5); NotNull<MyPtr<int>> nnmy4 = WrapNotNull(my4); //WrapNotNull(nullptr); // no wrapping from nullptr //WrapNotNull(0); // no wrapping from zero // NotNull<int*> construction combinations //NotNull<int*> nni4a; // no default //NotNull<int*> nni4a(nullptr); // no nullptr //NotNull<int*> nni4a(0); // no zero //NotNull<int*> nni4a(&i4); // no int* //NotNull<int*> nni4a(my4); // no MyPtr<int> NotNull<int*> nni4b(WrapNotNull(&i4)); // WrapNotNull(int*) NotNull<int*> nni4c(WrapNotNull(my4)); // WrapNotNull(MyPtr<int>) NotNull<int*> nni4d(nni4); // NotNull<int*> NotNull<int*> nni4e(nnmy4); // NotNull<MyPtr<int>> CHECK(*nni4b == 4); CHECK(*nni4c == 4); CHECK(*nni4d == 4); CHECK(*nni4e == 4); // NotNull<MyPtr<int>> construction combinations //NotNull<MyPtr<int>> nnmy4a; // no default //NotNull<MyPtr<int>> nnmy4a(nullptr); // no nullptr //NotNull<MyPtr<int>> nnmy4a(0); // no zero //NotNull<MyPtr<int>> nnmy4a(&i4); // no int* //NotNull<MyPtr<int>> nnmy4a(my4); // no MyPtr<int> NotNull<MyPtr<int>> nnmy4b(WrapNotNull(&i4)); // WrapNotNull(int*) NotNull<MyPtr<int>> nnmy4c(WrapNotNull(my4)); // WrapNotNull(MyPtr<int>) NotNull<MyPtr<int>> nnmy4d(nni4); // NotNull<int*> NotNull<MyPtr<int>> nnmy4e(nnmy4); // NotNull<MyPtr<int>> CHECK(*nnmy4b == 4); CHECK(*nnmy4c == 4); CHECK(*nnmy4d == 4); CHECK(*nnmy4e == 4); // NotNull<int*> assignment combinations //nni4b = nullptr; // no nullptr //nni4b = 0; // no zero //nni4a = &i4; // no int* //nni4a = my4; // no MyPtr<int> nni4b = WrapNotNull(&i4); // WrapNotNull(int*) nni4c = WrapNotNull(my4); // WrapNotNull(MyPtr<int>) nni4d = nni4; // NotNull<int*> nni4e = nnmy4; // NotNull<MyPtr<int>> CHECK(*nni4b == 4); CHECK(*nni4c == 4); CHECK(*nni4d == 4); CHECK(*nni4e == 4); // NotNull<MyPtr<int>> assignment combinations //nnmy4a = nullptr; // no nullptr //nnmy4a = 0; // no zero //nnmy4a = &i4; // no int* //nnmy4a = my4; // no MyPtr<int> nnmy4b = WrapNotNull(&i4); // WrapNotNull(int*) nnmy4c = WrapNotNull(my4); // WrapNotNull(MyPtr<int>) nnmy4d = nni4; // NotNull<int*> nnmy4e = nnmy4; // NotNull<MyPtr<int>> CHECK(*nnmy4b == 4); CHECK(*nnmy4c == 4); CHECK(*nnmy4d == 4); CHECK(*nnmy4e == 4); NotNull<MyPtr<int>> nnmy5 = WrapNotNull(&i5); CHECK(*nnmy5 == 5); CHECK(nnmy5 == &i5); // NotNull<MyPtr<int>> == int* CHECK(nnmy5 == my5); // NotNull<MyPtr<int>> == MyPtr<int> CHECK(nnmy5 == nni5); // NotNull<MyPtr<int>> == NotNull<int*> CHECK(nnmy5 == nnmy5); // NotNull<MyPtr<int>> == NotNull<MyPtr<int>> CHECK(&i5 == nnmy5); // int* == NotNull<MyPtr<int>> CHECK(my5 == nnmy5); // MyPtr<int> == NotNull<MyPtr<int>> CHECK(nni5 == nnmy5); // NotNull<int*> == NotNull<MyPtr<int>> CHECK(nnmy5 == nnmy5); // NotNull<MyPtr<int>> == NotNull<MyPtr<int>> //CHECK(nni5 == nullptr); // no comparisons with nullptr //CHECK(nullptr == nni5); // no comparisons with nullptr //CHECK(nni5 == 0); // no comparisons with zero //CHECK(0 == nni5); // no comparisons with zero CHECK(*nnmy5 == 5); CHECK(nnmy5 != &i4); // NotNull<MyPtr<int>> != int* CHECK(nnmy5 != my4); // NotNull<MyPtr<int>> != MyPtr<int> CHECK(nnmy5 != nni4); // NotNull<MyPtr<int>> != NotNull<int*> CHECK(nnmy5 != nnmy4); // NotNull<MyPtr<int>> != NotNull<MyPtr<int>> CHECK(&i4 != nnmy5); // int* != NotNull<MyPtr<int>> CHECK(my4 != nnmy5); // MyPtr<int> != NotNull<MyPtr<int>> CHECK(nni4 != nnmy5); // NotNull<int*> != NotNull<MyPtr<int>> CHECK(nnmy4 != nnmy5); // NotNull<MyPtr<int>> != NotNull<MyPtr<int>> //CHECK(nni4 != nullptr); // no comparisons with nullptr //CHECK(nullptr != nni4); // no comparisons with nullptr //CHECK(nni4 != 0); // no comparisons with zero //CHECK(0 != nni4); // no comparisons with zero // int* parameter f_i(&i4); // identity int* --> int* f_i(my4); // implicit MyPtr<int> --> int* f_i(my4.get()); // explicit MyPtr<int> --> int* f_i(nni4); // implicit NotNull<int*> --> int* f_i(nni4.get()); // explicit NotNull<int*> --> int* //f_i(nnmy4); // no implicit NotNull<MyPtr<int>> --> int* f_i(nnmy4.get()); // explicit NotNull<MyPtr<int>> --> int* f_i(nnmy4.get().get());// doubly-explicit NotNull<MyPtr<int>> --> int* // MyPtr<int> parameter f_my(&i4); // implicit int* --> MyPtr<int> f_my(my4); // identity MyPtr<int> --> MyPtr<int> f_my(my4.get()); // explicit MyPtr<int> --> MyPtr<int> //f_my(nni4); // no implicit NotNull<int*> --> MyPtr<int> f_my(nni4.get()); // explicit NotNull<int*> --> MyPtr<int> f_my(nnmy4); // implicit NotNull<MyPtr<int>> --> MyPtr<int> f_my(nnmy4.get()); // explicit NotNull<MyPtr<int>> --> MyPtr<int> f_my(nnmy4.get().get());// doubly-explicit NotNull<MyPtr<int>> --> MyPtr<int> // NotNull<int*> parameter f_nni(nni4); // identity NotNull<int*> --> NotNull<int*> f_nni(nnmy4); // implicit NotNull<MyPtr<int>> --> NotNull<int*> // NotNull<MyPtr<int>> parameter f_nnmy(nni4); // implicit NotNull<int*> --> NotNull<MyPtr<int>> f_nnmy(nnmy4); // identity NotNull<MyPtr<int>> --> NotNull<MyPtr<int>> //CHECK(nni4); // disallow boolean conversion / unary expression usage //CHECK(nnmy4); // ditto // '->' dereferencing. Blah blah; MyPtr<Blah> myblah = &blah; NotNull<Blah*> nnblah = WrapNotNull(&blah); NotNull<MyPtr<Blah>> nnmyblah = WrapNotNull(myblah); (&blah)->blah(); // int* myblah->blah(); // MyPtr<int> nnblah->blah(); // NotNull<int*> nnmyblah->blah(); // NotNull<MyPtr<int>> (&blah)->mX = 1; CHECK((&blah)->mX == 1); myblah->mX = 2; CHECK(myblah->mX == 2); nnblah->mX = 3; CHECK(nnblah->mX == 3); nnmyblah->mX = 4; CHECK(nnmyblah->mX == 4); // '*' dereferencing (lvalues and rvalues) *(&i4) = 7; // int* CHECK(*(&i4) == 7); *my4 = 6; // MyPtr<int> CHECK(*my4 == 6); *nni4 = 5; // NotNull<int*> CHECK(*nni4 == 5); *nnmy4 = 4; // NotNull<MyPtr<int>> CHECK(*nnmy4 == 4); // Non-null arrays. static const int N = 20; int a[N]; NotNull<int*> nna = WrapNotNull(a); for (int i = 0; i < N; i++) { nna[i] = i; } for (int i = 0; i < N; i++) { nna[i] *= 2; } for (int i = 0; i < N; i++) { CHECK(nna[i] == i * 2); } }
nsresult nsNSSCertificateDB::handleCACertDownload(NotNull<nsIArray*> x509Certs, nsIInterfaceRequestor *ctx, const nsNSSShutDownPreventionLock &proofOfLock) { // First thing we have to do is figure out which certificate we're // gonna present to the user. The CA may have sent down a list of // certs which may or may not be a chained list of certs. Until // the day we can design some solid UI for the general case, we'll // code to the > 90% case. That case is where a CA sends down a // list that is a hierarchy whose root is either the first or // the last cert. What we're gonna do is compare the first // 2 entries, if the second was signed by the first, we assume // the root cert is the first cert and display it. Otherwise, // we compare the last 2 entries, if the second to last cert was // signed by the last cert, then we assume the last cert is the // root and display it. uint32_t numCerts; x509Certs->GetLength(&numCerts); NS_ASSERTION(numCerts > 0, "Didn't get any certs to import."); if (numCerts == 0) return NS_OK; // Nothing to import, so nothing to do. nsCOMPtr<nsIX509Cert> certToShow; uint32_t selCertIndex; if (numCerts == 1) { // There's only one cert, so let's show it. selCertIndex = 0; certToShow = do_QueryElementAt(x509Certs, selCertIndex); } else { nsCOMPtr<nsIX509Cert> cert0; // first cert nsCOMPtr<nsIX509Cert> cert1; // second cert nsCOMPtr<nsIX509Cert> certn_2; // second to last cert nsCOMPtr<nsIX509Cert> certn_1; // last cert cert0 = do_QueryElementAt(x509Certs, 0); cert1 = do_QueryElementAt(x509Certs, 1); certn_2 = do_QueryElementAt(x509Certs, numCerts-2); certn_1 = do_QueryElementAt(x509Certs, numCerts-1); nsXPIDLString cert0SubjectName; nsXPIDLString cert1IssuerName; nsXPIDLString certn_2IssuerName; nsXPIDLString certn_1SubjectName; cert0->GetSubjectName(cert0SubjectName); cert1->GetIssuerName(cert1IssuerName); certn_2->GetIssuerName(certn_2IssuerName); certn_1->GetSubjectName(certn_1SubjectName); if (cert1IssuerName.Equals(cert0SubjectName)) { // In this case, the first cert in the list signed the second, // so the first cert is the root. Let's display it. selCertIndex = 0; certToShow = cert0; } else if (certn_2IssuerName.Equals(certn_1SubjectName)) { // In this case the last cert has signed the second to last cert. // The last cert is the root, so let's display it. selCertIndex = numCerts-1; certToShow = certn_1; } else { // It's not a chain, so let's just show the first one in the // downloaded list. selCertIndex = 0; certToShow = cert0; } } if (!certToShow) return NS_ERROR_FAILURE; nsCOMPtr<nsICertificateDialogs> dialogs; nsresult rv = ::getNSSDialogs(getter_AddRefs(dialogs), NS_GET_IID(nsICertificateDialogs), NS_CERTIFICATEDIALOGS_CONTRACTID); if (NS_FAILED(rv)) { return rv; } UniqueCERTCertificate tmpCert(certToShow->GetCert()); if (!tmpCert) { return NS_ERROR_FAILURE; } if (!CERT_IsCACert(tmpCert.get(), nullptr)) { DisplayCertificateAlert(ctx, "NotACACert", certToShow, proofOfLock); return NS_ERROR_FAILURE; } if (tmpCert->isperm) { DisplayCertificateAlert(ctx, "CaCertExists", certToShow, proofOfLock); return NS_ERROR_FAILURE; } uint32_t trustBits; bool allows; rv = dialogs->ConfirmDownloadCACert(ctx, certToShow, &trustBits, &allows); if (NS_FAILED(rv)) return rv; if (!allows) return NS_ERROR_NOT_AVAILABLE; MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("trust is %d\n", trustBits)); UniquePORTString nickname(CERT_MakeCANickname(tmpCert.get())); MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("Created nick \"%s\"\n", nickname.get())); nsNSSCertTrust trust; trust.SetValidCA(); trust.AddCATrust(!!(trustBits & nsIX509CertDB::TRUSTED_SSL), !!(trustBits & nsIX509CertDB::TRUSTED_EMAIL), !!(trustBits & nsIX509CertDB::TRUSTED_OBJSIGN)); if (CERT_AddTempCertToPerm(tmpCert.get(), nickname.get(), trust.GetTrust()) != SECSuccess) { return NS_ERROR_FAILURE; } // Import additional delivered certificates that can be verified. // build a CertList for filtering UniqueCERTCertList certList(CERT_NewCertList()); if (!certList) { return NS_ERROR_FAILURE; } // get all remaining certs into temp store for (uint32_t i=0; i<numCerts; i++) { if (i == selCertIndex) { // we already processed that one continue; } nsCOMPtr<nsIX509Cert> remainingCert = do_QueryElementAt(x509Certs, i); if (!remainingCert) { continue; } UniqueCERTCertificate tmpCert2(remainingCert->GetCert()); if (!tmpCert2) { continue; // Let's try to import the rest of 'em } if (CERT_AddCertToListTail(certList.get(), tmpCert2.get()) != SECSuccess) { continue; } Unused << tmpCert2.release(); } return ImportValidCACertsInList(certList, ctx, proofOfLock); }
void VectorImage::CreateSurfaceAndShow(const SVGDrawingParameters& aParams) { mSVGDocumentWrapper->UpdateViewportBounds(aParams.viewportSize); mSVGDocumentWrapper->FlushImageTransformInvalidation(); RefPtr<gfxDrawingCallback> cb = new SVGDrawingCallback(mSVGDocumentWrapper, IntRect(IntPoint(0, 0), aParams.viewportSize), aParams.size, aParams.flags); RefPtr<gfxDrawable> svgDrawable = new gfxCallbackDrawable(cb, aParams.size); bool bypassCache = bool(aParams.flags & FLAG_BYPASS_SURFACE_CACHE) || // Refuse to cache animated images: // XXX(seth): We may remove this restriction in bug 922893. mHaveAnimations || // The image is too big to fit in the cache: !SurfaceCache::CanHold(aParams.size); if (bypassCache) { return Show(svgDrawable, aParams); } // We're about to rerasterize, which may mean that some of the previous // surfaces we've rasterized aren't useful anymore. We can allow them to // expire from the cache by unlocking them here, and then sending out an // invalidation. If this image is locked, any surfaces that are still useful // will become locked again when Draw touches them, and the remainder will // eventually expire. SurfaceCache::UnlockEntries(ImageKey(this)); // Try to create an imgFrame, initializing the surface it contains by drawing // our gfxDrawable into it. (We use FILTER_NEAREST since we never scale here.) NotNull<RefPtr<imgFrame>> frame = WrapNotNull(new imgFrame); nsresult rv = frame->InitWithDrawable(svgDrawable, aParams.size, SurfaceFormat::B8G8R8A8, SamplingFilter::POINT, aParams.flags); // If we couldn't create the frame, it was probably because it would end // up way too big. Generally it also wouldn't fit in the cache, but the prefs // could be set such that the cache isn't the limiting factor. if (NS_FAILED(rv)) { return Show(svgDrawable, aParams); } // Take a strong reference to the frame's surface and make sure it hasn't // already been purged by the operating system. RefPtr<SourceSurface> surface = frame->GetSourceSurface(); if (!surface) { return Show(svgDrawable, aParams); } // Attempt to cache the frame. SurfaceKey surfaceKey = VectorSurfaceKey(aParams.size, aParams.svgContext); NotNull<RefPtr<ISurfaceProvider>> provider = WrapNotNull(new SimpleSurfaceProvider(ImageKey(this), surfaceKey, frame)); SurfaceCache::Insert(provider); // Draw. RefPtr<gfxDrawable> drawable = new gfxSurfaceDrawable(surface, aParams.size); Show(drawable, aParams); // Send out an invalidation so that surfaces that are still in use get // re-locked. See the discussion of the UnlockSurfaces call above. mProgressTracker->SyncNotifyProgress(FLAG_FRAME_COMPLETE, GetMaxSizedIntRect()); }