void FTPChannelChild::DoOnDataAvailable(const nsCString& data, const PRUint32& offset, const PRUint32& count) { LOG(("FTPChannelChild::RecvOnDataAvailable [this=%x]\n", this)); if (mCanceled) return; // NOTE: the OnDataAvailable contract requires the client to read all the data // in the inputstream. This code relies on that ('data' will go away after // this function). Apparently the previous, non-e10s behavior was to actually // support only reading part of the data, allowing later calls to read the // rest. nsCOMPtr<nsIInputStream> stringStream; nsresult rv = NS_NewByteInputStream(getter_AddRefs(stringStream), data.get(), count, NS_ASSIGNMENT_DEPEND); if (NS_FAILED(rv)) { Cancel(rv); return; } AutoEventEnqueuer ensureSerialDispatch(this); rv = mListener->OnDataAvailable(this, mListenerContext, stringStream, offset, count); if (NS_FAILED(rv)) Cancel(rv); stringStream->Close(); }
void DataTransfer::FillInExternalCustomTypes(nsIVariant* aData, uint32_t aIndex, nsIPrincipal* aPrincipal) { char* chrs; uint32_t len = 0; nsresult rv = aData->GetAsStringWithSize(&len, &chrs); if (NS_FAILED(rv)) { return; } CheckedInt<int32_t> checkedLen(len); if (!checkedLen.isValid()) { return; } nsCOMPtr<nsIInputStream> stringStream; NS_NewByteInputStream(getter_AddRefs(stringStream), chrs, checkedLen.value(), NS_ASSIGNMENT_ADOPT); nsCOMPtr<nsIObjectInputStream> stream = NS_NewObjectInputStream(stringStream); uint32_t type; do { rv = stream->Read32(&type); NS_ENSURE_SUCCESS_VOID(rv); if (type == eCustomClipboardTypeId_String) { uint32_t formatLength; rv = stream->Read32(&formatLength); NS_ENSURE_SUCCESS_VOID(rv); char* formatBytes; rv = stream->ReadBytes(formatLength, &formatBytes); NS_ENSURE_SUCCESS_VOID(rv); nsAutoString format; format.Adopt(reinterpret_cast<char16_t*>(formatBytes), formatLength / sizeof(char16_t)); uint32_t dataLength; rv = stream->Read32(&dataLength); NS_ENSURE_SUCCESS_VOID(rv); char* dataBytes; rv = stream->ReadBytes(dataLength, &dataBytes); NS_ENSURE_SUCCESS_VOID(rv); nsAutoString data; data.Adopt(reinterpret_cast<char16_t*>(dataBytes), dataLength / sizeof(char16_t)); RefPtr<nsVariantCC> variant = new nsVariantCC(); rv = variant->SetAsAString(data); NS_ENSURE_SUCCESS_VOID(rv); SetDataWithPrincipal(format, variant, aIndex, aPrincipal); } } while (type != eCustomClipboardTypeId_None); }
static nsresult moz_gdk_pixbuf_to_channel(GdkPixbuf* aPixbuf, nsIURI *aURI, nsIChannel **aChannel) { int width = gdk_pixbuf_get_width(aPixbuf); int height = gdk_pixbuf_get_height(aPixbuf); NS_ENSURE_TRUE(height < 256 && width < 256 && height > 0 && width > 0 && gdk_pixbuf_get_colorspace(aPixbuf) == GDK_COLORSPACE_RGB && gdk_pixbuf_get_bits_per_sample(aPixbuf) == 8 && gdk_pixbuf_get_has_alpha(aPixbuf) && gdk_pixbuf_get_n_channels(aPixbuf) == 4, NS_ERROR_UNEXPECTED); const int n_channels = 4; gsize buf_size = 3 + n_channels * height * width; PRUint8 * const buf = (PRUint8*)NS_Alloc(buf_size); NS_ENSURE_TRUE(buf, NS_ERROR_OUT_OF_MEMORY); PRUint8 *out = buf; *(out++) = width; *(out++) = height; *(out++) = 8; // bits of alpha per pixel const guchar * const pixels = gdk_pixbuf_get_pixels(aPixbuf); int rowextra = gdk_pixbuf_get_rowstride(aPixbuf) - width * n_channels; // encode the RGB data and the A data const guchar * in = pixels; PRUint8 *alpha_out = out + height * width * 3; #ifdef DEBUG PRUint8 * const alpha_start = alpha_out; #endif for (int y = 0; y < height; ++y, in += rowextra) { for (int x = 0; x < width; ++x) { *(out++) = *(in++); // R *(out++) = *(in++); // G *(out++) = *(in++); // B *(alpha_out++) = *(in++); // A } } NS_ASSERTION(out == alpha_start && alpha_out == buf + buf_size, "size miscalculation"); nsresult rv; nsCOMPtr<nsIInputStream> stream; rv = NS_NewByteInputStream(getter_AddRefs(stream), (char*)buf, buf_size); NS_ENSURE_SUCCESS(rv, rv); nsCOMPtr<nsIStringInputStream> sstream = do_QueryInterface(stream); sstream->AdoptData((char*)buf, buf_size); // previous call was |ShareData| rv = NS_NewInputStreamChannel(aChannel, aURI, stream, NS_LITERAL_CSTRING("image/icon")); return rv; }
NS_IMETHODIMP nsJSON::Decode(const nsAString& json) { const PRUnichar *data; PRUint32 len = NS_StringGetData(json, &data); nsCOMPtr<nsIInputStream> stream; nsresult rv = NS_NewByteInputStream(getter_AddRefs(stream), (const char*) data, len * sizeof(PRUnichar), NS_ASSIGNMENT_DEPEND); NS_ENSURE_SUCCESS(rv, rv); return DecodeInternal(stream, len, PR_FALSE); }
NS_IMETHODIMP nsJSON::LegacyDecode(const nsAString& json, JSContext* cx, JS::Value* aRetval) { const PRUnichar *data; uint32_t len = NS_StringGetData(json, &data); nsCOMPtr<nsIInputStream> stream; nsresult rv = NS_NewByteInputStream(getter_AddRefs(stream), (const char*) data, len * sizeof(PRUnichar), NS_ASSIGNMENT_DEPEND); NS_ENSURE_SUCCESS(rv, rv); return DecodeInternal(cx, stream, len, false, aRetval, LEGACY); }
NS_IMETHODIMP nsSAXXMLReader::ParseFromString(const nsAString &aStr, const char *aContentType) { // Don't call this in the middle of an async parse NS_ENSURE_TRUE(!mIsAsyncParse, NS_ERROR_FAILURE); NS_ConvertUTF16toUTF8 data(aStr); // The new stream holds a reference to the buffer nsCOMPtr<nsIInputStream> stream; nsresult rv = NS_NewByteInputStream(getter_AddRefs(stream), data.get(), data.Length()); NS_ENSURE_SUCCESS(rv, rv); return ParseFromStream(stream, "UTF-8", aContentType); }
NS_IMETHODIMP nsJSON::Decode(const nsAString& json, JSContext* cx, JS::Value* aRetval) { nsresult rv = WarnDeprecatedMethod(DecodeWarning); if (NS_FAILED(rv)) return rv; const PRUnichar *data; uint32_t len = NS_StringGetData(json, &data); nsCOMPtr<nsIInputStream> stream; rv = NS_NewByteInputStream(getter_AddRefs(stream), reinterpret_cast<const char*>(data), len * sizeof(PRUnichar), NS_ASSIGNMENT_DEPEND); NS_ENSURE_SUCCESS(rv, rv); return DecodeInternal(cx, stream, len, false, aRetval); }
// static already_AddRefed<nsIInputStream> FileHandleBase::GetInputStream(const ArrayBuffer& aValue, uint64_t* aInputLength, ErrorResult& aRv) { aValue.ComputeLengthAndData(); const char* data = reinterpret_cast<const char*>(aValue.Data()); uint32_t length = aValue.Length(); nsCOMPtr<nsIInputStream> stream; aRv = NS_NewByteInputStream(getter_AddRefs(stream), data, length, NS_ASSIGNMENT_COPY); if (aRv.Failed()) { return nullptr; } *aInputLength = length; return stream.forget(); }
static nsresult GetBufferDataAsStream(const uint8_t* aData, uint32_t aDataLength, nsIInputStream** aResult, uint64_t* aContentLength, nsACString& aContentType, nsACString& aCharset) { aContentType.SetIsVoid(true); aCharset.Truncate(); *aContentLength = aDataLength; const char* data = reinterpret_cast<const char*>(aData); nsCOMPtr<nsIInputStream> stream; nsresult rv = NS_NewByteInputStream(getter_AddRefs(stream), data, aDataLength, NS_ASSIGNMENT_COPY); NS_ENSURE_SUCCESS(rv, rv); stream.forget(aResult); return NS_OK; }
static nsresult CreateBufferedStream(const uint8_t *aBuffer, uint32_t aBufLen, nsCOMPtr<nsIInputStream> &aResult) { nsCOMPtr<nsIInputStream> stream; nsresult rv = NS_NewByteInputStream(getter_AddRefs(stream), reinterpret_cast<const char *>(aBuffer), aBufLen, NS_ASSIGNMENT_DEPEND); NS_ENSURE_SUCCESS(rv, rv); nsCOMPtr<nsIInputStream> aBufferedStream; if (!NS_InputStreamIsBuffered(stream)) { rv = NS_NewBufferedInputStream(getter_AddRefs(aBufferedStream), stream, 4096); NS_ENSURE_SUCCESS(rv, rv); stream = aBufferedStream; } aResult = stream; return NS_OK; }
void WyciwygChannelChild::OnDataAvailable(const nsCString& data, const PRUint32& offset) { LOG(("WyciwygChannelChild::RecvOnDataAvailable [this=%x]\n", this)); if (mCanceled) return; mState = WCC_ONDATA; // NOTE: the OnDataAvailable contract requires the client to read all the data // in the inputstream. This code relies on that ('data' will go away after // this function). Apparently the previous, non-e10s behavior was to actually // support only reading part of the data, allowing later calls to read the // rest. nsCOMPtr<nsIInputStream> stringStream; nsresult rv = NS_NewByteInputStream(getter_AddRefs(stringStream), data.get(), data.Length(), NS_ASSIGNMENT_DEPEND); if (NS_FAILED(rv)) { Cancel(rv); return; } AutoEventEnqueuer ensureSerialDispatch(mEventQ); rv = mListener->OnDataAvailable(this, mListenerContext, stringStream, offset, data.Length()); if (NS_FAILED(rv)) Cancel(rv); if (mProgressSink && NS_SUCCEEDED(rv) && !(mLoadFlags & LOAD_BACKGROUND)) mProgressSink->OnProgress(this, nsnull, PRUint64(offset + data.Length()), PRUint64(mContentLength)); }
nsresult nsDeflateConverter::PushAvailableData(nsIRequest *aRequest, nsISupports *aContext) { uint32_t bytesToWrite = sizeof(mWriteBuffer) - mZstream.avail_out; // We don't need to do anything if there isn't any data if (bytesToWrite == 0) return NS_OK; MOZ_ASSERT(bytesToWrite <= INT32_MAX); nsCOMPtr<nsIInputStream> stream; nsresult rv = NS_NewByteInputStream(getter_AddRefs(stream), (char*)mWriteBuffer, bytesToWrite); NS_ENSURE_SUCCESS(rv, rv); rv = mListener->OnDataAvailable(aRequest, mContext, stream, mOffset, bytesToWrite); // now set the state for 'deflate' mZstream.next_out = mWriteBuffer; mZstream.avail_out = sizeof(mWriteBuffer); mOffset += bytesToWrite; return rv; }
// nsFaviconService::OptimizeFaviconImage // // Given a blob of data (a image file already read into a buffer), optimize // its size by recompressing it as a 16x16 PNG. nsresult nsFaviconService::OptimizeFaviconImage(const PRUint8* aData, PRUint32 aDataLen, const nsACString& aMimeType, nsACString& aNewData, nsACString& aNewMimeType) { nsresult rv; nsCOMPtr<imgITools> imgtool = do_CreateInstance("@mozilla.org/image/tools;1"); nsCOMPtr<nsIInputStream> stream; rv = NS_NewByteInputStream(getter_AddRefs(stream), reinterpret_cast<const char*>(aData), aDataLen, NS_ASSIGNMENT_DEPEND); NS_ENSURE_SUCCESS(rv, rv); // decode image nsCOMPtr<imgIContainer> container; rv = imgtool->DecodeImageData(stream, aMimeType, getter_AddRefs(container)); NS_ENSURE_SUCCESS(rv, rv); aNewMimeType.AssignLiteral("image/png"); // scale and recompress nsCOMPtr<nsIInputStream> iconStream; rv = imgtool->EncodeScaledImage(container, aNewMimeType, 16, 16, getter_AddRefs(iconStream)); NS_ENSURE_SUCCESS(rv, rv); // Read the stream into a new buffer. rv = NS_ConsumeStream(iconStream, PR_UINT32_MAX, aNewData); NS_ENSURE_SUCCESS(rv, rv); return NS_OK; }
NS_IMETHODIMP AsyncFaviconDataReady::OnComplete(nsIURI *aFaviconURI, uint32_t aDataLen, const uint8_t *aData, const nsACString &aMimeType) { if (!aDataLen || !aData) { if (mURLShortcut) { OnFaviconDataNotAvailable(); } return NS_OK; } nsCOMPtr<nsIFile> icoFile; nsresult rv = FaviconHelper::GetOutputIconPath(mNewURI, icoFile, mURLShortcut); NS_ENSURE_SUCCESS(rv, rv); nsAutoString path; rv = icoFile->GetPath(path); NS_ENSURE_SUCCESS(rv, rv); // Convert the obtained favicon data to an input stream nsCOMPtr<nsIInputStream> stream; rv = NS_NewByteInputStream(getter_AddRefs(stream), reinterpret_cast<const char*>(aData), aDataLen, NS_ASSIGNMENT_DEPEND); NS_ENSURE_SUCCESS(rv, rv); // Decode the image from the format it was returned to us in (probably PNG) nsAutoCString mimeTypeOfInputData; mimeTypeOfInputData.AssignLiteral("image/vnd.microsoft.icon"); nsCOMPtr<imgIContainer> container; nsCOMPtr<imgITools> imgtool = do_CreateInstance("@mozilla.org/image/tools;1"); rv = imgtool->DecodeImageData(stream, aMimeType, getter_AddRefs(container)); NS_ENSURE_SUCCESS(rv, rv); nsRefPtr<gfxASurface> imgFrame = container->GetFrame(imgIContainer::FRAME_FIRST, 0); NS_ENSURE_TRUE(imgFrame, NS_ERROR_FAILURE); nsRefPtr<gfxImageSurface> imageSurface; gfxIntSize size; if (mURLShortcut) { imageSurface = new gfxImageSurface(gfxIntSize(48, 48), gfxImageFormat::ARGB32); gfxContext context(imageSurface); context.SetOperator(gfxContext::OPERATOR_SOURCE); context.SetColor(gfxRGBA(1, 1, 1, 1)); context.Rectangle(gfxRect(0, 0, 48, 48)); context.Fill(); context.Translate(gfxPoint(16, 16)); context.SetOperator(gfxContext::OPERATOR_OVER); context.DrawSurface(imgFrame, gfxSize(16, 16)); size = imageSurface->GetSize(); } else { imageSurface = imgFrame->GetAsReadableARGB32ImageSurface(); size.width = GetSystemMetrics(SM_CXSMICON); size.height = GetSystemMetrics(SM_CYSMICON); if (!size.width || !size.height) { size.width = 16; size.height = 16; } } // Allocate a new buffer that we own and can use out of line in // another thread. Copy the favicon raw data into it. const fallible_t fallible = fallible_t(); uint8_t *data = new (fallible) uint8_t[imageSurface->GetDataSize()]; if (!data) { return NS_ERROR_OUT_OF_MEMORY; } memcpy(data, imageSurface->Data(), imageSurface->GetDataSize()); // AsyncEncodeAndWriteIcon takes ownership of the heap allocated buffer nsCOMPtr<nsIRunnable> event = new AsyncEncodeAndWriteIcon(path, data, imageSurface->GetDataSize(), imageSurface->Stride(), size.width, size.height, mURLShortcut); mIOThread->Dispatch(event, NS_DISPATCH_NORMAL); return NS_OK; }
nsresult imgContainer::ReloadImages(void) { NS_ASSERTION(!mRestoreData.IsEmpty(), "imgContainer::ReloadImages(): mRestoreData should not be empty"); NS_ASSERTION(mRestoreDataDone, "imgContainer::ReloadImages(): mRestoreDataDone shoudl be true!"); mNumFrames = 0; NS_ASSERTION(mFrames.Count() == 0, "imgContainer::ReloadImages(): mFrames should be empty"); nsCAutoString decoderCID(NS_LITERAL_CSTRING("@mozilla.org/image/decoder;2?type=") + mDiscardableMimeType); nsCOMPtr<imgIDecoder> decoder = do_CreateInstance(decoderCID.get()); if (!decoder) { PR_LOG(gCompressedImageAccountingLog, PR_LOG_WARNING, ("CompressedImageAccounting: imgContainer::ReloadImages() could not create decoder for %s", mDiscardableMimeType.get())); return NS_IMAGELIB_ERROR_NO_DECODER; } nsCOMPtr<imgILoad> loader = new ContainerLoader(); if (!loader) { PR_LOG(gCompressedImageAccountingLog, PR_LOG_WARNING, ("CompressedImageAccounting: imgContainer::ReloadImages() could not allocate ContainerLoader " "when reloading the images for container %p", this)); return NS_ERROR_OUT_OF_MEMORY; } loader->SetImage(this); nsresult result = decoder->Init(loader); if (NS_FAILED(result)) { PR_LOG(gCompressedImageAccountingLog, PR_LOG_WARNING, ("CompressedImageAccounting: imgContainer::ReloadImages() image container %p " "failed to initialize the decoder (%s)", this, mDiscardableMimeType.get())); return result; } nsCOMPtr<nsIInputStream> stream; result = NS_NewByteInputStream(getter_AddRefs(stream), mRestoreData.Elements(), mRestoreData.Length(), NS_ASSIGNMENT_DEPEND); NS_ENSURE_SUCCESS(result, result); if (PR_LOG_TEST(gCompressedImageAccountingLog, PR_LOG_DEBUG)) { char buf[9]; get_header_str(buf, mRestoreData.Elements(), mRestoreData.Length()); PR_LOG(gCompressedImageAccountingLog, PR_LOG_WARNING, ("CompressedImageAccounting: imgContainer::ReloadImages() starting to restore images for container %p (%s) - " "header %p is 0x%s (length %d)", this, mDiscardableMimeType.get(), mRestoreData.Elements(), buf, mRestoreData.Length())); } PRUint32 written; result = decoder->WriteFrom(stream, mRestoreData.Length(), &written); NS_ENSURE_SUCCESS(result, result); result = decoder->Flush(); NS_ENSURE_SUCCESS(result, result); result = decoder->Close(); NS_ENSURE_SUCCESS(result, result); NS_ASSERTION(mFrames.Count() == mNumFrames, "imgContainer::ReloadImages(): the restored mFrames.Count() doesn't match mNumFrames!"); return result; }
NS_IMETHODIMP AsyncWriteIconToDisk::Run() { NS_PRECONDITION(!NS_IsMainThread(), "Should not be called on the main thread."); // Convert the obtained favicon data to an input stream nsCOMPtr<nsIInputStream> stream; nsresult rv = NS_NewByteInputStream(getter_AddRefs(stream), reinterpret_cast<const char*>(mBuffer.get()), mBufferLength, NS_ASSIGNMENT_DEPEND); NS_ENSURE_SUCCESS(rv, rv); // Decode the image from the format it was returned to us in (probably PNG) nsCOMPtr<imgIContainer> container; nsCOMPtr<imgITools> imgtool = do_CreateInstance("@mozilla.org/image/tools;1"); rv = imgtool->DecodeImageData(stream, mMimeTypeOfInputData, getter_AddRefs(container)); NS_ENSURE_SUCCESS(rv, rv); // Get the recommended icon width and height, or if failure to obtain // these settings, fall back to 16x16 ICOs. These values can be different // if the user has a different DPI setting other than 100%. // Windows would scale the 16x16 icon themselves, but it's better // we let our ICO encoder do it. PRInt32 systemIconWidth = GetSystemMetrics(SM_CXSMICON); PRInt32 systemIconHeight = GetSystemMetrics(SM_CYSMICON); if (systemIconWidth == 0 || systemIconHeight == 0) { systemIconWidth = 16; systemIconHeight = 16; } // Scale the image to the needed size and in ICO format mMimeTypeOfInputData.AssignLiteral("image/vnd.microsoft.icon"); nsCOMPtr<nsIInputStream> iconStream; rv = imgtool->EncodeScaledImage(container, mMimeTypeOfInputData, systemIconWidth, systemIconHeight, EmptyString(), getter_AddRefs(iconStream)); NS_ENSURE_SUCCESS(rv, rv); nsCOMPtr<nsILocalFile> icoFile = do_CreateInstance("@mozilla.org/file/local;1"); NS_ENSURE_TRUE(icoFile, NS_ERROR_FAILURE); rv = icoFile->InitWithPath(mIconPath); // Setup the output stream for the ICO file on disk nsCOMPtr<nsIOutputStream> outputStream; rv = NS_NewLocalFileOutputStream(getter_AddRefs(outputStream), icoFile); NS_ENSURE_SUCCESS(rv, rv); // Obtain the ICO buffer size from the re-encoded ICO stream PRUint32 bufSize; rv = iconStream->Available(&bufSize); NS_ENSURE_SUCCESS(rv, rv); // Setup a buffered output stream from the stream object // so that we can simply use WriteFrom with the stream object nsCOMPtr<nsIOutputStream> bufferedOutputStream; rv = NS_NewBufferedOutputStream(getter_AddRefs(bufferedOutputStream), outputStream, bufSize); NS_ENSURE_SUCCESS(rv, rv); // Write out the icon stream to disk and make sure we wrote everything PRUint32 wrote; rv = bufferedOutputStream->WriteFrom(iconStream, bufSize, &wrote); NS_ASSERTION(bufSize == wrote, "Icon wrote size should be equal to requested write size"); // Cleanup bufferedOutputStream->Close(); outputStream->Close(); return rv; }
NS_IMETHODIMP AsyncWriteIconToDisk::Run() { NS_PRECONDITION(!NS_IsMainThread(), "Should not be called on the main thread."); // Convert the obtained favicon data to an input stream nsCOMPtr<nsIInputStream> stream; nsresult rv = NS_NewByteInputStream(getter_AddRefs(stream), reinterpret_cast<const char*>(mBuffer.get()), mBufferLength, NS_ASSIGNMENT_DEPEND); NS_ENSURE_SUCCESS(rv, rv); // Decode the image from the format it was returned to us in (probably PNG) nsCOMPtr<imgIContainer> container; nsCOMPtr<imgITools> imgtool = do_CreateInstance("@mozilla.org/image/tools;1"); rv = imgtool->DecodeImageData(stream, mMimeTypeOfInputData, getter_AddRefs(container)); NS_ENSURE_SUCCESS(rv, rv); // Get the recommended icon width and height, or if failure to obtain // these settings, fall back to 16x16 ICOs. These values can be different // if the user has a different DPI setting other than 100%. // Windows would scale the 16x16 icon themselves, but it's better // we let our ICO encoder do it. nsCOMPtr<nsIInputStream> iconStream; if (!mURLShortcut) { int32_t systemIconWidth = GetSystemMetrics(SM_CXSMICON); int32_t systemIconHeight = GetSystemMetrics(SM_CYSMICON); if ((systemIconWidth == 0 || systemIconHeight == 0)) { systemIconWidth = 16; systemIconHeight = 16; } // Scale the image to the needed size and in ICO format mMimeTypeOfInputData.AssignLiteral("image/vnd.microsoft.icon"); rv = imgtool->EncodeScaledImage(container, mMimeTypeOfInputData, systemIconWidth, systemIconHeight, EmptyString(), getter_AddRefs(iconStream)); } else { nsRefPtr<gfxASurface> s; rv = container->GetFrame(imgIContainer::FRAME_FIRST, 0, getter_AddRefs(s)); NS_ENSURE_SUCCESS(rv, rv); gfxImageSurface* surface = new gfxImageSurface(gfxIntSize(48, 48), gfxImageSurface::ImageFormatARGB32); gfxContext context(surface); context.SetOperator(gfxContext::OPERATOR_SOURCE); context.SetColor(gfxRGBA(1, 1, 1, 1)); context.Rectangle(gfxRect(0, 0, 48, 48)); context.Fill(); context.Translate(gfxPoint(16, 16)); context.SetOperator(gfxContext::OPERATOR_OVER); context.DrawSurface(s, gfxSize(16, 16)); gfxIntSize size = surface->GetSize(); nsRefPtr<imgIEncoder> encoder = do_CreateInstance("@mozilla.org/image/encoder;2?" "type=image/vnd.microsoft.icon"); NS_ENSURE_TRUE(encoder, NS_ERROR_FAILURE); rv = encoder->InitFromData(surface->Data(), surface->Stride() * size.height, size.width, size.height, surface->Stride(), imgIEncoder::INPUT_FORMAT_HOSTARGB, EmptyString()); NS_ENSURE_SUCCESS(rv, rv); CallQueryInterface(encoder.get(), getter_AddRefs(iconStream)); if (!iconStream) { return NS_ERROR_FAILURE; } } NS_ENSURE_SUCCESS(rv, rv); nsCOMPtr<nsIFile> icoFile = do_CreateInstance("@mozilla.org/file/local;1"); NS_ENSURE_TRUE(icoFile, NS_ERROR_FAILURE); rv = icoFile->InitWithPath(mIconPath); // Setup the output stream for the ICO file on disk nsCOMPtr<nsIOutputStream> outputStream; rv = NS_NewLocalFileOutputStream(getter_AddRefs(outputStream), icoFile); NS_ENSURE_SUCCESS(rv, rv); // Obtain the ICO buffer size from the re-encoded ICO stream uint64_t bufSize64; rv = iconStream->Available(&bufSize64); NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_TRUE(bufSize64 <= UINT32_MAX, NS_ERROR_FILE_TOO_BIG); uint32_t bufSize = (uint32_t)bufSize64; // Setup a buffered output stream from the stream object // so that we can simply use WriteFrom with the stream object nsCOMPtr<nsIOutputStream> bufferedOutputStream; rv = NS_NewBufferedOutputStream(getter_AddRefs(bufferedOutputStream), outputStream, bufSize); NS_ENSURE_SUCCESS(rv, rv); // Write out the icon stream to disk and make sure we wrote everything uint32_t wrote; rv = bufferedOutputStream->WriteFrom(iconStream, bufSize, &wrote); NS_ASSERTION(bufSize == wrote, "Icon wrote size should be equal to requested write size"); // Cleanup bufferedOutputStream->Close(); outputStream->Close(); if (mURLShortcut) { SendMessage(HWND_BROADCAST, WM_SETTINGCHANGE, SPI_SETNONCLIENTMETRICS, 0); } return rv; }
already_AddRefed<Promise> Request::ConsumeBody(ConsumeType aType, ErrorResult& aRv) { nsRefPtr<Promise> promise = Promise::Create(mOwner, aRv); if (aRv.Failed()) { return nullptr; } if (BodyUsed()) { aRv.ThrowTypeError(MSG_REQUEST_BODY_CONSUMED_ERROR); return nullptr; } SetBodyUsed(); // While the spec says to do this asynchronously, all the body constructors // right now only accept bodies whose streams are backed by an in-memory // buffer that can be read without blocking. So I think this is fine. nsCOMPtr<nsIInputStream> stream; mRequest->GetBody(getter_AddRefs(stream)); if (!stream) { aRv = NS_NewByteInputStream(getter_AddRefs(stream), "", 0, NS_ASSIGNMENT_COPY); if (aRv.Failed()) { return nullptr; } } AutoJSAPI api; api.Init(mOwner); JSContext* cx = api.cx(); // We can make this assertion because for now we only support memory backed // structures for the body argument for a Request. MOZ_ASSERT(NS_InputStreamIsBuffered(stream)); nsCString buffer; uint64_t len; aRv = stream->Available(&len); if (aRv.Failed()) { return nullptr; } aRv = NS_ReadInputStreamToString(stream, buffer, len); if (aRv.Failed()) { return nullptr; } buffer.SetLength(len); switch (aType) { case CONSUME_ARRAYBUFFER: { JS::Rooted<JSObject*> arrayBuffer(cx); arrayBuffer = ArrayBuffer::Create(cx, buffer.Length(), reinterpret_cast<const uint8_t*>(buffer.get())); JS::Rooted<JS::Value> val(cx); val.setObjectOrNull(arrayBuffer); promise->MaybeResolve(cx, val); return promise.forget(); } case CONSUME_BLOB: { // XXXnsm it is actually possible to avoid these duplicate allocations // for the Blob case by having the Blob adopt the stream's memory // directly, but I've not added a special case for now. // // This is similar to nsContentUtils::CreateBlobBuffer, but also deals // with worker wrapping. uint32_t blobLen = buffer.Length(); void* blobData = moz_malloc(blobLen); nsRefPtr<File> blob; if (blobData) { memcpy(blobData, buffer.BeginReading(), blobLen); blob = File::CreateMemoryFile(GetParentObject(), blobData, blobLen, NS_ConvertUTF8toUTF16(mMimeType)); } else { aRv = NS_ERROR_OUT_OF_MEMORY; return nullptr; } promise->MaybeResolve(blob); return promise.forget(); } case CONSUME_JSON: { nsString decoded; aRv = DecodeUTF8(buffer, decoded); if (aRv.Failed()) { return nullptr; } JS::Rooted<JS::Value> json(cx); if (!JS_ParseJSON(cx, decoded.get(), decoded.Length(), &json)) { JS::Rooted<JS::Value> exn(cx); if (JS_GetPendingException(cx, &exn)) { JS_ClearPendingException(cx); promise->MaybeReject(cx, exn); } } promise->MaybeResolve(cx, json); return promise.forget(); } case CONSUME_TEXT: { nsString decoded; aRv = DecodeUTF8(buffer, decoded); if (aRv.Failed()) { return nullptr; } promise->MaybeResolve(decoded); return promise.forget(); } } NS_NOTREACHED("Unexpected consume body type"); // Silence warnings. return nullptr; }
nsresult nsHttpTransaction::Init(PRUint8 caps, nsHttpConnectionInfo *cinfo, nsHttpRequestHead *requestHead, nsIInputStream *requestBody, PRBool requestBodyHasHeaders, nsIEventTarget *target, nsIInterfaceRequestor *callbacks, nsITransportEventSink *eventsink, nsIAsyncInputStream **responseBody) { nsresult rv; LOG(("nsHttpTransaction::Init [this=%x caps=%x]\n", this, caps)); NS_ASSERTION(cinfo, "ouch"); NS_ASSERTION(requestHead, "ouch"); NS_ASSERTION(target, "ouch"); // create transport event sink proxy that coalesces all events rv = net_NewTransportEventSinkProxy(getter_AddRefs(mTransportSink), eventsink, target, PR_TRUE); if (NS_FAILED(rv)) return rv; // try to get the nsIHttpActivityObserver distributor mActivityDistributor = do_GetService(NS_HTTPACTIVITYDISTRIBUTOR_CONTRACTID, &rv); // mActivityDistributor may not be valid if (NS_SUCCEEDED(rv) && mActivityDistributor) { // the service is valid, now check if it is active PRBool active; rv = mActivityDistributor->GetIsActive(&active); if (NS_SUCCEEDED(rv) && active) { // the service is valid and active, gather nsISupports // for the channel that called Init() mChannel = do_QueryInterface(eventsink); LOG(("nsHttpTransaction::Init() " \ "mActivityDistributor is active " \ "this=%x", this)); } else // the interface in valid but not active, so don't use it mActivityDistributor = nsnull; } NS_ADDREF(mConnInfo = cinfo); mCallbacks = callbacks; mConsumerTarget = target; mCaps = caps; if (requestHead->Method() == nsHttp::Head) mNoContent = PR_TRUE; // grab a weak reference to the request head mRequestHead = requestHead; // make sure we eliminate any proxy specific headers from // the request if we are talking HTTPS via a SSL tunnel. PRBool pruneProxyHeaders = cinfo->UsingSSL() && cinfo->UsingHttpProxy(); mReqHeaderBuf.Truncate(); requestHead->Flatten(mReqHeaderBuf, pruneProxyHeaders); #if defined(PR_LOGGING) if (LOG3_ENABLED()) { LOG3(("http request [\n")); LogHeaders(mReqHeaderBuf.get()); LOG3(("]\n")); } #endif // If the request body does not include headers or if there is no request // body, then we must add the header/body separator manually. if (!requestBodyHasHeaders || !requestBody) mReqHeaderBuf.AppendLiteral("\r\n"); // report the request header if (mActivityDistributor) mActivityDistributor->ObserveActivity( mChannel, NS_HTTP_ACTIVITY_TYPE_HTTP_TRANSACTION, NS_HTTP_ACTIVITY_SUBTYPE_REQUEST_HEADER, LL_ZERO, LL_ZERO, mReqHeaderBuf); // Create a string stream for the request header buf (the stream holds // a non-owning reference to the request header data, so we MUST keep // mReqHeaderBuf around). nsCOMPtr<nsIInputStream> headers; rv = NS_NewByteInputStream(getter_AddRefs(headers), mReqHeaderBuf.get(), mReqHeaderBuf.Length()); if (NS_FAILED(rv)) return rv; if (requestBody) { mHasRequestBody = PR_TRUE; // wrap the headers and request body in a multiplexed input stream. nsCOMPtr<nsIMultiplexInputStream> multi = do_CreateInstance(kMultiplexInputStream, &rv); if (NS_FAILED(rv)) return rv; rv = multi->AppendStream(headers); if (NS_FAILED(rv)) return rv; rv = multi->AppendStream(requestBody); if (NS_FAILED(rv)) return rv; // wrap the multiplexed input stream with a buffered input stream, so // that we write data in the largest chunks possible. this is actually // necessary to workaround some common server bugs (see bug 137155). rv = NS_NewBufferedInputStream(getter_AddRefs(mRequestStream), multi, NET_DEFAULT_SEGMENT_SIZE); if (NS_FAILED(rv)) return rv; } else mRequestStream = headers; rv = mRequestStream->Available(&mRequestSize); if (NS_FAILED(rv)) return rv; // create pipe for response stream rv = NS_NewPipe2(getter_AddRefs(mPipeIn), getter_AddRefs(mPipeOut), PR_TRUE, PR_TRUE, NS_HTTP_SEGMENT_SIZE, NS_HTTP_SEGMENT_COUNT, nsIOService::gBufferCache); if (NS_FAILED(rv)) return rv; NS_ADDREF(*responseBody = mPipeIn); return NS_OK; }
NS_IMETHODIMP nsClipboard::GetData(nsITransferable *aTransferable, PRInt32 aWhichClipboard) { if (!aTransferable) return NS_ERROR_FAILURE; GtkClipboard *clipboard; clipboard = gtk_clipboard_get(GetSelectionAtom(aWhichClipboard)); guchar *data = NULL; gint length = 0; PRBool foundData = PR_FALSE; nsCAutoString foundFlavor; // Get a list of flavors this transferable can import nsCOMPtr<nsISupportsArray> flavors; nsresult rv; rv = aTransferable->FlavorsTransferableCanImport(getter_AddRefs(flavors)); if (!flavors || NS_FAILED(rv)) return NS_ERROR_FAILURE; PRUint32 count; flavors->Count(&count); for (PRUint32 i=0; i < count; i++) { nsCOMPtr<nsISupports> genericFlavor; flavors->GetElementAt(i, getter_AddRefs(genericFlavor)); nsCOMPtr<nsISupportsCString> currentFlavor; currentFlavor = do_QueryInterface(genericFlavor); if (currentFlavor) { nsXPIDLCString flavorStr; currentFlavor->ToString(getter_Copies(flavorStr)); // Special case text/unicode since we can convert any // string into text/unicode if (!strcmp(flavorStr, kUnicodeMime)) { gchar* new_text = wait_for_text(clipboard); if (new_text) { // Convert utf-8 into our unicode format. NS_ConvertUTF8toUTF16 ucs2string(new_text); data = (guchar *)ToNewUnicode(ucs2string); length = ucs2string.Length() * 2; g_free(new_text); foundData = PR_TRUE; foundFlavor = kUnicodeMime; break; } // If the type was text/unicode and we couldn't get // text off the clipboard, run the next loop // iteration. continue; } // For images, we must wrap the data in an nsIInputStream then return instead of break, // because that code below won't help us. if (!strcmp(flavorStr, kJPEGImageMime) || !strcmp(flavorStr, kPNGImageMime) || !strcmp(flavorStr, kGIFImageMime)) { GdkAtom atom; if (!strcmp(flavorStr, kJPEGImageMime)) // This is image/jpg, but X only understands image/jpeg atom = gdk_atom_intern("image/jpeg", FALSE); else atom = gdk_atom_intern(flavorStr, FALSE); GtkSelectionData *selectionData = wait_for_contents(clipboard, atom); if (!selectionData) continue; nsCOMPtr<nsIInputStream> byteStream; NS_NewByteInputStream(getter_AddRefs(byteStream), (const char*)selectionData->data, selectionData->length, NS_ASSIGNMENT_COPY); aTransferable->SetTransferData(flavorStr, byteStream, sizeof(nsIInputStream*)); gtk_selection_data_free(selectionData); return NS_OK; } // Get the atom for this type and try to request it off // the clipboard. GdkAtom atom = gdk_atom_intern(flavorStr, FALSE); GtkSelectionData *selectionData; selectionData = wait_for_contents(clipboard, atom); if (selectionData) { length = selectionData->length; // Special case text/html since we can convert into UCS2 if (!strcmp(flavorStr, kHTMLMime)) { PRUnichar* htmlBody= nsnull; PRInt32 htmlBodyLen = 0; // Convert text/html into our unicode format ConvertHTMLtoUCS2((guchar *)selectionData->data, length, &htmlBody, htmlBodyLen); // Try next data format? if (!htmlBodyLen) continue; data = (guchar *)htmlBody; length = htmlBodyLen * 2; } else { data = (guchar *)nsMemory::Alloc(length); if (!data) break; memcpy(data, selectionData->data, length); } foundData = PR_TRUE; foundFlavor = flavorStr; break; } } } if (foundData) { nsCOMPtr<nsISupports> wrapper; nsPrimitiveHelpers::CreatePrimitiveForData(foundFlavor.get(), data, length, getter_AddRefs(wrapper)); aTransferable->SetTransferData(foundFlavor.get(), wrapper, length); } if (data) nsMemory::Free(data); return NS_OK; }
nsresult nsHttpTransaction::Init(PRUint8 caps, nsHttpConnectionInfo *cinfo, nsHttpRequestHead *requestHead, nsIInputStream *requestBody, PRBool requestBodyHasHeaders, nsIEventTarget *target, nsIInterfaceRequestor *callbacks, nsITransportEventSink *eventsink, nsIAsyncInputStream **responseBody) { nsresult rv; LOG(("nsHttpTransaction::Init [this=%x caps=%x]\n", this, caps)); NS_ASSERTION(cinfo, "ouch"); NS_ASSERTION(requestHead, "ouch"); NS_ASSERTION(target, "ouch"); // create transport event sink proxy that coalesces all events rv = net_NewTransportEventSinkProxy(getter_AddRefs(mTransportSink), eventsink, target, PR_TRUE); if (NS_FAILED(rv)) return rv; mActivityDistributor = do_GetService(NS_HTTPACTIVITYDISTRIBUTOR_CONTRACTID, &rv); if (NS_FAILED(rv)) return rv; PRBool active; rv = mActivityDistributor->GetIsActive(&active); if (NS_SUCCEEDED(rv) && active) { // there are some observers registered at activity distributor, gather // nsISupports for the channel that called Init() mChannel = do_QueryInterface(eventsink); LOG(("nsHttpTransaction::Init() " \ "mActivityDistributor is active " \ "this=%x", this)); } else // there is no observer, so don't use it mActivityDistributor = nsnull; NS_ADDREF(mConnInfo = cinfo); mCallbacks = callbacks; mConsumerTarget = target; mCaps = caps; if (requestHead->Method() == nsHttp::Head) mNoContent = PR_TRUE; // Make sure that there is "Content-Length: 0" header in the requestHead // in case of POST and PUT methods when there is no requestBody and // requestHead doesn't contain "Transfer-Encoding" header. // // RFC1945 section 7.2.2: // HTTP/1.0 requests containing an entity body must include a valid // Content-Length header field. // // RFC2616 section 4.4: // For compatibility with HTTP/1.0 applications, HTTP/1.1 requests // containing a message-body MUST include a valid Content-Length header // field unless the server is known to be HTTP/1.1 compliant. if ((requestHead->Method() == nsHttp::Post || requestHead->Method() == nsHttp::Put) && !requestBody && !requestHead->PeekHeader(nsHttp::Transfer_Encoding)) { requestHead->SetHeader(nsHttp::Content_Length, NS_LITERAL_CSTRING("0")); } // grab a weak reference to the request head mRequestHead = requestHead; // make sure we eliminate any proxy specific headers from // the request if we are talking HTTPS via a SSL tunnel. PRBool pruneProxyHeaders = cinfo->UsingSSL() && cinfo->UsingHttpProxy(); mReqHeaderBuf.Truncate(); requestHead->Flatten(mReqHeaderBuf, pruneProxyHeaders); #if defined(PR_LOGGING) if (LOG3_ENABLED()) { LOG3(("http request [\n")); LogHeaders(mReqHeaderBuf.get()); LOG3(("]\n")); } #endif // If the request body does not include headers or if there is no request // body, then we must add the header/body separator manually. if (!requestBodyHasHeaders || !requestBody) mReqHeaderBuf.AppendLiteral("\r\n"); // report the request header if (mActivityDistributor) mActivityDistributor->ObserveActivity( mChannel, NS_HTTP_ACTIVITY_TYPE_HTTP_TRANSACTION, NS_HTTP_ACTIVITY_SUBTYPE_REQUEST_HEADER, PR_Now(), LL_ZERO, mReqHeaderBuf); // Create a string stream for the request header buf (the stream holds // a non-owning reference to the request header data, so we MUST keep // mReqHeaderBuf around). nsCOMPtr<nsIInputStream> headers; rv = NS_NewByteInputStream(getter_AddRefs(headers), mReqHeaderBuf.get(), mReqHeaderBuf.Length()); if (NS_FAILED(rv)) return rv; if (requestBody) { mHasRequestBody = PR_TRUE; // wrap the headers and request body in a multiplexed input stream. nsCOMPtr<nsIMultiplexInputStream> multi = do_CreateInstance(kMultiplexInputStream, &rv); if (NS_FAILED(rv)) return rv; rv = multi->AppendStream(headers); if (NS_FAILED(rv)) return rv; rv = multi->AppendStream(requestBody); if (NS_FAILED(rv)) return rv; // wrap the multiplexed input stream with a buffered input stream, so // that we write data in the largest chunks possible. this is actually // necessary to workaround some common server bugs (see bug 137155). rv = NS_NewBufferedInputStream(getter_AddRefs(mRequestStream), multi, nsIOService::gDefaultSegmentSize); if (NS_FAILED(rv)) return rv; } else mRequestStream = headers; rv = mRequestStream->Available(&mRequestSize); if (NS_FAILED(rv)) return rv; // create pipe for response stream rv = NS_NewPipe2(getter_AddRefs(mPipeIn), getter_AddRefs(mPipeOut), PR_TRUE, PR_TRUE, nsIOService::gDefaultSegmentSize, nsIOService::gDefaultSegmentCount, nsIOService::gBufferCache); if (NS_FAILED(rv)) return rv; NS_ADDREF(*responseBody = mPipeIn); return NS_OK; }
void HttpChannelChild::OnTransportAndData(const nsresult& status, const PRUint64 progress, const PRUint64& progressMax, const nsCString& data, const PRUint32& offset, const PRUint32& count) { LOG(("HttpChannelChild::OnTransportAndData [this=%x]\n", this)); if (mCanceled) return; // cache the progress sink so we don't have to query for it each time. if (!mProgressSink) GetCallback(mProgressSink); // Hold queue lock throughout all three calls, else we might process a later // necko msg in between them. AutoEventEnqueuer ensureSerialDispatch(mEventQ); // block status/progress after Cancel or OnStopRequest has been called, // or if channel has LOAD_BACKGROUND set. // - JDUELL: may not need mStatus/mIsPending checks, given this is always called // during OnDataAvailable, and we've already checked mCanceled. Code // dupe'd from nsHttpChannel if (mProgressSink && NS_SUCCEEDED(mStatus) && mIsPending && !(mLoadFlags & LOAD_BACKGROUND)) { // OnStatus // NS_ASSERTION(status == nsISocketTransport::STATUS_RECEIVING_FROM || status == nsITransport::STATUS_READING, "unexpected status code"); nsCAutoString host; mURI->GetHost(host); mProgressSink->OnStatus(this, nsnull, status, NS_ConvertUTF8toUTF16(host).get()); // OnProgress // if (progress > 0) { NS_ASSERTION(progress <= progressMax, "unexpected progress values"); mProgressSink->OnProgress(this, nsnull, progress, progressMax); } } // OnDataAvailable // // NOTE: the OnDataAvailable contract requires the client to read all the data // in the inputstream. This code relies on that ('data' will go away after // this function). Apparently the previous, non-e10s behavior was to actually // support only reading part of the data, allowing later calls to read the // rest. nsCOMPtr<nsIInputStream> stringStream; nsresult rv = NS_NewByteInputStream(getter_AddRefs(stringStream), data.get(), count, NS_ASSIGNMENT_DEPEND); if (NS_FAILED(rv)) { Cancel(rv); return; } rv = mListener->OnDataAvailable(this, mListenerContext, stringStream, offset, count); stringStream->Close(); if (NS_FAILED(rv)) { Cancel(rv); } }