static void __ReplaceCChar (nsACString &string, const char replace, const char with) { PRInt32 i = string.FindChar (replace); while (i >= 0 ) { string.Replace (i, 1, (const char*) &with, 1); i = string.FindChar (replace); } }
nsresult nsDefaultURIFixup::KeywordURIFixup(const nsACString & aURIString, nsIURI** aURI) { // These are keyword formatted strings // "what is mozilla" // "what is mozilla?" // "docshell site:mozilla.org" - has no dot/colon in the first space-separated substring // "?mozilla" - anything that begins with a question mark // "?site:mozilla.org docshell" // Things that have a quote before the first dot/colon // These are not keyword formatted strings // "www.blah.com" - first space-separated substring contains a dot, doesn't start with "?" // "www.blah.com stuff" // "nonQualifiedHost:80" - first space-separated substring contains a colon, doesn't start with "?" // "nonQualifiedHost:80 args" // "nonQualifiedHost?" // "nonQualifiedHost?args" // "nonQualifiedHost?some args" // Note: uint32_t(kNotFound) is greater than any actual location // in practice. So if we cast all locations to uint32_t, then a < // b guarantees that either b is kNotFound and a is found, or both // are found and a found before b. uint32_t dotLoc = uint32_t(aURIString.FindChar('.')); uint32_t colonLoc = uint32_t(aURIString.FindChar(':')); uint32_t spaceLoc = uint32_t(aURIString.FindChar(' ')); if (spaceLoc == 0) { // Treat this as not found spaceLoc = uint32_t(kNotFound); } uint32_t qMarkLoc = uint32_t(aURIString.FindChar('?')); uint32_t quoteLoc = NS_MIN(uint32_t(aURIString.FindChar('"')), uint32_t(aURIString.FindChar('\''))); if (((spaceLoc < dotLoc || quoteLoc < dotLoc) && (spaceLoc < colonLoc || quoteLoc < colonLoc) && (spaceLoc < qMarkLoc || quoteLoc < qMarkLoc)) || qMarkLoc == 0 || (dotLoc == uint32_t(kNotFound) && colonLoc == uint32_t(kNotFound) && qMarkLoc == uint32_t(kNotFound) ) ) { KeywordToURI(aURIString, aURI); } if(*aURI) return NS_OK; return NS_ERROR_FAILURE; }
PRBool ParseString(const nsACString& aSource, char aDelimiter, nsTArray<nsCString>& aArray) { PRInt32 start = 0; PRInt32 end = aSource.Length(); PRUint32 oldLength = aArray.Length(); for (;;) { PRInt32 delimiter = aSource.FindChar(aDelimiter, start); if (delimiter < 0) { delimiter = end; } if (delimiter != start) { if (!aArray.AppendElement(Substring(aSource, start, delimiter - start))) { aArray.RemoveElementsAt(oldLength, aArray.Length() - oldLength); return PR_FALSE; } } if (delimiter == end) break; start = ++delimiter; if (start == end) break; } return PR_TRUE; }
NS_IMETHODIMP nsNNTPNewsgroupList::ProcessHEADLine(const nsACString &line) { int32_t colon = line.FindChar(':'); nsCString header = PromiseFlatCString(line), value; if (colon != -1) { value = Substring(line, colon+1); header.SetLength((uint32_t)colon); } else if (line.CharAt(0) == ' ' || line.CharAt(0) == '\t') // We are continuing the header { m_thisLine += header; // Preserve whitespace (should we?) return NS_OK; } else { return NS_OK; // We are malformed. Just ignore and hope for the best... } nsresult rv; if (!m_lastHeader.IsEmpty()) { rv = AddHeader(m_lastHeader.get(), m_thisLine.get()); NS_ENSURE_SUCCESS(rv,rv); } value.Trim(" "); ToLowerCase(header, m_lastHeader); m_thisLine.Assign(value); return NS_OK; }
// static PRBool nsDOMStorageList::ConvertDomainToArray(const nsACString& aDomain, nsTArray<nsCString> *aArray) { PRInt32 length = aDomain.Length(); PRInt32 n = 0; while (n < length) { PRInt32 dotpos = aDomain.FindChar('.', n); nsCAutoString domain; if (dotpos == -1) // no more dots domain.Assign(Substring(aDomain, n)); else if (dotpos - n == 0) // no point continuing in this case return false; else if (dotpos >= 0) domain.Assign(Substring(aDomain, n, dotpos - n)); ToLowerCase(domain); aArray->AppendElement(domain); if (dotpos == -1) break; n = dotpos + 1; } // if n equals the length, there is a dot at the end, so treat it as invalid return (n != length); }
bool ParseString(const nsACString& aSource, char aDelimiter, nsTArray<nsCString>& aArray) { int32_t start = 0; int32_t end = aSource.Length(); uint32_t oldLength = aArray.Length(); for (;;) { int32_t delimiter = aSource.FindChar(aDelimiter, start); if (delimiter < 0) { delimiter = end; } if (delimiter != start) { if (!aArray.AppendElement(Substring(aSource, start, delimiter - start))) { aArray.RemoveElementsAt(oldLength, aArray.Length() - oldLength); return false; } } if (delimiter == end) break; start = ++delimiter; if (start == end) break; } return true; }
// Works out the screen name to put on the card for some well-known addresses void nsAbAddressCollector::AutoCollectScreenName(nsIAbCard *aCard, const nsACString &aEmail) { if (!aCard) return; int32_t atPos = aEmail.FindChar('@'); if (atPos == -1) return; const nsACString& domain = Substring(aEmail, atPos + 1); if (domain.IsEmpty()) return; // username in // [email protected] (America Online) // [email protected] (Compuserve) // [email protected] (Netscape webmail) // are all AIM screennames. autocollect that info. if (domain.Equals("aol.com") || domain.Equals("cs.com") || domain.Equals("netscape.net")) aCard->SetPropertyAsAUTF8String(kScreenNameProperty, Substring(aEmail, 0, atPos)); else if (domain.Equals("gmail.com") || domain.Equals("googlemail.com")) aCard->SetPropertyAsAUTF8String(kGtalkProperty, Substring(aEmail, 0, atPos)); }
SRIMetadata::SRIMetadata(const nsACString& aToken) : mAlgorithmType(SRIMetadata::UNKNOWN_ALGORITHM), mEmpty(false) { MOZ_ASSERT(!aToken.IsEmpty()); // callers should check this first SRIMETADATALOG(("SRIMetadata::SRIMetadata, aToken='%s'", PromiseFlatCString(aToken).get())); int32_t hyphen = aToken.FindChar('-'); if (hyphen == -1) { SRIMETADATAERROR(("SRIMetadata::SRIMetadata, invalid (no hyphen)")); return; // invalid metadata } // split the token into its components mAlgorithm = Substring(aToken, 0, hyphen); uint32_t hashStart = hyphen + 1; if (hashStart >= aToken.Length()) { SRIMETADATAERROR(("SRIMetadata::SRIMetadata, invalid (missing digest)")); return; // invalid metadata } int32_t question = aToken.FindChar('?'); if (question == -1) { mHashes.AppendElement(Substring(aToken, hashStart, aToken.Length() - hashStart)); } else { MOZ_ASSERT(question > 0); if (static_cast<uint32_t>(question) <= hashStart) { SRIMETADATAERROR(("SRIMetadata::SRIMetadata, invalid (options w/o digest)")); return; // invalid metadata } mHashes.AppendElement(Substring(aToken, hashStart, question - hashStart)); } if (mAlgorithm.EqualsLiteral("sha256")) { mAlgorithmType = nsICryptoHash::SHA256; } else if (mAlgorithm.EqualsLiteral("sha384")) { mAlgorithmType = nsICryptoHash::SHA384; } else if (mAlgorithm.EqualsLiteral("sha512")) { mAlgorithmType = nsICryptoHash::SHA512; } SRIMETADATALOG(("SRIMetadata::SRIMetadata, hash='%s'; alg='%s'", mHashes[0].get(), mAlgorithm.get())); }
/*static*/ nsresult nsHttpHeaderArray::ParseHeaderLine(const nsACString& line, nsHttpAtom *hdr, nsACString *headerName, nsACString *val) { // // BNF from section 4.2 of RFC 2616: // // message-header = field-name ":" [ field-value ] // field-name = token // field-value = *( field-content | LWS ) // field-content = <the OCTETs making up the field-value // and consisting of either *TEXT or combinations // of token, separators, and quoted-string> // // We skip over mal-formed headers in the hope that we'll still be able to // do something useful with the response. int32_t split = line.FindChar(':'); if (split == kNotFound) { LOG(("malformed header [%s]: no colon\n", PromiseFlatCString(line).get())); return NS_ERROR_FAILURE; } const nsACString& sub = Substring(line, 0, split); const nsACString& sub2 = Substring( line, split + 1, line.Length() - split - 1); // make sure we have a valid token for the field-name if (!nsHttp::IsValidToken(sub)) { LOG(("malformed header [%s]: field-name not a token\n", PromiseFlatCString(line).get())); return NS_ERROR_FAILURE; } nsHttpAtom atom = nsHttp::ResolveAtom(sub); if (!atom) { LOG(("failed to resolve atom [%s]\n", PromiseFlatCString(line).get())); return NS_ERROR_FAILURE; } // skip over whitespace char *p = net_FindCharNotInSet( sub2.BeginReading(), sub2.EndReading(), HTTP_LWS); // trim trailing whitespace - bug 86608 char *p2 = net_RFindCharNotInSet(p, sub2.EndReading(), HTTP_LWS); // assign return values if (hdr) *hdr = atom; if (val) val->Assign(p, p2 - p + 1); if (headerName) headerName->Assign(sub); return NS_OK; }
NS_IMETHODIMP nsAbManager::GetDirectory(const nsACString &aURI, nsIAbDirectory **aResult) { NS_ENSURE_ARG_POINTER(aResult); nsresult rv; nsCOMPtr<nsIAbDirectory> directory; // Was the directory root requested? if (aURI.EqualsLiteral(kAllDirectoryRoot)) { rv = GetRootDirectory(getter_AddRefs(directory)); NS_ENSURE_SUCCESS(rv, rv); NS_IF_ADDREF(*aResult = directory); return NS_OK; } // Do we have a copy of this directory already within our look-up table? if (!mAbStore.Get(aURI, getter_AddRefs(directory))) { // The directory wasn't in our look-up table, so we need to instantiate // it. First, extract the scheme from the URI... nsCAutoString scheme; PRInt32 colon = aURI.FindChar(':'); if (colon <= 0) return NS_ERROR_MALFORMED_URI; scheme = Substring(aURI, 0, colon); // Construct the appropriate nsIAbDirectory... nsCAutoString contractID; contractID.AssignLiteral(NS_AB_DIRECTORY_TYPE_CONTRACTID_PREFIX); contractID.Append(scheme); directory = do_CreateInstance(contractID.get(), &rv); NS_ENSURE_SUCCESS(rv, rv); // Init it with the URI rv = directory->Init(PromiseFlatCString(aURI).get()); NS_ENSURE_SUCCESS(rv, rv); // Check if this directory was initiated with a search query. If so, // we don't cache it. bool isQuery = false; rv = directory->GetIsQuery(&isQuery); NS_ENSURE_SUCCESS(rv, rv); if (!isQuery) mAbStore.Put(aURI, directory); } NS_IF_ADDREF(*aResult = directory); return NS_OK; }
NS_IMETHODIMP RustURL::GetSpecIgnoringRef(nsACString & aSpecIgnoringRef) { nsresult rv = GetSpec(aSpecIgnoringRef); if (NS_FAILED(rv)) { return rv; } int32_t pos = aSpecIgnoringRef.FindChar('#'); if (pos == kNotFound) { return NS_OK; } aSpecIgnoringRef.Truncate(pos); return NS_OK; }
NS_IMETHODIMP nsViewSourceHandler::NewURI(const nsACString &aSpec, const char *aCharset, nsIURI *aBaseURI, nsIURI **aResult) { *aResult = nsnull; // Extract inner URL and normalize to ASCII. This is done to properly // support IDN in cases like "view-source:http://www.szalagavató.hu/" PRInt32 colon = aSpec.FindChar(':'); if (colon == kNotFound) return NS_ERROR_MALFORMED_URI; nsCOMPtr<nsIURI> innerURI; nsresult rv = NS_NewURI(getter_AddRefs(innerURI), Substring(aSpec, colon + 1), aCharset, aBaseURI); if (NS_FAILED(rv)) return rv; nsCAutoString asciiSpec; rv = innerURI->GetAsciiSpec(asciiSpec); if (NS_FAILED(rv)) return rv; // put back our scheme and construct a simple-uri wrapper asciiSpec.Insert(VIEW_SOURCE ":", 0); // We can't swap() from an nsRefPtr<nsSimpleNestedURI> to an nsIURI**, // sadly. nsSimpleNestedURI* ourURI = new nsSimpleNestedURI(innerURI); nsCOMPtr<nsIURI> uri = ourURI; if (!uri) return NS_ERROR_OUT_OF_MEMORY; rv = ourURI->SetSpec(asciiSpec); if (NS_FAILED(rv)) return rv; // Make the URI immutable so it's impossible to get it out of sync // with its inner URI. ourURI->SetMutable(PR_FALSE); uri.swap(*aResult); return rv; }
NS_IMETHODIMP nsSimpleURI::SetPath(const nsACString &path) { NS_ENSURE_STATE(mMutable); int32_t hashPos = path.FindChar('#'); if (hashPos < 0) { mIsRefValid = false; mRef.Truncate(); // invariant: mRef should be empty when it's not valid mPath = path; return NS_OK; } mPath = StringHead(path, hashPos); return SetRef(Substring(path, uint32_t(hashPos))); }
NS_IMETHODIMP RustURL::SetUserPass(const nsACString & aUserPass) { ENSURE_MUTABLE(); int32_t colonPos = aUserPass.FindChar(':'); nsAutoCString user; nsAutoCString pass; if (colonPos == kNotFound) { user = aUserPass; } else { user = Substring(aUserPass, 0, colonPos); pass = Substring(aUserPass, colonPos + 1, aUserPass.Length()); } if (rusturl_set_username(mURL.get(), &user) != 0) { return NS_ERROR_FAILURE; } return static_cast<nsresult>(rusturl_set_password(mURL.get(), &pass)); }
static nsMsgSearchOpValue ConvertSearchFlagsToOperator(const nsACString &aFlags) { nsCString flags(aFlags); int32_t lastTabPosition = flags.RFindChar('\t'); if ((lastTabPosition == -1) || ((int32_t)aFlags.Length() == lastTabPosition - 1)) { return -1; } switch (aFlags.CharAt(0)) { case 'X': return nsMsgSearchOp::DoesntContain; case 'O': if (aFlags.FindChar('T', lastTabPosition + 1) >= 0) return nsMsgSearchOp::BeginsWith; return nsMsgSearchOp::Contains; default: return -1; } }
NS_IMETHODIMP nsNNTPNewsgroupList::ProcessXHDRLine(const nsACString &line) { PRInt32 middle = line.FindChar(' '); nsCString value, key = PromiseFlatCString(line); if (middle == -1) return NS_OK; value = Substring(line, middle+1); key.SetLength((PRUint32)middle); // According to RFC 2980, some will send (none) instead. // So we don't treat this is an error. if (key.CharAt(0) < '0' || key.CharAt(0) > '9') return NS_OK; nsresult code; PRInt32 number = key.ToInteger(&code); if (code != NS_OK) return NS_ERROR_FAILURE; // RFC 2980 specifies one or more spaces. value.Trim(" "); nsCOMPtr <nsIMsgDBHdr> header; nsresult rv = m_newsDB->GetMsgHdrForKey(number, getter_AddRefs(header)); NS_ENSURE_SUCCESS(rv, rv); rv = header->SetStringProperty(m_filterHeaders[m_currentXHDRIndex].get(), value.get()); NS_ENSURE_SUCCESS(rv, rv); PRInt32 totalToDownload = m_lastMsgToDownload - m_firstMsgToDownload + 1; PRInt32 numDownloaded = number - m_firstMsgNumber + 1; PRTime elapsedTime = PR_Now() - m_lastStatusUpdate; if (elapsedTime > MIN_STATUS_UPDATE_INTERVAL) UpdateStatus(true, numDownloaded, totalToDownload); return rv; }
/* static */ nsresult sbURIChecker::CheckDomain( nsACString &aDomain, nsIURI *aSiteURI ) { NS_ENSURE_ARG_POINTER(aSiteURI); LOG(( "sbURIChecker::CheckDomain(%s)", aDomain.BeginReading() )); // get host from URI nsCString host; nsresult rv = aSiteURI->GetHost(host); NS_ENSURE_SUCCESS( rv, rv ); nsCString fixedHost; rv = sbURIChecker::FixupDomain( host, fixedHost ); NS_ENSURE_SUCCESS( rv, rv ); host.Assign(fixedHost); if ( !aDomain.IsEmpty() ) { LOG(("sbURIChecker::CheckDomain() -- Have a domain from the user")); // remove trailing dots, lowercase it nsCString fixedDomain; rv = sbURIChecker::FixupDomain( aDomain, fixedDomain ); NS_ENSURE_SUCCESS( rv, rv ); aDomain.Assign(fixedDomain); // Deal first with numerical ip addresses PRNetAddr addr; if ( PR_StringToNetAddr( host.get(), &addr ) == PR_SUCCESS ) { // numerical ip address LOG(("sbURIChecker::CheckDomain() -- Numerical Address ")); if ( !aDomain.Equals(host) ) { LOG(("sbURIChecker::CheckDomain() -- FAILED ip address check")); return NS_ERROR_FAILURE; } } else { // domain based host, check it against host from URI LOG(("sbURIChecker::CheckDomain() -- Domain based host ")); // make sure the domain wasn't '.com' - it should have a dot in it // we need to skip this check if the host is localhost PRInt32 dot = aDomain.FindChar('.'); if ( dot < 0 && !host.Equals("localhost")) { LOG(("sbURIChecker::CheckDomain() -- FAILED dot test ")); return NS_ERROR_FAILURE; } // prepend a dot so bar.com doesn't match foobar.com but does foo.bar.com aDomain.Insert( NS_LITERAL_CSTRING("."), 0 ); PRInt32 domainLength = aDomain.Length(); PRInt32 lengthDiff = host.Length() - domainLength; if ( lengthDiff == -1 ) { LOG(("sbURIChecker::CheckDomain() -- long domain check")); // special case: from user: .bar.com vs. from URI: bar.com // XXXredfive - I actually think we'll see this most often because // of the prepending of the dot to the user supplied domain if ( !StringEndsWith(aDomain, host) ) { LOG(("sbURIChecker::CheckDomain() -- FAILED long domain check")); return NS_ERROR_FAILURE; } } else if ( lengthDiff == 0 ) { LOG(("sbURIChecker::CheckDomain() -- same length check")); // same length better be the same strings if ( !aDomain.Equals(host) ) { LOG(("sbURIChecker::CheckDomain() -- FAILED same length check")); return NS_ERROR_FAILURE; } } else if ( lengthDiff > 0 ) { LOG(("sbURIChecker::CheckDomain() -- parent domain check")); // normal case URI host is longer that host from user // from user: .bar.com from URI: foo.bar.com if ( !StringEndsWith(host, aDomain) ) { LOG(("sbURIChecker::CheckDomain() -- FAILED parent domain check")); return NS_ERROR_FAILURE; } } else { // domains are WAY off, the user domain is more than 1 char longer than // the URI domain. ie: user: jgaunt.com URI: "" LOG(("sbURIChecker::CheckDomain() -- FAILED, user domain is superset")); return NS_ERROR_FAILURE; } // remove the leading dot we added aDomain.Cut( 0, 1 ); } } else { LOG(( "sbURIChecker::CheckDomain() -- NO domain from the user")); // If the user didn't specify a host // if the URI host is empty, make sure we're file:// if ( host.IsEmpty() ) { PRBool isFileURI; rv = aSiteURI->SchemeIs( "file", &isFileURI ); NS_ENSURE_SUCCESS( rv, rv ); if (!isFileURI) { // non-file URI without a host!!! LOG(("sbURIChecker::CheckDomain() -- FAILED file scheme check")); return NS_ERROR_FAILURE; } // clear the isVoid flag if set aDomain.Truncate(); } else { // no domain from the user but there is a domain from the URI aDomain.Assign(host); } } LOG(("sbURIChecker::CheckDomain() -- PASSED match test")); return NS_OK; }
nsresult nsDefaultURIFixup::ConvertFileToStringURI(const nsACString& aIn, nsCString& aOut) { bool attemptFixup = false; #if defined(XP_WIN) // Check for \ in the url-string or just a drive (PC) if(kNotFound != aIn.FindChar('\\') || (aIn.Length() == 2 && (aIn.Last() == ':' || aIn.Last() == '|'))) { attemptFixup = true; } #elif defined(XP_UNIX) // Check if it starts with / (UNIX) if(aIn.First() == '/') { attemptFixup = true; } #else // Do nothing (All others for now) #endif if (attemptFixup) { // Test if this is a valid path by trying to create a local file // object. The URL of that is returned if successful. // NOTE: Please be sure to check that the call to NS_NewLocalFile // rejects bad file paths when using this code on a new // platform. nsCOMPtr<nsIFile> filePath; nsresult rv; // this is not the real fix but a temporary fix // in order to really fix the problem, we need to change the // nsICmdLineService interface to use wstring to pass paramenters // instead of string since path name and other argument could be // in non ascii.(see bug 87127) Since it is too risky to make interface change right // now, we decide not to do so now. // Therefore, the aIn we receive here maybe already in damage form // (e.g. treat every bytes as ISO-8859-1 and cast up to char16_t // while the real data could be in file system charset ) // we choice the following logic which will work for most of the case. // Case will still failed only if it meet ALL the following condiction: // 1. running on CJK, Russian, or Greek system, and // 2. user type it from URL bar // 3. the file name contains character in the range of // U+00A1-U+00FF but encode as different code point in file // system charset (e.g. ACP on window)- this is very rare case // We should remove this logic and convert to File system charset here // once we change nsICmdLineService to use wstring and ensure // all the Unicode data come in is correctly converted. // XXXbz nsICmdLineService doesn't hand back unicode, so in some cases // what we have is actually a "utf8" version of a "utf16" string that's // actually byte-expanded native-encoding data. Someone upstream needs // to stop using AssignWithConversion and do things correctly. See bug // 58866 for what happens if we remove this // PossiblyByteExpandedFileName check. NS_ConvertUTF8toUTF16 in(aIn); if (PossiblyByteExpandedFileName(in)) { // removes high byte rv = NS_NewNativeLocalFile(NS_LossyConvertUTF16toASCII(in), false, getter_AddRefs(filePath)); } else { // input is unicode rv = NS_NewLocalFile(in, false, getter_AddRefs(filePath)); } if (NS_SUCCEEDED(rv)) { NS_GetURLSpecFromFile(filePath, aOut); return NS_OK; } } return NS_ERROR_FAILURE; }
/* static */ nsresult nsPrincipal::GetOriginForURI(nsIURI* aURI, nsACString& aOrigin) { if (!aURI) { return NS_ERROR_FAILURE; } nsCOMPtr<nsIURI> origin = NS_GetInnermostURI(aURI); if (!origin) { return NS_ERROR_FAILURE; } nsAutoCString hostPort; // chrome: URLs don't have a meaningful origin, so make // sure we just get the full spec for them. // XXX this should be removed in favor of the solution in // bug 160042. bool isChrome; nsresult rv = origin->SchemeIs("chrome", &isChrome); if (NS_SUCCEEDED(rv) && !isChrome) { rv = origin->GetAsciiHostPort(hostPort); // Some implementations return an empty string, treat it as no support // for asciiHost by that implementation. if (hostPort.IsEmpty()) { rv = NS_ERROR_FAILURE; } } // We want the invariant that prinA.origin == prinB.origin i.f.f. // prinA.equals(prinB). However, this requires that we impose certain constraints // on the behavior and origin semantics of principals, and in particular, forbid // creating origin strings for principals whose equality constraints are not // expressible as strings (i.e. object equality). Moreover, we want to forbid URIs // containing the magic "^" we use as a separating character for origin // attributes. // // These constraints can generally be achieved by restricting .origin to // nsIStandardURL-based URIs, but there are a few other URI schemes that we need // to handle. bool isBehaved; if ((NS_SUCCEEDED(origin->SchemeIs("about", &isBehaved)) && isBehaved) || (NS_SUCCEEDED(origin->SchemeIs("moz-safe-about", &isBehaved)) && isBehaved) || (NS_SUCCEEDED(origin->SchemeIs("indexeddb", &isBehaved)) && isBehaved)) { rv = origin->GetAsciiSpec(aOrigin); NS_ENSURE_SUCCESS(rv, rv); // These URIs could technically contain a '^', but they never should. if (NS_WARN_IF(aOrigin.FindChar('^', 0) != -1)) { aOrigin.Truncate(); return NS_ERROR_FAILURE; } return NS_OK; } if (NS_SUCCEEDED(rv) && !isChrome) { rv = origin->GetScheme(aOrigin); NS_ENSURE_SUCCESS(rv, rv); aOrigin.AppendLiteral("://"); aOrigin.Append(hostPort); } else { // If we reached this branch, we can only create an origin if we have a nsIStandardURL. // So, we query to a nsIStandardURL, and fail if we aren't an instance of an nsIStandardURL // nsIStandardURLs have the good property of escaping the '^' character in their specs, // which means that we can be sure that the caret character (which is reserved for delimiting // the end of the spec, and the beginning of the origin attributes) is not present in the // origin string nsCOMPtr<nsIStandardURL> standardURL = do_QueryInterface(origin); NS_ENSURE_TRUE(standardURL, NS_ERROR_FAILURE); rv = origin->GetAsciiSpec(aOrigin); NS_ENSURE_SUCCESS(rv, rv); } return NS_OK; }
void MozMtpDatabase::CreateEntryForFileAndNotify(const nsACString& aPath, DeviceStorageFile* aFile, RefCountedMtpServer* aMtpServer) { // Find the StorageID that this path corresponds to. nsCString remainder; MtpStorageID storageID = FindStorageIDFor(aPath, remainder); if (storageID == 0) { // The path in question isn't for a storage area we're monitoring. nsCString path(aPath); return; } bool exists = false; aFile->mFile->Exists(&exists); if (!exists) { // File doesn't exist, no sense telling MTP about it. // This could happen if Device Storage created and deleted a file right // away. Since the notifications wind up being async, the file might // not exist any more. return; } // Now walk the remaining directories, finding or creating as required. MtpObjectHandle parent = MTP_PARENT_ROOT; bool doFind = true; int32_t offset = aPath.Length() - remainder.Length(); int32_t slash; do { nsDependentCSubstring component; slash = aPath.FindChar('/', offset); if (slash == kNotFound) { component.Rebind(aPath, 0, aPath.Length()); } else { component.Rebind(aPath, 0 , slash); } if (doFind) { MtpObjectHandle entryHandle = FindEntryByPath(component); if (entryHandle != 0) { // We found an entry. parent = entryHandle; offset = slash + 1 ; continue; } } // We've got a directory component that doesn't exist. This means that all // further subdirectories won't exist either, so we can skip searching // for them. doFind = false; // This directory and the file don't exist, create them RefPtr<DbEntry> entry = new DbEntry; entry->mStorageID = storageID; entry->mObjectName = Substring(aPath, offset, slash - offset); entry->mParent = parent; entry->mDisplayName = entry->mObjectName; entry->mPath = component; if (slash == kNotFound) { // No slash - this is the file component entry->mObjectFormat = MTP_FORMAT_DEFINED; int64_t fileSize = 0; aFile->mFile->GetFileSize(&fileSize); entry->mObjectSize = fileSize; // Note: Even though PRTime records usec, GetLastModifiedTime returns // msecs. PRTime dateModifiedMsecs; aFile->mFile->GetLastModifiedTime(&dateModifiedMsecs); entry->mDateModified = dateModifiedMsecs / PR_MSEC_PER_SEC; } else { // Found a slash, this makes this a directory component entry->mObjectFormat = MTP_FORMAT_ASSOCIATION; entry->mObjectSize = 0; time(&entry->mDateModified); } entry->mDateCreated = entry->mDateModified; entry->mDateAdded = entry->mDateModified; AddEntryAndNotify(entry, aMtpServer); MTP_LOG("About to call sendObjectAdded Handle 0x%08x file %s", entry->mHandle, entry->mPath.get()); parent = entry->mHandle; offset = slash + 1; } while (slash != kNotFound); return; }