Quellcodebibliothek nsDirectoryIndexStream.cpp
Interaktion und PortierbarkeitC
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* vim:set sw=2 sts=2 et cin: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/*
The converts a filesystem directory into an "HTTP index" stream per Lou Montulli's original spec:
// NOTE: This runs on the _file transport_ thread. // The problem is that now that we're actually doing something with the data, // we want to do stuff like i18n sorting. However, none of the collation stuff // is threadsafe. // So THIS CODE IS ASCII ONLY!!!!!!!! This is no worse than the current // behaviour, though. See bug 99382.
staticint compare(nsIFile* aElement1, nsIFile* aElement2) { if (!NS_IsNativeUTF8()) { // don't check for errors, because we can't report them anyway
nsAutoString name1, name2;
aElement1->GetLeafName(name1);
aElement2->GetLeafName(name2);
// Note - we should do the collation to do sorting. Why don't we? // Because that is _slow_. Using TestProtocols to list file:///dev/ // goes from 3 seconds to 22. (This may be why nsXULSortService is // so slow as well). // Does this have bad effects? Probably, but since nsXULTree appears // to use the raw RDF literal value as the sort key (which ammounts to an // strcmp), it won't be any worse, I think. // This could be made faster, by creating the keys once, // but CompareString could still be smarter - see bug 99383 - bbaetz // NB - 99393 has been WONTFIXed. So if the I18N code is ever made // threadsafe so that this matters, we'd have to pass through a // struct { nsIFile*, uint8_t* } with the pre-calculated key. return Compare(name1, name2);
}
nsresult nsDirectoryIndexStream::Init(nsIFile* aDir) {
nsresult rv; bool isDir;
rv = aDir->IsDirectory(&isDir); if (NS_FAILED(rv)) return rv;
MOZ_ASSERT(isDir, "not a directory"); if (!isDir) return NS_ERROR_ILLEGAL_VALUE;
if (MOZ_LOG_TEST(gLog, LogLevel::Debug)) {
MOZ_LOG(gLog, LogLevel::Debug,
("nsDirectoryIndexStream[%p]: initialized on %s", this,
aDir->HumanReadablePath().get()));
}
// Sigh. We have to allocate on the heap because there are no // assignment operators defined.
nsCOMPtr<nsIDirectoryEnumerator> iter;
rv = aDir->GetDirectoryEntries(getter_AddRefs(iter)); if (NS_FAILED(rv)) return rv;
// Now lets sort, because clients expect it that way // XXX - should we do so here, or when the first item is requested? // XXX - use insertion sort instead?
nsresult nsDirectoryIndexStream::Create(nsIFile* aDir,
nsIInputStream** aResult) {
RefPtr<nsDirectoryIndexStream> result = new nsDirectoryIndexStream(); if (!result) return NS_ERROR_OUT_OF_MEMORY;
nsresult rv = result->Init(aDir); if (NS_FAILED(rv)) { return rv;
}
// If anything is enqueued (or left-over) in mBuf, then feed it to // the reader first. while (mOffset < (int32_t)mBuf.Length() && aCount != 0) {
*(aBuf++) = char(mBuf.CharAt(mOffset++));
--aCount;
++nread;
}
// Okay, now we'll suck stuff off of our iterator into the mBuf... while (uint32_t(mBuf.Length()) < aCount) { bool more = mPos < mArray.Count(); if (!more) break;
// don't addref, for speed - an addref happened when it // was placed in the array, so it's not going to go stale
nsIFile* current = mArray.ObjectAt(mPos);
++mPos;
// The "content-length" field
mBuf.AppendInt(fileSize, 10);
mBuf.Append(' ');
// The "last-modified" field
PRExplodedTime tm;
PR_ExplodeTime(fileInfoModifyTime, PR_GMTParameters, &tm);
{ char buf[64];
PR_FormatTimeUSEnglish(
buf, sizeof(buf), "%a,%%20%d%%20%b%%20%Y%%20%H:%M:%S%%20GMT ", &tm);
mBuf.Append(buf);
}
// The "file-type" field bool isFile = true;
current->IsFile(&isFile); if (isFile) {
mBuf.AppendLiteral("FILE ");
} else { bool isDir;
rv = current->IsDirectory(&isDir); if (NS_FAILED(rv)) return rv; if (isDir) {
mBuf.AppendLiteral("DIRECTORY ");
} else { bool isLink;
rv = current->IsSymlink(&isLink); if (NS_FAILED(rv)) return rv; if (isLink) {
mBuf.AppendLiteral("SYMBOLIC-LINK ");
}
}
}
mBuf.Append('\n');
}
// ...and once we've either run out of directory entries, or // filled up the buffer, then we'll push it to the reader. while (mOffset < (int32_t)mBuf.Length() && aCount != 0) {
*(aBuf++) = char(mBuf.CharAt(mOffset++));
--aCount;
++nread;
}
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.