nsresult nsHttpPipeline::FillSendBuf() { // reads from request queue, moving transactions to response queue // when they have been completely read. nsresult rv; if (!mSendBufIn) { // allocate a single-segment pipe rv = NS_NewPipe(getter_AddRefs(mSendBufIn), getter_AddRefs(mSendBufOut), nsIOService::gDefaultSegmentSize, /* segment size */ nsIOService::gDefaultSegmentSize, /* max size */ true, true); if (NS_FAILED(rv)) return rv; } PRUint32 n; PRUint64 avail; nsAHttpTransaction *trans; nsITransport *transport = Transport(); while ((trans = Request(0)) != nullptr) { avail = trans->Available(); if (avail) { // if there is already a response in the responseq then this // new data comprises a pipeline. Update the transaction in the // response queue to reflect that if necessary. We are now sending // out a request while we haven't received all responses. nsAHttpTransaction *response = Response(0); if (response && !response->PipelinePosition()) response->SetPipelinePosition(1); rv = trans->ReadSegments(this, (PRUint32)NS_MIN(avail, (PRUint64)PR_UINT32_MAX), &n); if (NS_FAILED(rv)) return rv; if (n == 0) { LOG(("send pipe is full")); break; } mSendingToProgress += n; if (!mSuppressSendEvents && transport) { // Simulate a SENDING_TO event trans->OnTransportStatus(transport, NS_NET_STATUS_SENDING_TO, mSendingToProgress); } } avail = trans->Available(); if (avail == 0) { // move transaction from request queue to response queue mRequestQ.RemoveElementAt(0); mResponseQ.AppendElement(trans); mRequestIsPartial = false; if (!mSuppressSendEvents && transport) { // Simulate a WAITING_FOR event trans->OnTransportStatus(transport, NS_NET_STATUS_WAITING_FOR, mSendingToProgress); } // It would be good to re-enable data read handlers via ResumeRecv() // except the read handler code can be synchronously dispatched on // the stack. } else mRequestIsPartial = true; } return NS_OK; }
nsresult nsUnknownDecoder::FireListenerNotifications(nsIRequest* request, nsISupports *aCtxt) { nsresult rv = NS_OK; if (!mNextListener) return NS_ERROR_FAILURE; if (!mContentType.IsEmpty()) { nsCOMPtr<nsIViewSourceChannel> viewSourceChannel = do_QueryInterface(request); if (viewSourceChannel) { rv = viewSourceChannel->SetOriginalContentType(mContentType); } else { nsCOMPtr<nsIChannel> channel = do_QueryInterface(request, &rv); if (NS_SUCCEEDED(rv)) { // Set the new content type on the channel... rv = channel->SetContentType(mContentType); } } NS_ASSERTION(NS_SUCCEEDED(rv), "Unable to set content type on channel!"); if (NS_FAILED(rv)) { // Cancel the request to make sure it has the correct status if // mNextListener looks at it. request->Cancel(rv); mNextListener->OnStartRequest(request, aCtxt); nsCOMPtr<nsIDivertableChannel> divertable = do_QueryInterface(request); if (divertable) { rv = divertable->UnknownDecoderInvolvedOnStartRequestCalled(); } return rv; } } // Fire the OnStartRequest(...) rv = mNextListener->OnStartRequest(request, aCtxt); nsCOMPtr<nsIDivertableChannel> divertable = do_QueryInterface(request); if (divertable) { rv = divertable->UnknownDecoderInvolvedOnStartRequestCalled(); bool diverting; divertable->GetDivertingToParent(&diverting); if (diverting) { // The channel is diverted to the parent do not send any more data here. return rv; } } if (NS_SUCCEEDED(rv)) { // install stream converter if required nsCOMPtr<nsIEncodedChannel> encodedChannel = do_QueryInterface(request); if (encodedChannel) { nsCOMPtr<nsIStreamListener> listener; rv = encodedChannel->DoApplyContentConversions(mNextListener, getter_AddRefs(listener), aCtxt); if (NS_SUCCEEDED(rv) && listener) { mNextListener = listener; } } } if (!mBuffer) return NS_ERROR_OUT_OF_MEMORY; // If the request was canceled, then we need to treat that equivalently // to an error returned by OnStartRequest. if (NS_SUCCEEDED(rv)) request->GetStatus(&rv); // Fire the first OnDataAvailable for the data that was read from the // stream into the sniffer buffer... if (NS_SUCCEEDED(rv) && (mBufferLen > 0)) { uint32_t len = 0; nsCOMPtr<nsIInputStream> in; nsCOMPtr<nsIOutputStream> out; // Create a pipe and fill it with the data from the sniffer buffer. rv = NS_NewPipe(getter_AddRefs(in), getter_AddRefs(out), MAX_BUFFER_SIZE, MAX_BUFFER_SIZE); if (NS_SUCCEEDED(rv)) { rv = out->Write(mBuffer, mBufferLen, &len); if (NS_SUCCEEDED(rv)) { if (len == mBufferLen) { rv = mNextListener->OnDataAvailable(request, aCtxt, in, 0, len); } else { NS_ERROR("Unable to write all the data into the pipe."); rv = NS_ERROR_FAILURE; } } } } delete [] mBuffer; mBuffer = nullptr; mBufferLen = 0; return rv; }
nsresult nsIconChannel::MakeInputStream(nsIInputStream** _retval, PRBool nonBlocking) { nsXPIDLCString contentType; nsCAutoString filePath; nsCAutoString fileExtension; nsCOMPtr<nsIFile> localFile; // File we want an icon for PRUint32 desiredImageSize; nsresult rv = ExtractIconInfoFromUrl(getter_AddRefs(localFile), &desiredImageSize, contentType, fileExtension); NS_ENSURE_SUCCESS(rv, rv); PRUint32 iconSize = 16; if (desiredImageSize > 16) iconSize = 32; PRUint32 alphaBytesPerRow = (iconSize / 8); if (iconSize % 32 != 0) alphaBytesPerRow = ((iconSize / 32) + 1) * 4; PRBool fileExists = PR_FALSE; if (localFile) { localFile->GetNativePath(filePath); localFile->Exists(&fileExists); } // Get the native icon. // 1) If it is for an actual local file, BNodeInfo::GetTrackerIcon. // 2) If the local file does not exist, use the content type // and BMimeType::GetIcon BBitmap nativeIcon(BRect(0, 0, iconSize - 1, iconSize - 1), B_CMAP8); if (!nativeIcon.IsValid()) return NS_ERROR_OUT_OF_MEMORY; PRBool gotBitmap = PR_FALSE; if (fileExists) { BNode localNode(filePath.get()); // BeOS doesn't MIME type foreign files immediately - // If there is no type attribute then we can force an identify if (localNode.ReadAttr("BEOS:TYPE", B_STRING_TYPE, 0, NULL, 0) != B_OK) update_mime_info(filePath.get(), 0, 1, 1); BNodeInfo localNodeInfo(&localNode); if (iconSize == 16) { if (localNodeInfo.GetTrackerIcon(&nativeIcon, B_MINI_ICON) == B_OK) gotBitmap = PR_TRUE; } else { if (localNodeInfo.GetTrackerIcon(&nativeIcon, B_LARGE_ICON) == B_OK) gotBitmap = PR_TRUE; } } // If we haven't got a bitmap yet, use the content type if (!gotBitmap) { // If no content type specified, use mozilla's mime service to guess a mime type if (contentType.IsEmpty()) { nsCOMPtr<nsIMIMEService> mimeService (do_GetService("@mozilla.org/mime;1", &rv)); if (NS_SUCCEEDED(rv)) mimeService->GetTypeFromExtension(fileExtension, contentType); // If unrecognised extension - set to generic file if (contentType.IsEmpty()) contentType = "application/octet-stream"; } // Create BeOS-Native MIME type info - if unheard of, set to generic file BMimeType mimeType(contentType.get()); if (!mimeType.IsInstalled()) mimeType.SetTo("application/octet-stream"); if (iconSize == 16) { if (mimeType.GetIcon(&nativeIcon, B_MINI_ICON) == B_OK) gotBitmap = PR_TRUE; } else { if (mimeType.GetIcon(&nativeIcon, B_LARGE_ICON) == B_OK) gotBitmap = PR_TRUE; } } if (!gotBitmap) return NS_ERROR_NOT_AVAILABLE; BScreen mainScreen(B_MAIN_SCREEN_ID); if (!mainScreen.IsValid()) return NS_ERROR_NOT_AVAILABLE; // Got a bitmap and color space info - convert data to mozilla's icon format PRUint32 iconLength = 2 + iconSize * iconSize * 4; uint8 *buffer = new uint8[iconLength]; if (!buffer) return NS_ERROR_OUT_OF_MEMORY; uint8* destByte = buffer; *(destByte++) = iconSize; *(destByte++) = iconSize; // RGB data uint8* sourceByte = (uint8*)nativeIcon.Bits(); for(PRUint32 iconRow = 0; iconRow < iconSize; iconRow++) { sourceByte = (uint8*)nativeIcon.Bits() + nativeIcon.BytesPerRow() * iconRow; for(PRUint32 iconCol = 0; iconCol < iconSize; iconCol++) { if (*sourceByte != B_TRANSPARENT_MAGIC_CMAP8) { rgb_color colorVal = mainScreen.ColorForIndex(*sourceByte); #ifdef IS_LITTLE_ENDIAN *(destByte++) = colorVal.blue; *(destByte++) = colorVal.green; *(destByte++) = colorVal.red; *(destByte++) = uint8(255); #else *(destByte++) = uint8(255); *(destByte++) = colorVal.red; *(destByte++) = colorVal.green; *(destByte++) = colorVal.blue; #endif } else { *destByte++ = 0; *destByte++ = 0; *destByte++ = 0; *destByte++ = 0; } // original code had a conditional here: // if (iconCol < iconSize - 1) // Leaving this comment in case complications arise later sourceByte++; } } NS_ASSERTION(buffer + iconLength == destByte, "size miscalculation"); // Now, create a pipe and stuff our data into it nsCOMPtr<nsIInputStream> inStream; nsCOMPtr<nsIOutputStream> outStream; rv = NS_NewPipe(getter_AddRefs(inStream), getter_AddRefs(outStream), iconLength, iconLength, nonBlocking); if (NS_SUCCEEDED(rv)) { PRUint32 written; rv = outStream->Write((char*)buffer, iconLength, &written); if (NS_SUCCEEDED(rv)) NS_ADDREF(*_retval = inStream); } delete [] buffer; return rv; }
nsresult nsHttpPipeline::FillSendBuf() { // reads from request queue, moving transactions to response queue // when they have been completely read. nsresult rv; if (!mSendBufIn) { // allocate a single-segment pipe rv = NS_NewPipe(getter_AddRefs(mSendBufIn), getter_AddRefs(mSendBufOut), nsIOService::gDefaultSegmentSize, /* segment size */ nsIOService::gDefaultSegmentSize, /* max size */ true, true); if (NS_FAILED(rv)) return rv; } PRUint32 n, avail; nsAHttpTransaction *trans; nsITransport *transport = Transport(); while ((trans = Request(0)) != nsnull) { avail = trans->Available(); if (avail) { rv = trans->ReadSegments(this, avail, &n); if (NS_FAILED(rv)) return rv; if (n == 0) { LOG(("send pipe is full")); break; } mSendingToProgress += n; if (!mSuppressSendEvents && transport) { // Simulate a SENDING_TO event trans->OnTransportStatus(transport, NS_NET_STATUS_SENDING_TO, mSendingToProgress); } } avail = trans->Available(); if (avail == 0) { // move transaction from request queue to response queue mRequestQ.RemoveElementAt(0); mResponseQ.AppendElement(trans); mRequestIsPartial = false; if (!mSuppressSendEvents && transport) { // Simulate a WAITING_FOR event trans->OnTransportStatus(transport, NS_NET_STATUS_WAITING_FOR, mSendingToProgress); } } else mRequestIsPartial = true; } return NS_OK; }