adding chrome url parsing stuff to the lite chrome registry, minor tweaks to the embed lite module.

not part of build


git-svn-id: svn://10.0.0.236/trunk@135942 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
alecf%netscape.com
2003-01-07 21:37:30 +00:00
parent 41c6e98c5f
commit df1557b64e
8 changed files with 943 additions and 116 deletions

View File

@@ -25,24 +25,39 @@ VPATH = @srcdir@
MODULE = embed_lite
LIBRARY_NAME = embed_lite
IS_COMPONENT = 1
include $(DEPTH)/config/autoconf.mk
REQUIRES = xpcom \
string \
chrome \
appshell \
necko \
history \
pref \
content \
caps \
xpconnect \
js \
xuldoc \
$(NULL)
CPPSRCS = \
nsEmbedChromeRegistry.cpp \
nsEmbedWindowMediator.cpp \
nsEmbedGlobalHistory.cpp \
nsEmbedLiteModule.cpp \
$(NULL)
# bring in the chrome protocol handler
LOBJS = $(topsrcdir)/rdf/chrome/src/nsChromeProtocolHandler.$(OBJ_SUFFIX)
LOCAL_INCLUDES = -I$(DEPTH)/rdf/chrome/src
EXTRA_DSO_LDOPTS = \
$(MOZ_COMPONENT_LIBS) \
$(NULL)
NO_DIST_INSTALL = 1
include $(topsrcdir)/config/rules.mk

View File

@@ -39,6 +39,120 @@
#include "nsEmbedChromeRegistry.h"
#include "nsString.h"
#include "nsReadableUtils.h"
#include "plstr.h"
#include "nsIDirectoryService.h"
#include "nsAppDirectoryServiceDefs.h"
#include "nsIProperties.h"
#include "nsILocalFile.h"
#define CHROME_TYPE_CONTENT 0
#define CHROME_TYPE_LOCALE 1
#define CHROME_TYPE_SKIN 2
const char kChromePrefix[] = "chrome://";
static nsresult
SplitURL(nsIURI *aChromeURI, nsCString& aPackage, nsCString& aProvider, nsCString& aFile,
PRBool *aModified = nsnull)
{
// Splits a "chrome:" URL into its package, provider, and file parts.
// Here are the current portions of a
// chrome: url that make up the chrome-
//
// chrome://global/skin/foo?bar
// \------/ \----/\---/ \-----/
// | | | |
// | | | `-- RemainingPortion
// | | |
// | | `-- Provider
// | |
// | `-- Package
// |
// `-- Always "chrome://"
//
//
nsresult rv;
nsCAutoString str;
rv = aChromeURI->GetSpec(str);
if (NS_FAILED(rv)) return rv;
// We only want to deal with "chrome:" URLs here. We could return
// an error code if the URL isn't properly prefixed here...
if (PL_strncmp(str.get(), kChromePrefix, sizeof(kChromePrefix) - 1) != 0)
return NS_ERROR_INVALID_ARG;
// Cull out the "package" string; e.g., "navigator"
aPackage = str.get() + sizeof(kChromePrefix) - 1;
PRInt32 idx;
idx = aPackage.FindChar('/');
if (idx < 0)
return NS_OK;
// Cull out the "provider" string; e.g., "content"
aPackage.Right(aProvider, aPackage.Length() - (idx + 1));
aPackage.Truncate(idx);
idx = aProvider.FindChar('/');
if (idx < 0) {
// Force the provider to end with a '/'
idx = aProvider.Length();
aProvider.Append('/');
}
// Cull out the "file"; e.g., "navigator.xul"
aProvider.Right(aFile, aProvider.Length() - (idx + 1));
aProvider.Truncate(idx);
PRBool nofile = (aFile.Length() == 0);
if (nofile) {
// If there is no file, then construct the default file
aFile = aPackage;
if (aProvider.Equals("content")) {
aFile += ".xul";
}
else if (aProvider.Equals("skin")) {
aFile += ".css";
}
else if (aProvider.Equals("locale")) {
aFile += ".dtd";
}
else {
NS_ERROR("unknown provider");
return NS_ERROR_FAILURE;
}
} else {
// Protect against URIs containing .. that reach up out of the
// chrome directory to grant chrome privileges to non-chrome files.
int depth = 0;
PRBool sawSlash = PR_TRUE; // .. at the beginning is suspect as well as /..
for (const char* p=aFile.get(); *p; p++) {
if (sawSlash) {
if (p[0] == '.' && p[1] == '.'){
depth--; // we have /.., decrement depth.
} else {
static const char escape[] = "%2E%2E";
if (PL_strncasecmp(p, escape, sizeof(escape)-1) == 0)
depth--; // we have the HTML-escaped form of /.., decrement depth.
}
} else if (p[0] != '/') {
depth++; // we have /x for some x that is not /
}
sawSlash = (p[0] == '/');
if (depth < 0) {
return NS_ERROR_FAILURE;
}
}
}
if (aModified)
*aModified = nofile;
return NS_OK;
}
NS_IMPL_ISUPPORTS1(nsEmbedChromeRegistry, nsIChromeRegistry)
@@ -50,11 +164,145 @@ nsEmbedChromeRegistry::nsEmbedChromeRegistry()
nsresult
nsEmbedChromeRegistry::Init()
{
NS_ASSERTION(0, "Creating embedding chrome registry\n");
nsresult rv;
rv = NS_NewISupportsArray(getter_AddRefs(mEmptyArray));
if (NS_FAILED(rv)) return rv;
rv = ReadChromeRegistry();
if (NS_FAILED(rv)) return rv;
return NS_OK;
}
nsresult
nsEmbedChromeRegistry::ReadChromeRegistry()
{
nsresult rv;
nsCOMPtr<nsIProperties> directoryService =
do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID, &rv);
if (NS_FAILED(rv)) return rv;
nsCOMPtr<nsILocalFile> listFile;
rv = directoryService->Get(NS_APP_CHROME_DIR, NS_GET_IID(nsILocalFile),
getter_AddRefs(listFile));
if (NS_FAILED(rv)) return rv;
rv = listFile->AppendRelativeNativePath(NS_LITERAL_CSTRING("installed-chrome.txt"));
if (NS_FAILED(rv)) return rv;
PRFileDesc *file;
rv = listFile->OpenNSPRFileDesc(PR_RDONLY, 0, &file);
if (NS_FAILED(rv)) return rv;
PRFileInfo finfo;
if (PR_GetOpenFileInfo(file, &finfo) == PR_SUCCESS) {
char *dataBuffer = new char[finfo.size+1];
if (dataBuffer) {
PRInt32 bufferSize = PR_Read(file, dataBuffer, finfo.size);
if (bufferSize > 0) {
dataBuffer[bufferSize] = '\r';
rv = ProcessNewChromeBuffer(dataBuffer, bufferSize);
}
delete [] dataBuffer;
}
}
PR_Close(file);
return rv;
}
nsresult
nsEmbedChromeRegistry::ProcessNewChromeBuffer(char* aBuffer, PRInt32 aLength)
{
nsresult rv = NS_OK;
while (aLength > 0) {
PRInt32 processedBytes = ProcessChromeLine(aBuffer, aLength);
aBuffer += processedBytes;
aLength -= processedBytes;
}
return NS_OK;
}
#define MAX_TOKENS 5
struct chromeToken {
const char *tokenStart;
const char *tokenEnd;
};
PRInt32
nsEmbedChromeRegistry::ProcessChromeLine(const char* aBuffer, PRInt32 aLength)
{
PRInt32 bytesProcessed = 0;
chromeToken tokens[MAX_TOKENS];
PRInt32 tokenCount = 0;
PRBool expectingToken = PR_TRUE;
while (bytesProcessed <= aLength &&
*aBuffer != '\n' && *aBuffer != '\r' &&
tokenCount < MAX_TOKENS) {
if (*aBuffer == ',') {
tokenCount++;
expectingToken = PR_TRUE;
}
else if (expectingToken)
tokens[tokenCount].tokenStart = aBuffer;
else
tokens[tokenCount].tokenEnd = aBuffer;
aBuffer++;
bytesProcessed++;
}
NS_ASSERTION(tokenCount == 4, "Unexpected tokens in line");
nsDependentSingleFragmentCSubstring
chromeType(tokens[0].tokenStart, tokens[0].tokenEnd);
nsDependentSingleFragmentCSubstring
chromeProfile(tokens[1].tokenStart, tokens[1].tokenEnd);
nsDependentSingleFragmentCSubstring
chromeLocType(tokens[2].tokenStart, tokens[2].tokenEnd);
nsDependentSingleFragmentCSubstring
chromeLocation(tokens[3].tokenStart, tokens[3].tokenEnd);
RegisterChrome(chromeType, chromeProfile, chromeLocType, chromeLocation);
return bytesProcessed;
}
nsresult
nsEmbedChromeRegistry::RegisterChrome(const nsACString& aChromeType,
const nsACString& aChromeProfile,
const nsACString& aChromeLocType,
const nsACString& aChromeLocation)
{
PRInt32 chromeType;
if (aChromeType.Equals(NS_LITERAL_CSTRING("skin")))
chromeType = CHROME_TYPE_SKIN;
else if (aChromeType.Equals(NS_LITERAL_CSTRING("locale")))
chromeType = CHROME_TYPE_LOCALE;
else
chromeType = CHROME_TYPE_CONTENT;
PRBool chromeIsProfile =
aChromeProfile.Equals(NS_LITERAL_CSTRING("profile"));
PRBool chromeIsURL =
aChromeProfile.Equals(NS_LITERAL_CSTRING("url"));
return RegisterChrome(chromeType, chromeIsProfile, chromeIsURL,
aChromeLocation);
}
nsresult
nsEmbedChromeRegistry::RegisterChrome(PRInt32 aChromeType, // CHROME_TYPE_CONTENT, etc
PRBool aChromeIsProfile, // per-profile?
PRBool aChromeIsURL, // is it a url? (else path)
const nsACString& aChromeLocation)
{
return NS_OK;
}
@@ -68,7 +316,7 @@ nsEmbedChromeRegistry::CheckForNewChrome()
NS_IMETHODIMP
nsEmbedChromeRegistry::Canonify(nsIURI* aChromeURI)
{
#if 0
#if 1
// Canonicalize 'chrome:' URLs. We'll take any 'chrome:' URL
// without a filename, and change it to a URL -with- a filename;
// e.g., "chrome://navigator/content" to

View File

@@ -55,6 +55,20 @@ public:
NS_DECL_ISUPPORTS
NS_DECL_NSICHROMEREGISTRY
nsresult ReadChromeRegistry();
nsresult ProcessNewChromeBuffer(char* aBuffer, PRInt32 aLength);
PRInt32 ProcessChromeLine(const char* aBuffer, PRInt32 aLength);
nsresult RegisterChrome(const nsACString& aChromeType,
const nsACString& aChromeProfile,
const nsACString& aChromeLocType,
const nsACString& aChromeLocation);
nsresult RegisterChrome(PRInt32 aChromeType, // CHROME_TYPE_CONTENT, etc
PRBool aChromeIsProfile, // per-profile?
PRBool aChromeIsURL, // is it a url? (else path)
const nsACString& aChromeLocation);
private:
nsCOMPtr<nsISupportsArray> mEmptyArray;

View File

@@ -0,0 +1,553 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Netscape Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Conrad Carlen <ccarlen@netscape.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the NPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the NPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "nsEmbedGlobalHistory.h"
#include "nsIObserver.h"
#include "nsIObserverService.h"
#include "nsWeakReference.h"
#include "nsAppDirectoryServiceDefs.h"
#include "nsHashTable.h"
#include "nsInt64.h"
#include "prtypes.h"
#include "nsFixedSizeAllocator.h"
#include "nsVoidArray.h"
#include "nsIPrefService.h"
// Constants
static const PRInt32 kNewEntriesBetweenFlush = 10;
static const PRUint32 kDefaultExpirationIntervalDays = 7;
static const PRInt64 kMSecsPerDay = LL_INIT(0, 60 * 60 * 24 * 1000);
static const PRInt64 kOneThousand = LL_INIT(0, 1000);
#define PREF_BROWSER_HISTORY_EXPIRE_DAYS "browser.history_expire_days"
// Static Routine Prototypes
static nsresult readEntry(FILE *inStream, nsCString& url, HistoryEntry **entry);
static nsresult writeEntry(FILE *outStm, nsCStringKey *url, HistoryEntry *entry);
static PRIntn enumWriteEntry(nsHashKey *aKey, void *aData, void* closure);
static PRIntn enumWriteEntryIfUnwritten(nsHashKey *aKey, void *aData, void* closure);
static PRIntn enumDeleteEntry(nsHashKey *aKey, void *aData, void* closure);
//*****************************************************************************
// HistoryEntry
//*****************************************************************************
class HistoryEntry {
public:
HistoryEntry() :
mWritten(PR_FALSE) {}
void OnVisited()
{
mLastVisitTime = PR_Now();
LL_DIV(mLastVisitTime, mLastVisitTime, kOneThousand);
}
PRInt64 GetLastVisitTime()
{ return mLastVisitTime; }
void SetLastVisitTime(const PRInt64& aTime)
{ mLastVisitTime = aTime; }
PRBool GetIsWritten()
{ return mWritten; }
void SetIsWritten(PRBool written = PR_TRUE)
{ mWritten = PR_TRUE; }
// Memory management stuff
static void* operator new(size_t size);
static void operator delete(void *p, size_t size);
// Must be called when done with all HistoryEntry objects
static void ReleasePool();
private:
PRInt64 mLastVisitTime; // Millisecs
PRPackedBool mWritten; // TRUE if ever persisted
static nsresult InitPool();
static nsFixedSizeAllocator *sPool;
};
nsFixedSizeAllocator *HistoryEntry::sPool;
//*****************************************************************************
void* HistoryEntry::operator new(size_t size)
{
if (size != sizeof(HistoryEntry))
return ::operator new(size);
if (!sPool && NS_FAILED(InitPool()))
return nsnull;
return sPool->Alloc(size);
}
void HistoryEntry::operator delete(void *p, size_t size)
{
if (!p)
return;
if (size != sizeof(HistoryEntry))
::operator delete(p);
if (!sPool) {
NS_ERROR("HistoryEntry outlived its memory pool");
return;
}
sPool->Free(p, size);
}
nsresult HistoryEntry::InitPool()
{
if (!sPool) {
sPool = new nsFixedSizeAllocator;
if (!sPool)
return NS_ERROR_OUT_OF_MEMORY;
static const size_t kBucketSizes[] =
{ sizeof(HistoryEntry) };
static const PRInt32 kInitialPoolSize =
NS_SIZE_IN_HEAP(sizeof(HistoryEntry)) * 256;
nsresult rv = sPool->Init("EmbedLite HistoryEntry Pool", kBucketSizes, 1, kInitialPoolSize);
if (NS_FAILED(rv))
return rv;
}
return NS_OK;
}
void HistoryEntry::ReleasePool()
{
delete sPool;
sPool = nsnull;
}
//*****************************************************************************
// nsEmbedGlobalHistory - Creation/Destruction
//*****************************************************************************
NS_IMPL_ISUPPORTS3(nsEmbedGlobalHistory, nsIGlobalHistory, nsIObserver, nsISupportsWeakReference)
nsEmbedGlobalHistory::nsEmbedGlobalHistory() :
mDataIsLoaded(PR_FALSE), mEntriesAddedSinceFlush(0),
mURLTable(nsnull)
{
NS_INIT_REFCNT();
LL_I2L(mExpirationInterval, kDefaultExpirationIntervalDays);
LL_MUL(mExpirationInterval, mExpirationInterval, kMSecsPerDay);
}
nsEmbedGlobalHistory::~nsEmbedGlobalHistory()
{
FlushData();
delete mURLTable;
HistoryEntry::ReleasePool();
}
NS_IMETHODIMP nsEmbedGlobalHistory::Init()
{
mURLTable = new nsHashtable;
NS_ENSURE_TRUE(mURLTable, NS_ERROR_OUT_OF_MEMORY);
// Get Pref and convert to millisecs
nsCOMPtr<nsIPrefBranch> prefs(do_GetService("@mozilla.org/preferences-service;1"));
if (prefs) {
PRInt32 expireDays;
prefs->GetIntPref(PREF_BROWSER_HISTORY_EXPIRE_DAYS, &expireDays);
LL_I2L(mExpirationInterval, expireDays);
LL_MUL(mExpirationInterval, mExpirationInterval, kMSecsPerDay);
}
// register to observe profile changes
nsCOMPtr<nsIObserverService> observerService =
do_GetService("@mozilla.org/observer-service;1");
NS_ASSERTION(observerService, "failed to get observer service");
if (observerService)
observerService->AddObserver(this, "profile-before-change", PR_TRUE);
return NS_OK;
}
//*****************************************************************************
// nsEmbedGlobalHistory::nsIGlobalHistory
//*****************************************************************************
NS_IMETHODIMP nsEmbedGlobalHistory::AddPage(const char *aURL)
{
NS_ENSURE_ARG(aURL);
nsresult rv = LoadData();
NS_ENSURE_SUCCESS(rv, rv);
nsCStringKey asKey(aURL);
HistoryEntry *entry = NS_STATIC_CAST(HistoryEntry *, mURLTable->Get(&asKey));
if (!entry) {
if (++mEntriesAddedSinceFlush >= kNewEntriesBetweenFlush)
FlushData(kFlushModeAppend);
HistoryEntry *newEntry = new HistoryEntry;
if (!newEntry)
return NS_ERROR_FAILURE;
(void)mURLTable->Put(&asKey, newEntry);
entry = newEntry;
}
entry->OnVisited();
return NS_OK;
}
NS_IMETHODIMP nsEmbedGlobalHistory::IsVisited(const char *aURL, PRBool *_retval)
{
NS_ENSURE_ARG(aURL);
NS_ENSURE_ARG_POINTER(_retval);
nsresult rv = LoadData();
NS_ENSURE_SUCCESS(rv, rv);
nsCStringKey asKey(aURL);
*_retval = (mURLTable->Exists(&asKey));
return NS_OK;
}
//*****************************************************************************
// nsEmbedGlobalHistory::nsIObserver
//*****************************************************************************
NS_IMETHODIMP nsEmbedGlobalHistory::Observe(nsISupports *aSubject, const char *aTopic, const PRUnichar *aData)
{
nsresult rv = NS_OK;
if (strcmp(aTopic, "profile-before-change") == 0) {
(void)FlushData();
(void)ResetData();
}
return rv;
}
//*****************************************************************************
// nsEmbedGlobalHistory
//*****************************************************************************
nsresult nsEmbedGlobalHistory::LoadData()
{
if (!mDataIsLoaded) {
nsresult rv;
PRBool exists;
mDataIsLoaded = PR_TRUE;
rv = GetHistoryFile();
if (NS_FAILED(rv))
return rv;
rv = mHistoryFile->Exists(&exists);
if (NS_FAILED(rv))
return rv;
if (!exists)
return NS_OK;
FILE *stdFile;
rv = mHistoryFile->OpenANSIFileDesc("r", &stdFile);
if (NS_FAILED(rv))
return rv;
nsCAutoString outString;
HistoryEntry *newEntry;
while (NS_SUCCEEDED(readEntry(stdFile, outString, &newEntry))) {
if (EntryHasExpired(newEntry)) {
delete newEntry;
}
else {
nsCStringKey asKey(outString);
mURLTable->Put(&asKey, newEntry);
}
}
fclose(stdFile);
}
return NS_OK;
}
nsresult nsEmbedGlobalHistory::FlushData(PRIntn mode)
{
if (mHistoryFile) {
const char* openMode = (mode == kFlushModeAppend ? "a" : "w");
FILE *stdFile;
nsresult rv = mHistoryFile->OpenANSIFileDesc(openMode, &stdFile);
if (NS_FAILED(rv)) return rv;
// Before flushing either way, remove dead entries
mURLTable->Enumerate(enumRemoveEntryIfExpired, this);
if (mode == kFlushModeAppend)
mURLTable->Enumerate(enumWriteEntryIfUnwritten, stdFile);
else
mURLTable->Enumerate(enumWriteEntry, stdFile);
mEntriesAddedSinceFlush = 0;
fclose(stdFile);
}
return NS_OK;
}
nsresult nsEmbedGlobalHistory::ResetData()
{
mURLTable->Reset(enumDeleteEntry);
mHistoryFile = 0;
mDataIsLoaded = PR_FALSE;
mEntriesAddedSinceFlush = 0;
return NS_OK;
}
nsresult nsEmbedGlobalHistory::GetHistoryFile()
{
nsresult rv;
// Get the history file in our profile dir.
// Notice we are not just getting NS_APP_HISTORY_50_FILE
// because it is used by the "real" global history component.
nsCOMPtr<nsIFile> aFile;
rv = NS_GetSpecialDirectory(NS_APP_USER_PROFILE_50_DIR, getter_AddRefs(aFile));
NS_ENSURE_SUCCESS(rv, rv);
rv = aFile->Append(NS_LITERAL_STRING("history.txt"));
NS_ENSURE_SUCCESS(rv, rv);
mHistoryFile = do_QueryInterface(aFile);
return NS_OK;
}
PRBool nsEmbedGlobalHistory::EntryHasExpired(HistoryEntry *entry)
{
// convert "now" from microsecs to millisecs
PRInt64 nowInMilliSecs = PR_Now();
LL_DIV(nowInMilliSecs, nowInMilliSecs, kOneThousand);
// determine when the entry would have expired
PRInt64 expirationIntervalAgo;
LL_SUB(expirationIntervalAgo, nowInMilliSecs, mExpirationInterval);
PRInt64 lastVisitTime = entry->GetLastVisitTime();
return (LL_CMP(lastVisitTime, <, expirationIntervalAgo));
}
PRIntn nsEmbedGlobalHistory::enumRemoveEntryIfExpired(nsHashKey *aKey, void *aData, void* closure)
{
HistoryEntry *entry = NS_STATIC_CAST(HistoryEntry*, aData);
if (!entry)
return PR_FALSE;
nsEmbedGlobalHistory *history = NS_STATIC_CAST(nsEmbedGlobalHistory*, closure);
if (!history)
return PR_FALSE;
if (history->EntryHasExpired(entry)) {
// what do do here?
//delete entry;
return PR_TRUE;
}
return PR_TRUE;
}
//*****************************************************************************
// Static Functions
//*****************************************************************************
static nsresult parsePRInt64(FILE *inStm, PRInt64& outValue)
{
int c, charsRead = 0;
nsInt64 value = 0;
while (PR_TRUE) {
c = fgetc(inStm);
if (c == EOF || !isdigit(c))
break;
++charsRead;
PRInt32 digit = c - '0';
value *= nsInt64(10);
value += nsInt64(digit);
}
if (!charsRead)
return NS_ERROR_FAILURE;
outValue = value;
return NS_OK;
}
nsresult readEntry(FILE *inStream, nsCString& outURL, HistoryEntry **outEntry)
{
nsresult rv;
// Get the last visted date
PRInt64 value;
rv = parsePRInt64(inStream, value);
if (NS_FAILED(rv))
return rv;
// Get the URL
int c;
char buf[1024];
char *next, *end = buf + sizeof(buf);
outURL.Truncate(0);
next = buf;
while (PR_TRUE) {
c = fgetc(inStream);
if (c == EOF)
break;
else if (c == '\n')
break;
else if (c == '\r') {
c = fgetc(inStream);
if (c != '\n')
ungetc(c, inStream);
break;
}
else {
*next++ = c;
if (next >= end) {
outURL.Append(buf, next - buf);
next = buf;
}
}
}
if (next > buf)
outURL.Append(buf, next - buf);
if (!outURL.Length() && c == EOF)
return NS_ERROR_FAILURE;
*outEntry = new HistoryEntry;
if (!*outEntry)
return NS_ERROR_OUT_OF_MEMORY;
(*outEntry)->SetLastVisitTime(value);
(*outEntry)->SetIsWritten();
return NS_OK;
}
static nsresult writePRInt64(FILE *outStm, const PRInt64& inValue)
{
nsInt64 value(inValue);
if (value == nsInt64(0)) {
fputc('0', outStm);
return NS_OK;
}
nsCAutoString tempString;
while (value != nsInt64(0)) {
PRInt32 ones = PRInt32(value % nsInt64(10));
value /= nsInt64(10);
tempString.Insert(char('0' + ones), 0);
}
int result = fputs(tempString.get(), outStm);
return (result == EOF) ? NS_ERROR_FAILURE : NS_OK;
}
nsresult writeEntry(FILE *outStm, nsCStringKey *url, HistoryEntry *entry)
{
writePRInt64(outStm, entry->GetLastVisitTime());
fputc(':', outStm);
fputs(url->GetString(), outStm);
entry->SetIsWritten();
#if defined (XP_PC)
fputc('\r', outStm);
fputc('\n', outStm);
#elif defined(XP_UNIX)
fputc('\n', outStm);
#else
fputc('\r', outStm);
#endif
return NS_OK;
}
PRBool enumWriteEntry(nsHashKey *aKey, void *aData, void* closure)
{
FILE *outStm = NS_STATIC_CAST(FILE*, closure);
if (!outStm)
return PR_FALSE;
nsCStringKey *stringKey = NS_STATIC_CAST(nsCStringKey*, aKey);
if (!stringKey)
return PR_FALSE;
HistoryEntry *entry = NS_STATIC_CAST(HistoryEntry*, aData);
if (!entry)
return PR_FALSE;
nsresult rv = writeEntry(outStm, stringKey, entry);
return NS_SUCCEEDED(rv) ? PR_TRUE : PR_FALSE;
}
PRBool enumWriteEntryIfUnwritten(nsHashKey *aKey, void *aData, void* closure)
{
FILE *outStm = NS_STATIC_CAST(FILE*, closure);
if (!outStm)
return PR_FALSE;
nsCStringKey *stringKey = NS_STATIC_CAST(nsCStringKey*, aKey);
if (!stringKey)
return PR_FALSE;
HistoryEntry *entry = NS_STATIC_CAST(HistoryEntry*, aData);
if (!entry)
return PR_FALSE;
nsresult rv;
if (!entry->GetIsWritten())
rv = writeEntry(outStm, stringKey, entry);
return NS_SUCCEEDED(rv) ? PR_TRUE : PR_FALSE;
}
PRIntn enumDeleteEntry(nsHashKey *aKey, void *aData, void* closure)
{
HistoryEntry *entry = NS_STATIC_CAST(HistoryEntry*, aData);
delete entry;
return PR_TRUE;
}

View File

@@ -0,0 +1,96 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Netscape Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Conrad Carlen <ccarlen@netscape.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the NPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the NPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifndef __nsEmbedGlobalHistory_h__
#define __nsEmbedGlobalHistory_h__
#include "nsIGlobalHistory.h"
#include "nsIObserver.h"
#include "nsWeakReference.h"
#include "nsILocalFile.h"
#include "nsString.h"
class nsHashtable;
class nsHashKey;
class nsCStringKey;
class HistoryEntry;
//*****************************************************************************
// nsEmbedGlobalHistory
//*****************************************************************************
// {2f977d51-5485-11d4-87e2-0010a4e75ef2}
#define NS_EMBEDGLOBALHISTORY_CID \
{ 0x2f977d51, 0x5485, 0x11d4, \
{ 0x87, 0xe2, 0x00, 0x10, 0xa4, 0xe7, 0x5e, 0xf2 } }
class nsEmbedGlobalHistory: public nsIGlobalHistory,
public nsIObserver,
public nsSupportsWeakReference
{
public:
nsEmbedGlobalHistory();
virtual ~nsEmbedGlobalHistory();
NS_IMETHOD Init();
NS_DECL_ISUPPORTS
NS_DECL_NSIGLOBALHISTORY
NS_DECL_NSIOBSERVER
protected:
enum { kFlushModeAppend, kFlushModeFullWrite };
nsresult LoadData();
nsresult FlushData(PRIntn mode = kFlushModeFullWrite);
nsresult ResetData();
nsresult GetHistoryFile();
PRBool EntryHasExpired(HistoryEntry *entry);
static PRIntn enumRemoveEntryIfExpired(nsHashKey *aKey, void *aData, void* closure);
protected:
PRBool mDataIsLoaded;
PRUint32 mEntriesAddedSinceFlush;
nsCOMPtr<nsILocalFile> mHistoryFile;
nsHashtable *mURLTable;
PRInt64 mExpirationInterval;
};
#endif

View File

@@ -39,23 +39,31 @@
#include "nsIGenericFactory.h"
#include "nsEmbedChromeRegistry.h"
#include "nsEmbedWindowMediator.h"
#include "nsEmbedGlobalHistory.h"
#include "nsChromeProtocolHandler.h"
NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsEmbedChromeRegistry, Init)
NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsEmbedWindowMediator, Init)
NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsEmbedGlobalHistory, Init)
static const nsModuleComponentInfo components[] =
{
#if 1 // Don't hook up until implementation is finished
{ "Chrome Registry",
NS_EMBEDCHROMEREGISTRY_CID,
"@mozilla.org/chrome/chrome-registry;1",
nsEmbedChromeRegistryConstructor,
},
{ "Window mediator",
NS_EMBEDWINDOWMEDIATOR_CID,
NS_WINDOWMEDIATOR_CONTRACTID,
nsEmbedWindowMediatorConstructor,
#endif
{ "Global History",
NS_EMBEDGLOBALHISTORY_CID,
"@mozilla.org/browser/global-history;1",
nsEmbedGlobalHistoryConstructor,
},
{ "Chrome Protocol Handler",
NS_CHROMEPROTOCOLHANDLER_CID,
NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX "chrome",
nsChromeProtocolHandler::Create
}
};
NS_IMPL_NSGETMODULE("EmbedLite components", components);

View File

@@ -1,48 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Netscape Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 2001
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the NPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the NPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "nsIFactory.h"
#include "nsEmbedWindowMediator.h"
NS_IMPL_ISUPPORTS1(nsEmbedWindowMediator, nsIWindowMediator)
nsresult
nsEmbedWindowMediator::Init()
{
return NS_OK;
}

View File

@@ -1,59 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Netscape Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 2001
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the NPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the NPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "nsIWindowMediator.h"
// {486E344C-F33A-45f6-B4B3-A55B7F67AE89}
#define NS_EMBEDWINDOWMEDIATOR_CID \
{ 0x486e344c, 0xf33a, 0x45f6, \
{ 0xb4, 0xb3, 0xa5, 0x5b, 0x7f, 0x67, 0xae, 0x89 } }
class nsEmbedWindowMediator : public nsIWindowMediator
{
public:
nsEmbedWindowMediator() { NS_INIT_ISUPPORTS(); }
virtual ~nsEmbedWindowMediator() {}
nsresult Init();
NS_DECL_ISUPPORTS
NS_DECL_NSIWINDOWMEDIATOR
};