void nsIncrementalDownload::UpdateProgress() { mLastProgressUpdate = PR_Now(); if (mProgressSink) mProgressSink->OnProgress(this, mObserverContext, PRUint64(PRInt64(mCurrentSize) + mChunkLen), PRUint64(PRInt64(mTotalSize))); }
NS_IMETHODIMP nsInputStreamPump::Init(nsIInputStream *stream, PRInt64 streamPos, PRInt64 streamLen, PRUint32 segsize, PRUint32 segcount, bool closeWhenDone) { NS_ENSURE_TRUE(mState == STATE_IDLE, NS_ERROR_IN_PROGRESS); mStreamOffset = PRUint64(streamPos); if (PRInt64(streamLen) >= PRInt64(0)) mStreamLength = PRUint64(streamLen); mStream = stream; mSegSize = segsize; mSegCount = segcount; mCloseWhenDone = closeWhenDone; return NS_OK; }
NS_IMETHODIMP nsWyciwygChannel::OnDataAvailable(nsIRequest *request, nsISupports *ctx, nsIInputStream *input, PRUint32 offset, PRUint32 count) { LOG(("nsWyciwygChannel::OnDataAvailable [this=%x request=%x offset=%u count=%u]\n", this, request, offset, count)); nsresult rv; rv = mListener->OnDataAvailable(this, mListenerContext, input, offset, count); // XXX handle 64-bit stuff for real if (mProgressSink && NS_SUCCEEDED(rv) && !(mLoadFlags & LOAD_BACKGROUND)) mProgressSink->OnProgress(this, nsnull, PRUint64(offset + count), PRUint64(mContentLength)); return rv; // let the pump cancel on failure }
nsresult nsIncrementalDownload::FlushChunk() { NS_ASSERTION(mTotalSize != nsInt64(-1), "total size should be known"); if (mChunkLen == 0) return NS_OK; nsresult rv = AppendToFile(mDest, mChunk, mChunkLen); if (NS_FAILED(rv)) return rv; mCurrentSize += nsInt64(mChunkLen); mChunkLen = 0; if (mProgressSink) mProgressSink->OnProgress(this, mObserverContext, PRUint64(PRInt64(mCurrentSize)), PRUint64(PRInt64(mTotalSize))); 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)); }
NS_IMETHODIMP nsBaseChannel::OnDataAvailable(nsIRequest *request, nsISupports *ctxt, nsIInputStream *stream, PRUint32 offset, PRUint32 count) { SUSPEND_PUMP_FOR_SCOPE(); nsresult rv = mListener->OnDataAvailable(this, mListenerContext, stream, offset, count); if (mSynthProgressEvents && NS_SUCCEEDED(rv)) { PRUint64 prog = PRUint64(offset) + count; OnTransportStatus(nsnull, nsITransport::STATUS_READING, prog, mContentLength); } return rv; }
TimeStamp TimeStamp::Now() { // XXX this could be considerably simpler and faster if we had // 64-bit atomic operations PR_Lock(gTimeStampLock); PRIntervalTime now = PR_IntervalNow(); if (now < gLastNow) { ++gRolloverCount; // This can't happen unless you've been running for millions of years NS_ASSERTION(gRolloverCount > 0, "Rollover in rollover count???"); } gLastNow = now; TimeStamp result((PRUint64(gRolloverCount) << 32) + now); PR_Unlock(gTimeStampLock); return result; }
NS_IMETHODIMP nsXPInstallManager::OnProgress(nsIRequest* request, nsISupports *ctxt, PRUint64 aProgress, PRUint64 aProgressMax) { nsresult rv = NS_OK; if (mDlg && !mCancelled) { if (mContentLength < 1) { nsCOMPtr<nsIChannel> channel = do_QueryInterface(request,&rv); NS_ASSERTION(channel, "should have a channel"); if (NS_FAILED(rv)) return rv; rv = channel->GetContentLength(&mContentLength); if (NS_FAILED(rv)) return rv; } // XXX once channels support that, use 64-bit contentlength rv = mDlg->OnProgress( mNextItem-1, aProgress, PRUint64(mContentLength) ); } return rv; }
NS_IMETHODIMP nsJARChannel::OnDataAvailable(nsIRequest *req, nsISupports *ctx, nsIInputStream *stream, PRUint32 offset, PRUint32 count) { #if defined(PR_LOGGING) LOG(("nsJARChannel::OnDataAvailable [this=%x %s]\n", this, mSpec.get())); #endif nsresult rv; // XXX want 64-bit values in OnDataAvailable rv = mListener->OnDataAvailable(this, mListenerContext, stream, offset, count); // simply report progress here instead of hooking ourselves up as a // nsITransportEventSink implementation. if (mProgressSink && NS_SUCCEEDED(rv) && !(mLoadFlags & LOAD_BACKGROUND)) mProgressSink->OnProgress(this, nsnull, PRUint64(offset + count), mContentLength); return rv; // let the pump cancel on failure }
static PRStatus ARENA_POISON_init() { PRUword rgnsize = GetDesiredRegionSize(); PRUword rgnbase = ReservePoisonArea(rgnsize); if (rgnsize == 0) // can't happen return PR_FAILURE; ARENA_POISON = rgnbase + rgnsize/2 - 1; #ifdef MOZ_CRASHREPORTER nsCOMPtr<nsICrashReporter> cr = do_GetService("@mozilla.org/toolkit/crash-reporter;1"); PRBool enabled; if (cr && NS_SUCCEEDED(cr->GetEnabled(&enabled)) && enabled) { cr->AnnotateCrashReport(NS_LITERAL_CSTRING("FramePoisonBase"), nsPrintfCString(17, "%.16llx", PRUint64(rgnbase))); cr->AnnotateCrashReport(NS_LITERAL_CSTRING("FramePoisonSize"), nsPrintfCString("%lu", PRUint32(rgnsize))); } #endif return PR_SUCCESS; }
PRUint32 nsInputStreamPump::OnStateTransfer() { SAMPLE_LABEL("Input", "nsInputStreamPump::OnStateTransfer"); LOG((" OnStateTransfer [this=%x]\n", this)); // if canceled, go directly to STATE_STOP... if (NS_FAILED(mStatus)) return STATE_STOP; nsresult rv; PRUint32 avail; rv = mAsyncStream->Available(&avail); LOG((" Available returned [stream=%x rv=%x avail=%u]\n", mAsyncStream.get(), rv, avail)); if (rv == NS_BASE_STREAM_CLOSED) { rv = NS_OK; avail = 0; } else if (NS_SUCCEEDED(rv) && avail) { // figure out how much data to report (XXX detect overflow??) if (PRUint64(avail) + mStreamOffset > mStreamLength) avail = PRUint32(mStreamLength - mStreamOffset); if (avail) { // we used to limit avail to 16K - we were afraid some ODA handlers // might assume they wouldn't get more than 16K at once // we're removing that limit since it speeds up local file access. // Now there's an implicit 64K limit of 4 16K segments // NOTE: ok, so the story is as follows. OnDataAvailable impls // are by contract supposed to consume exactly |avail| bytes. // however, many do not... mailnews... stream converters... // cough, cough. the input stream pump is fairly tolerant // in this regard; however, if an ODA does not consume any // data from the stream, then we could potentially end up in // an infinite loop. we do our best here to try to catch // such an error. (see bug 189672) // in most cases this QI will succeed (mAsyncStream is almost always // a nsPipeInputStream, which implements nsISeekableStream::Tell). PRInt64 offsetBefore; nsCOMPtr<nsISeekableStream> seekable = do_QueryInterface(mAsyncStream); if (seekable && NS_FAILED(seekable->Tell(&offsetBefore))) { NS_NOTREACHED("Tell failed on readable stream"); offsetBefore = 0; } // report the current stream offset to our listener... if we've // streamed more than PR_UINT32_MAX, then avoid overflowing the // stream offset. it's the best we can do without a 64-bit stream // listener API. PRUint32 odaOffset = mStreamOffset > PR_UINT32_MAX ? PR_UINT32_MAX : PRUint32(mStreamOffset); LOG((" calling OnDataAvailable [offset=%lld(%u) count=%u]\n", mStreamOffset, odaOffset, avail)); rv = mListener->OnDataAvailable(this, mListenerContext, mAsyncStream, odaOffset, avail); // don't enter this code if ODA failed or called Cancel if (NS_SUCCEEDED(rv) && NS_SUCCEEDED(mStatus)) { // test to see if this ODA failed to consume data if (seekable) { // NOTE: if Tell fails, which can happen if the stream is // now closed, then we assume that everything was read. PRInt64 offsetAfter; if (NS_FAILED(seekable->Tell(&offsetAfter))) offsetAfter = offsetBefore + avail; if (offsetAfter > offsetBefore) mStreamOffset += (offsetAfter - offsetBefore); else if (mSuspendCount == 0) { // // possible infinite loop if we continue pumping data! // // NOTE: although not allowed by nsIStreamListener, we // will allow the ODA impl to Suspend the pump. IMAP // does this :-( // NS_ERROR("OnDataAvailable implementation consumed no data"); mStatus = NS_ERROR_UNEXPECTED; } } else mStreamOffset += avail; // assume ODA behaved well } } } // an error returned from Available or OnDataAvailable should cause us to // abort; however, we must not stomp on mStatus if already canceled. if (NS_SUCCEEDED(mStatus)) { if (NS_FAILED(rv)) mStatus = rv; else if (avail) { // if stream is now closed, advance to STATE_STOP right away. // Available may return 0 bytes available at the moment; that // would not mean that we are done. // XXX async streams should have a GetStatus method! rv = mAsyncStream->Available(&avail); if (NS_SUCCEEDED(rv)) return STATE_TRANSFER; } } return STATE_STOP; }
static inline PRUint64 version(PRUint32 major, PRUint32 minor) { return (PRUint64(major) << 32) + PRUint64(minor); }
NS_IMETHODIMP nsIndexedToHTML::OnIndexAvailable(nsIRequest *aRequest, nsISupports *aCtxt, nsIDirIndex *aIndex) { nsresult rv; if (!aIndex) return NS_ERROR_NULL_POINTER; nsString pushBuffer; pushBuffer.AppendLiteral("<tr"); nsXPIDLString description; aIndex->GetDescription(getter_Copies(description)); if (description.First() == PRUnichar('.')) pushBuffer.AppendLiteral(" class=\"hidden-object\""); pushBuffer.AppendLiteral(">\n <td sortable-data=\""); // The sort key is the name of the item, prepended by either 0, 1 or 2 // in order to group items. PRUint32 type; aIndex->GetType(&type); switch (type) { case nsIDirIndex::TYPE_SYMLINK: pushBuffer.AppendInt(0); break; case nsIDirIndex::TYPE_DIRECTORY: pushBuffer.AppendInt(1); break; case nsIDirIndex::TYPE_FILE: case nsIDirIndex::TYPE_UNKNOWN: pushBuffer.AppendInt(2); break; } PRUnichar* escaped = nsEscapeHTML2(description.get(), description.Length()); pushBuffer.Append(escaped); pushBuffer.AppendLiteral("\"><a class=\""); switch (type) { case nsIDirIndex::TYPE_DIRECTORY: pushBuffer.AppendLiteral("dir"); break; case nsIDirIndex::TYPE_SYMLINK: pushBuffer.AppendLiteral("symlink"); break; case nsIDirIndex::TYPE_FILE: case nsIDirIndex::TYPE_UNKNOWN: pushBuffer.AppendLiteral("file"); break; } pushBuffer.AppendLiteral("\""); // Truncate long names to not stretch the table //XXX this should be left to the stylesheet (bug 391471) nsString escapedShort; if (description.Length() > 71) { nsCOMPtr<nsIChannel> channel = do_QueryInterface(aRequest); nsCOMPtr<nsIURI> uri; rv = channel->GetURI(getter_AddRefs(uri)); if (NS_FAILED(rv)) return rv; //XXX this potentially truncates after a combining char (bug 391472) nsXPIDLString descriptionAffix; descriptionAffix.Assign(description); descriptionAffix.Cut(0, descriptionAffix.Length() - 25); if (NS_IS_LOW_SURROGATE(descriptionAffix.First())) descriptionAffix.Cut(0, 1); description.Truncate(NS_MIN<PRUint32>(71, description.Length() - 28)); if (NS_IS_HIGH_SURROGATE(description.Last())) description.Truncate(description.Length() - 1); escapedShort.Adopt(nsEscapeHTML2(description.get(), description.Length())); escapedShort.Append(mEscapedEllipsis); // add ZERO WIDTH SPACE (U+200B) for wrapping escapedShort.AppendLiteral("​"); nsString tmp; tmp.Adopt(nsEscapeHTML2(descriptionAffix.get(), descriptionAffix.Length())); escapedShort.Append(tmp); pushBuffer.AppendLiteral(" title=\""); pushBuffer.Append(escaped); pushBuffer.AppendLiteral("\""); } if (escapedShort.IsEmpty()) escapedShort.Assign(escaped); nsMemory::Free(escaped); pushBuffer.AppendLiteral(" href=\""); nsXPIDLCString loc; aIndex->GetLocation(getter_Copies(loc)); if (!mTextToSubURI) { mTextToSubURI = do_GetService(NS_ITEXTTOSUBURI_CONTRACTID, &rv); if (NS_FAILED(rv)) return rv; } nsXPIDLCString encoding; rv = mParser->GetEncoding(getter_Copies(encoding)); if (NS_FAILED(rv)) return rv; nsXPIDLString unEscapeSpec; rv = mTextToSubURI->UnEscapeAndConvert(encoding, loc, getter_Copies(unEscapeSpec)); if (NS_FAILED(rv)) return rv; // need to escape links nsCAutoString escapeBuf; NS_ConvertUTF16toUTF8 utf8UnEscapeSpec(unEscapeSpec); // Adding trailing slash helps to recognize whether the URL points to a file // or a directory (bug #214405). if ((type == nsIDirIndex::TYPE_DIRECTORY) && (utf8UnEscapeSpec.Last() != '/')) { utf8UnEscapeSpec.Append('/'); } // now minimally re-escape the location... PRUint32 escFlags; // for some protocols, we expect the location to be absolute. // if so, and if the location indeed appears to be a valid URI, then go // ahead and treat it like one. if (mExpectAbsLoc && NS_SUCCEEDED(net_ExtractURLScheme(utf8UnEscapeSpec, nsnull, nsnull, nsnull))) { // escape as absolute escFlags = esc_Forced | esc_OnlyASCII | esc_AlwaysCopy | esc_Minimal; } else { // escape as relative // esc_Directory is needed because directories have a trailing slash. // Without it, the trailing '/' will be escaped, and links from within // that directory will be incorrect escFlags = esc_Forced | esc_OnlyASCII | esc_AlwaysCopy | esc_FileBaseName | esc_Colon | esc_Directory; } NS_EscapeURL(utf8UnEscapeSpec.get(), utf8UnEscapeSpec.Length(), escFlags, escapeBuf); // esc_Directory does not escape the semicolons, so if a filename // contains semicolons we need to manually escape them. // This replacement should be removed in bug #473280 escapeBuf.ReplaceSubstring(";", "%3b"); NS_ConvertUTF8toUTF16 utf16URI(escapeBuf); nsString htmlEscapedURL; htmlEscapedURL.Adopt(nsEscapeHTML2(utf16URI.get(), utf16URI.Length())); pushBuffer.Append(htmlEscapedURL); pushBuffer.AppendLiteral("\">"); if (type == nsIDirIndex::TYPE_FILE || type == nsIDirIndex::TYPE_UNKNOWN) { pushBuffer.AppendLiteral("<img src=\"moz-icon://"); PRInt32 lastDot = escapeBuf.RFindChar('.'); if (lastDot != kNotFound) { escapeBuf.Cut(0, lastDot); NS_ConvertUTF8toUTF16 utf16EscapeBuf(escapeBuf); nsString htmlFileExt; htmlFileExt.Adopt(nsEscapeHTML2(utf16EscapeBuf.get(), utf16EscapeBuf.Length())); pushBuffer.Append(htmlFileExt); } else { pushBuffer.AppendLiteral("unknown"); } pushBuffer.AppendLiteral("?size=16\" alt=\""); nsXPIDLString altText; rv = mBundle->GetStringFromName(NS_LITERAL_STRING("DirFileLabel").get(), getter_Copies(altText)); if (NS_FAILED(rv)) return rv; AppendNonAsciiToNCR(altText, pushBuffer); pushBuffer.AppendLiteral("\">"); } pushBuffer.Append(escapedShort); pushBuffer.AppendLiteral("</a></td>\n <td"); if (type == nsIDirIndex::TYPE_DIRECTORY || type == nsIDirIndex::TYPE_SYMLINK) { pushBuffer.AppendLiteral(">"); } else { PRInt64 size; aIndex->GetSize(&size); if (PRUint64(size) != LL_MAXUINT) { pushBuffer.AppendLiteral(" sortable-data=\""); pushBuffer.AppendInt(size); pushBuffer.AppendLiteral("\">"); nsAutoString sizeString; FormatSizeString(size, sizeString); pushBuffer.Append(sizeString); } else { pushBuffer.AppendLiteral(">"); } } pushBuffer.AppendLiteral("</td>\n <td"); PRTime t; aIndex->GetLastModified(&t); if (t == -1) { pushBuffer.AppendLiteral("></td>\n <td>"); } else { pushBuffer.AppendLiteral(" sortable-data=\""); pushBuffer.AppendInt(t); pushBuffer.AppendLiteral("\">"); nsAutoString formatted; mDateTime->FormatPRTime(nsnull, kDateFormatShort, kTimeFormatNone, t, formatted); AppendNonAsciiToNCR(formatted, pushBuffer); pushBuffer.AppendLiteral("</td>\n <td>"); mDateTime->FormatPRTime(nsnull, kDateFormatNone, kTimeFormatSeconds, t, formatted); // use NCR to show date in any doc charset AppendNonAsciiToNCR(formatted, pushBuffer); } pushBuffer.AppendLiteral("</td>\n</tr>"); return FormatInputStream(aRequest, aCtxt, pushBuffer); }
TimeStamp TimeStamp::Now() { return TimeStamp(PRUint64(CalibratedPerformanceCounter())); }
GnomeVFSResult nsGnomeVFSInputStream::DoOpen() { GnomeVFSResult rv; NS_ASSERTION(mHandle == nsnull, "already open"); // Push a callback handler on the stack for this thread, so we can intercept // authentication requests from GnomeVFS. We'll use the channel to get a // nsIAuthPrompt instance. gnome_vfs_module_callback_push(GNOME_VFS_MODULE_CALLBACK_AUTHENTICATION, AuthCallback, mChannel, NULL); // Query the mime type first (this could return NULL). // // XXX We need to do this up-front in order to determine how to open the URI. // Unfortunately, the error code GNOME_VFS_ERROR_IS_DIRECTORY is not // always returned by gnome_vfs_open when we pass it a URI to a directory! // Otherwise, we could have used that as a way to failover to opening the // URI as a directory. Also, it would have been ideal if // gnome_vfs_get_file_info_from_handle were actually implemented by the // smb:// module, since that would have allowed us to potentially save a // round trip to the server to discover the mime type of the document in // the case where gnome_vfs_open would have been used. (Oh well! /me // throws hands up in the air and moves on...) GnomeVFSFileInfo info = {0}; rv = gnome_vfs_get_file_info(mSpec.get(), &info, GnomeVFSFileInfoOptions( GNOME_VFS_FILE_INFO_DEFAULT | GNOME_VFS_FILE_INFO_FOLLOW_LINKS)); if (rv == GNOME_VFS_OK) { if (info.type == GNOME_VFS_FILE_TYPE_DIRECTORY) { rv = gnome_vfs_directory_list_load(&mDirList, mSpec.get(), GNOME_VFS_FILE_INFO_DEFAULT); LOG(("gnomevfs: gnome_vfs_directory_list_load returned %d (%s) [spec=\"%s\"]\n", rv, gnome_vfs_result_to_string(rv), mSpec.get())); } else { rv = gnome_vfs_open(&mHandle, mSpec.get(), GNOME_VFS_OPEN_READ); LOG(("gnomevfs: gnome_vfs_open returned %d (%s) [spec=\"%s\"]\n", rv, gnome_vfs_result_to_string(rv), mSpec.get())); } } gnome_vfs_module_callback_pop(GNOME_VFS_MODULE_CALLBACK_AUTHENTICATION); if (rv == GNOME_VFS_OK) { if (mHandle) { // Here we set the content type of the channel to the value of the mime // type determined by GnomeVFS. However, if GnomeVFS is telling us that // the document is binary, we'll ignore that and keep the channel's // content type unspecified. That will enable our content type sniffing // algorithms. This should provide more consistent mime type handling. if (info.mime_type && (strcmp(info.mime_type, APPLICATION_OCTET_STREAM) != 0)) SetContentTypeOfChannel(info.mime_type); mBytesRemaining = info.size; // Update the content length attribute on the channel. We do this // synchronously without proxying. This hack is not as bad as it looks! if (mBytesRemaining != PRUint64(-1)) mChannel->SetContentLength(mBytesRemaining); } else { mDirOpen = PR_TRUE; // Sort mDirList mDirList = g_list_sort(mDirList, FileInfoComparator); mDirListPtr = mDirList; // Write base URL (make sure it ends with a '/') mDirBuf.Append("300: "); mDirBuf.Append(mSpec); if (mSpec.get()[mSpec.Length() - 1] != '/') mDirBuf.Append('/'); mDirBuf.Append('\n'); // Write column names mDirBuf.Append("200: filename content-length last-modified file-type\n"); // Write charset (assume UTF-8) // XXX is this correct? mDirBuf.Append("301: UTF-8\n"); SetContentTypeOfChannel(APPLICATION_HTTP_INDEX_FORMAT); } } gnome_vfs_file_info_clear(&info); return rv; }
static PRUint64 TimespecToNs(const struct timespec& ts) { PRUint64 baseNs = PRUint64(ts.tv_sec) * kNsPerSec; return baseNs + PRUint64(ts.tv_nsec); }
static inline PRUint64 version(PRUint32 major, PRUint32 minor, PRUint32 revision = 0) { return (PRUint64(major) << 32) + (PRUint64(minor) << 16) + PRUint64(revision); }