зеркало из https://github.com/mozilla/pjs.git
ix 109739, removed nsIRegistry and switched to flat file support for caching plugins info, r=av, sr=dveditz
This commit is contained in:
Родитель
ec04bf62ce
Коммит
f385095175
|
@ -93,7 +93,7 @@
|
|||
#undef None
|
||||
#endif
|
||||
|
||||
#include "nsIRegistry.h"
|
||||
//#include "nsIRegistry.h"
|
||||
#include "nsEnumeratorUtils.h"
|
||||
#include "nsISupportsPrimitives.h"
|
||||
// for the dialog
|
||||
|
@ -149,6 +149,7 @@
|
|||
#include "nsPluginError.h"
|
||||
|
||||
#include "nsUnicharUtils.h"
|
||||
#include "nsPluginManifestLineReader.h"
|
||||
|
||||
#include "imgILoader.h"
|
||||
#include "nsDefaultPlugin.h"
|
||||
|
@ -190,8 +191,9 @@
|
|||
// 0.03 changed name, description and mime desc from string to bytes, bug 108246
|
||||
// 0.04 added new mime entry point on Mac, bug 113464
|
||||
// 0.05 added new entry point check for the default plugin, bug 132430
|
||||
// 0.06 strip off suffixes in mime description strings, bug 53895
|
||||
static const char *kPluginInfoVersion = "0.06";
|
||||
// 0.06 strip off suffixes in mime description strings, bug 53895
|
||||
// 0.07 changed nsIRegistry to flat file support for caching plugins info
|
||||
static const char *kPluginInfoVersion = "0.07";
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// CID's && IID's
|
||||
static NS_DEFINE_IID(kIPluginInstanceIID, NS_IPLUGININSTANCE_IID);
|
||||
|
@ -210,7 +212,6 @@ static NS_DEFINE_CID(kIHttpHeaderVisitorIID, NS_IHTTPHEADERVISITOR_IID);
|
|||
static NS_DEFINE_CID(kStreamConverterServiceCID, NS_STREAMCONVERTERSERVICE_CID);
|
||||
static NS_DEFINE_IID(kIFileUtilitiesIID, NS_IFILEUTILITIES_IID);
|
||||
static NS_DEFINE_IID(kIOutputStreamIID, NS_IOUTPUTSTREAM_IID);
|
||||
static NS_DEFINE_CID(kRegistryCID, NS_REGISTRY_CID);
|
||||
static const char kDirectoryServiceContractID[] = "@mozilla.org/file/directory_service;1";
|
||||
// for the dialog
|
||||
static NS_DEFINE_IID(kStringBundleServiceCID, NS_STRINGBUNDLESERVICE_CID);
|
||||
|
@ -232,6 +233,8 @@ static const char kPluginsMimeTypeKey[] = "mimetype";
|
|||
static const char kPluginsMimeDescKey[] = "description";
|
||||
static const char kPluginsMimeExtKey[] = "extension";
|
||||
|
||||
#define kPluginRegistryFilename NS_LITERAL_CSTRING("pluginreg.dat")
|
||||
|
||||
#ifdef PLUGIN_LOGGING
|
||||
PRLogModuleInfo* nsPluginLogging::gNPNLog = nsnull;
|
||||
PRLogModuleInfo* nsPluginLogging::gNPPLog = nsnull;
|
||||
|
@ -343,6 +346,31 @@ void DisplayNoDefaultPluginDialog(const char *mimeType, nsIPrompt *prompt)
|
|||
return;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// flat file reg funcs
|
||||
static
|
||||
PRBool ReadSectionHeader(nsManifestLineReader& reader, const char *token)
|
||||
{
|
||||
do {
|
||||
if (*reader.LinePtr() == '[') {
|
||||
char* p = reader.LinePtr() + (reader.LineLength() - 1);
|
||||
if (*p != ']')
|
||||
break;
|
||||
*p = 0;
|
||||
|
||||
char* values[1];
|
||||
if (1 != reader.ParseLine(values, 1))
|
||||
break;
|
||||
// ignore the leading '['
|
||||
if (PL_strcmp(values[0]+1, token)) {
|
||||
break; // it's wrong token
|
||||
}
|
||||
return PR_TRUE;
|
||||
}
|
||||
} while (reader.NextLine());
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// Little helper struct to asynchronously reframe any presentations (embedded)
|
||||
// or reload any documents (full-page), that contained plugins
|
||||
|
@ -1186,11 +1214,12 @@ PRBool nsPluginTag::Equals(nsPluginTag *aPluginTag)
|
|||
(mVariants != aPluginTag->mVariants) )
|
||||
return PR_FALSE;
|
||||
|
||||
if (0 != mVariants && mMimeTypeArray && aPluginTag->mMimeTypeArray)
|
||||
for (PRInt32 i = 0; i < mVariants; i++)
|
||||
if (mVariants && mMimeTypeArray && aPluginTag->mMimeTypeArray) {
|
||||
for (PRInt32 i = 0; i < mVariants; i++) {
|
||||
if (PL_strcmp(mMimeTypeArray[i], aPluginTag->mMimeTypeArray[i]) != 0)
|
||||
return PR_FALSE;
|
||||
|
||||
}
|
||||
}
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
|
@ -3139,76 +3168,14 @@ NS_IMETHODIMP nsPluginHostImpl::RegisterPlugin(REFNSIID aCID,
|
|||
const char** aFileExtensions,
|
||||
PRInt32 aCount)
|
||||
{
|
||||
PLUGIN_LOG(PLUGIN_LOG_NORMAL, ("nsPluginHostImpl::RegisterPlugin name=%s\n",aPluginName));
|
||||
|
||||
nsCOMPtr<nsIRegistry> registry = do_CreateInstance(kRegistryCID);
|
||||
if (! registry)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
nsresult rv;
|
||||
rv = registry->OpenWellKnownRegistry(nsIRegistry::ApplicationComponentRegistry);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
nsCAutoString path(kPluginsRootKey);
|
||||
char* cid = aCID.ToString();
|
||||
if (! cid)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
path += '/';
|
||||
path += cid;
|
||||
nsMemory::Free(cid);
|
||||
|
||||
nsRegistryKey pluginKey;
|
||||
rv = registry->AddSubtree(nsIRegistry::Common, path.get(), &pluginKey);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
// we use SetBytes instead of SetString to address special character issue, see Mozilla bug 108246
|
||||
if(aPluginName)
|
||||
registry->SetBytesUTF8(pluginKey, kPluginsNameKey, strlen(aPluginName) + 1, (PRUint8 *)aPluginName);
|
||||
|
||||
if(aDescription)
|
||||
registry->SetBytesUTF8(pluginKey, kPluginsDescKey, strlen(aDescription) + 1, (PRUint8 *)aDescription);
|
||||
|
||||
for (PRInt32 i = 0; i < aCount; ++i) {
|
||||
nsCAutoString mimepath;
|
||||
mimepath.AppendInt(i);
|
||||
|
||||
nsRegistryKey key;
|
||||
registry->AddSubtree(pluginKey, mimepath.get(), &key);
|
||||
|
||||
registry->SetStringUTF8(key, kPluginsMimeTypeKey, aMimeTypes[i]);
|
||||
|
||||
if(aMimeDescriptions && aMimeDescriptions[i])
|
||||
registry->SetBytesUTF8(key, kPluginsMimeDescKey,
|
||||
strlen(aMimeDescriptions[i]) + 1,
|
||||
(PRUint8 *)aMimeDescriptions[i]);
|
||||
|
||||
registry->SetStringUTF8(key, kPluginsMimeExtKey, aFileExtensions[i]);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
NS_IMETHODIMP nsPluginHostImpl::UnregisterPlugin(REFNSIID aCID)
|
||||
{
|
||||
nsCOMPtr<nsIRegistry> registry = do_CreateInstance(kRegistryCID);
|
||||
if (! registry)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
nsresult rv;
|
||||
rv = registry->OpenWellKnownRegistry(nsIRegistry::ApplicationComponentRegistry);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
nsCAutoString path("software/plugins/");
|
||||
char* cid = aCID.ToString();
|
||||
if (! cid)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
path += cid;
|
||||
nsMemory::Free(cid);
|
||||
|
||||
return registry->RemoveSubtree(nsIRegistry::Common, path.get());
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
|
||||
|
@ -5108,20 +5075,9 @@ nsresult nsPluginHostImpl::FindPlugins(PRBool aCreatePluginList, PRBool * aPlugi
|
|||
|
||||
*aPluginsChanged = PR_FALSE;
|
||||
nsresult rv;
|
||||
|
||||
// If the create instance failed, then it automatically disables all
|
||||
// our caching functions and we will just end up loading the plugins
|
||||
// on startup.
|
||||
nsCOMPtr<nsIRegistry> registry = do_CreateInstance(kRegistryCID);
|
||||
if (registry) {
|
||||
rv = registry->OpenWellKnownRegistry(nsIRegistry::ApplicationRegistry);
|
||||
if (NS_FAILED(rv)) {
|
||||
registry = nsnull;
|
||||
}
|
||||
}
|
||||
|
||||
// Load cached plugins info
|
||||
LoadCachedPluginsInfo(registry);
|
||||
// Read cached plugins info
|
||||
ReadPluginInfo();
|
||||
|
||||
nsCOMPtr<nsIComponentManager> compManager = do_GetService(kComponentManagerCID, &rv);
|
||||
if (compManager)
|
||||
|
@ -5254,7 +5210,7 @@ nsresult nsPluginHostImpl::FindPlugins(PRBool aCreatePluginList, PRBool * aPlugi
|
|||
// if we are creating the list, it is already done;
|
||||
// update the plugins info cache if changes are detected
|
||||
if (*aPluginsChanged)
|
||||
CachePluginsInfo(registry);
|
||||
WritePluginInfo();
|
||||
|
||||
// No more need for cached plugins. Clear it up.
|
||||
ClearCachedPluginInfoList();
|
||||
|
@ -5293,236 +5249,13 @@ void nsPluginHostImpl::ClearCachedPluginInfoList()
|
|||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static nsresult
|
||||
cidToDllname(nsIComponentManager* aComponentManager, nsIRegistry* aRegistry,
|
||||
const nsACString &aCID, nsACString &dllName)
|
||||
{
|
||||
// To figure out the filename of the plugin, we'll need to get the
|
||||
// plugin's CID, and then navigate through the XPCOM registry to
|
||||
// pull out the DLL name to which the CID is registered.
|
||||
nsAutoString path(NS_LITERAL_STRING("software/mozilla/XPCOM/classID/") + NS_ConvertASCIItoUCS2(aCID));
|
||||
|
||||
nsRegistryKey cidKey;
|
||||
nsresult rv = aRegistry->GetKey(nsIRegistry::Common, path.get(), &cidKey);
|
||||
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
PRUint8* library;
|
||||
PRUint32 count;
|
||||
// XXX Good grief, what does "GetBytesUTF8()" mean? They're bytes!
|
||||
rv = aRegistry->GetBytesUTF8(cidKey, "InprocServer", &count, &library);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
nsCOMPtr<nsIFile> file;
|
||||
// what I want to do here is QI for a Component Registration Manager. Since this
|
||||
// has not been invented yet, QI to the obsolete manager. Kids, don't do this at home.
|
||||
nsCOMPtr<nsIComponentManagerObsolete> obsoleteManager = do_QueryInterface(aComponentManager, &rv);
|
||||
if (obsoleteManager)
|
||||
rv = obsoleteManager->SpecForRegistryLocation(NS_REINTERPRET_CAST(const char*, library),
|
||||
getter_AddRefs(file));
|
||||
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
file->GetNativePath(dllName);
|
||||
}
|
||||
|
||||
nsCRT::free(NS_REINTERPRET_CAST(char*, library));
|
||||
}
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
static nsresult
|
||||
LoadXPCOMPlugin(nsIRegistry* aRegistry,
|
||||
const char* aFilename,
|
||||
nsRegistryKey aPluginKey,
|
||||
nsPluginTag** aResult)
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
// The name, description, MIME types, MIME descriptions, and
|
||||
// supported file extensions will all hang off of the plugin's key
|
||||
// in the registry. Pull these out now.
|
||||
PRUint8 * name=nsnull;
|
||||
PRUint32 length;
|
||||
aRegistry->GetBytesUTF8(aPluginKey, kPluginsNameKey, &length, &name);
|
||||
|
||||
PRUint8 * description=nsnull;
|
||||
aRegistry->GetBytesUTF8(aPluginKey, kPluginsDescKey, &length, &description);
|
||||
|
||||
nsXPIDLCString filename;
|
||||
nsXPIDLCString fullpath;
|
||||
if (!aFilename) {
|
||||
// Look for a filename key
|
||||
aRegistry->GetStringUTF8(aPluginKey, kPluginsFilenameKey, getter_Copies(filename));
|
||||
aRegistry->GetStringUTF8(aPluginKey, kPluginsFullpathKey, getter_Copies(fullpath));
|
||||
}
|
||||
|
||||
PRInt64 lastmod = LL_ZERO;
|
||||
aRegistry->GetLongLong(aPluginKey, kPluginsModTimeKey, &lastmod);
|
||||
|
||||
PRInt32 intval = 1; // Default for canunload is PR_TRUE
|
||||
aRegistry->GetInt(aPluginKey, kPluginsCanUnload, &intval);
|
||||
PRBool canunload = (intval > 0);
|
||||
|
||||
nsCOMPtr<nsIEnumerator> enumerator;
|
||||
rv = aRegistry->EnumerateAllSubtrees(aPluginKey, getter_AddRefs(enumerator));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
nsCOMPtr<nsISimpleEnumerator> subtrees;
|
||||
rv = NS_NewAdapterEnumerator(getter_AddRefs(subtrees), enumerator);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
char** mimetypes = nsnull;
|
||||
char** mimedescriptions = nsnull;
|
||||
char** extensions = nsnull;
|
||||
PRInt32 count = 0;
|
||||
PRInt32 capacity = 0;
|
||||
|
||||
for (;;) {
|
||||
PRBool hasmore;
|
||||
subtrees->HasMoreElements(&hasmore);
|
||||
if (! hasmore)
|
||||
break;
|
||||
|
||||
nsCOMPtr<nsISupports> isupports;
|
||||
subtrees->GetNext(getter_AddRefs(isupports));
|
||||
|
||||
nsCOMPtr<nsIRegistryNode> node = do_QueryInterface(isupports);
|
||||
NS_ASSERTION(node != nsnull, "not an nsIRegistryNode");
|
||||
if (! node)
|
||||
continue;
|
||||
|
||||
nsRegistryKey key;
|
||||
node->GetKey(&key);
|
||||
|
||||
if (count >= capacity) {
|
||||
capacity += capacity ? capacity : 4;
|
||||
|
||||
char** newmimetypes = new char*[capacity];
|
||||
char** newmimedescriptions = new char*[capacity];
|
||||
char** newextensions = new char*[capacity];
|
||||
|
||||
if (!newmimetypes || !newmimedescriptions || !newextensions) {
|
||||
rv = NS_ERROR_OUT_OF_MEMORY;
|
||||
delete[] newmimetypes;
|
||||
delete[] newmimedescriptions;
|
||||
delete[] newextensions;
|
||||
break;
|
||||
}
|
||||
|
||||
for (PRInt32 i = 0; i < count; ++i) {
|
||||
newmimetypes[i] = mimetypes[i];
|
||||
newmimedescriptions[i] = mimedescriptions[i];
|
||||
newextensions[i] = extensions[i];
|
||||
}
|
||||
|
||||
delete[] mimetypes;
|
||||
delete[] mimedescriptions;
|
||||
delete[] extensions;
|
||||
|
||||
mimetypes = newmimetypes;
|
||||
mimedescriptions = newmimedescriptions;
|
||||
extensions = newextensions;
|
||||
}
|
||||
|
||||
aRegistry->GetStringUTF8(key, kPluginsMimeTypeKey, &mimetypes[count]);
|
||||
|
||||
PRUint8 * md;
|
||||
aRegistry->GetBytesUTF8(key, kPluginsMimeDescKey, &length, &md);
|
||||
mimedescriptions[count] = NS_REINTERPRET_CAST(char *, md);
|
||||
|
||||
aRegistry->GetStringUTF8(key, kPluginsMimeExtKey, &extensions[count]);
|
||||
++count;
|
||||
}
|
||||
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
// All done! Create the new nsPluginTag info and send it back.
|
||||
nsPluginTag* tag
|
||||
= new nsPluginTag(NS_REINTERPRET_CAST(const char *, name),
|
||||
NS_REINTERPRET_CAST(const char *, description),
|
||||
aFilename ? aFilename : filename.get(),
|
||||
fullpath.get(),
|
||||
(const char* const*)mimetypes,
|
||||
(const char* const*)mimedescriptions,
|
||||
(const char* const*)extensions,
|
||||
count, lastmod, canunload);
|
||||
|
||||
if (! tag)
|
||||
rv = NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
*aResult = tag;
|
||||
}
|
||||
|
||||
for (PRInt32 i = 0; i < count; ++i) {
|
||||
CRTFREEIF(mimetypes[i]);
|
||||
CRTFREEIF(mimedescriptions[i]);
|
||||
CRTFREEIF(extensions[i]);
|
||||
}
|
||||
|
||||
delete[] mimetypes;
|
||||
delete[] mimedescriptions;
|
||||
delete[] extensions;
|
||||
PR_FREEIF(name);
|
||||
PR_FREEIF(description);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
static nsresult
|
||||
AddPluginInfoToRegistry(nsIRegistry* registry, nsRegistryKey top,
|
||||
nsPluginTag *tag, const char *keyname)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(tag);
|
||||
nsRegistryKey pluginKey;
|
||||
nsresult rv = registry->AddSubtree(top, keyname, &pluginKey);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
// Add filename, name and description
|
||||
registry->SetStringUTF8(pluginKey, kPluginsFilenameKey, tag->mFileName);
|
||||
if (tag->mFullPath)
|
||||
registry->SetStringUTF8(pluginKey, kPluginsFullpathKey, tag->mFullPath);
|
||||
|
||||
// we use SetBytes instead of SetString to address special character issue, see Mozilla bug 108246
|
||||
if(tag->mName)
|
||||
registry->SetBytesUTF8(pluginKey, kPluginsNameKey, strlen(tag->mName) + 1, (PRUint8 *)tag->mName);
|
||||
|
||||
if(tag->mDescription)
|
||||
registry->SetBytesUTF8(pluginKey, kPluginsDescKey, strlen(tag->mDescription) + 1, (PRUint8 *)tag->mDescription);
|
||||
|
||||
registry->SetLongLong(pluginKey, kPluginsModTimeKey, &(tag->mLastModifiedTime));
|
||||
registry->SetInt(pluginKey, kPluginsCanUnload, tag->mCanUnloadLibrary);
|
||||
|
||||
// Add in each mimetype this plugin supports
|
||||
for (int i=0; i<tag->mVariants; i++) {
|
||||
char mimetypeKeyName[16];
|
||||
nsRegistryKey mimetypeKey;
|
||||
PR_snprintf(mimetypeKeyName, sizeof (mimetypeKeyName), "mimetype-%d", i);
|
||||
rv = registry->AddSubtree(pluginKey, mimetypeKeyName, &mimetypeKey);
|
||||
if (NS_FAILED(rv))
|
||||
break;
|
||||
registry->SetStringUTF8(mimetypeKey, kPluginsMimeTypeKey, tag->mMimeTypeArray[i]);
|
||||
|
||||
if(tag->mMimeDescriptionArray && tag->mMimeDescriptionArray[i])
|
||||
registry->SetBytesUTF8(mimetypeKey, kPluginsMimeDescKey,
|
||||
strlen(tag->mMimeDescriptionArray[i]) + 1,
|
||||
(PRUint8 *)tag->mMimeDescriptionArray[i]);
|
||||
|
||||
registry->SetStringUTF8(mimetypeKey, kPluginsMimeExtKey, tag->mExtensionsArray[i]);
|
||||
}
|
||||
if (NS_FAILED(rv))
|
||||
rv = registry->RemoveSubtree(top, keyname);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
nsresult
|
||||
nsPluginHostImpl::LoadXPCOMPlugins(nsIComponentManager* aComponentManager)
|
||||
{
|
||||
{
|
||||
// the component reg is a flat file now see 48888
|
||||
// we have to reimplement this method if we need it
|
||||
|
||||
// The "new style" XPCOM plugins have their information stored in
|
||||
// the component registry, under the key
|
||||
//
|
||||
|
@ -5530,213 +5263,281 @@ nsPluginHostImpl::LoadXPCOMPlugins(nsIComponentManager* aComponentManager)
|
|||
//
|
||||
// Enumerate through that list now, creating an nsPluginTag for
|
||||
// each.
|
||||
nsCOMPtr<nsIRegistry> registry = do_CreateInstance(kRegistryCID);
|
||||
if (! registry)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
nsresult rv;
|
||||
rv = registry->OpenWellKnownRegistry(nsIRegistry::ApplicationComponentRegistry);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
nsRegistryKey pluginsKey;
|
||||
rv = registry->GetSubtree(nsIRegistry::Common, kPluginsRootKey, &pluginsKey);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
// XXX get rid nsIEnumerator someday!
|
||||
nsCOMPtr<nsIEnumerator> enumerator;
|
||||
rv = registry->EnumerateSubtrees(pluginsKey, getter_AddRefs(enumerator));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
nsCOMPtr<nsISimpleEnumerator> plugins;
|
||||
rv = NS_NewAdapterEnumerator(getter_AddRefs(plugins), enumerator);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
for (;;) {
|
||||
PRBool hasMore;
|
||||
plugins->HasMoreElements(&hasMore);
|
||||
if (! hasMore)
|
||||
break;
|
||||
|
||||
nsCOMPtr<nsISupports> isupports;
|
||||
plugins->GetNext(getter_AddRefs(isupports));
|
||||
|
||||
nsCOMPtr<nsIRegistryNode> node = do_QueryInterface(isupports);
|
||||
NS_ASSERTION(node != nsnull, "not an nsIRegistryNode");
|
||||
if (! node)
|
||||
continue;
|
||||
|
||||
// Pull out the information for an individual plugin, and link it
|
||||
// in to the mPlugins list.
|
||||
nsXPIDLCString cid;
|
||||
node->GetNameUTF8(getter_Copies(cid));
|
||||
|
||||
nsRegistryKey key;
|
||||
node->GetKey(&key);
|
||||
|
||||
nsCAutoString filename;
|
||||
rv = cidToDllname(aComponentManager, registry, cid, filename);
|
||||
if (NS_FAILED(rv))
|
||||
continue;
|
||||
|
||||
nsPluginTag* tag = nsnull;
|
||||
rv = LoadXPCOMPlugin(registry, filename.get(), key, &tag);
|
||||
if (NS_FAILED(rv))
|
||||
continue;
|
||||
|
||||
PRBool bAddIt = PR_TRUE;
|
||||
|
||||
// Find the same plugin in our cache and mark it as 'unwanted' so this plugin will
|
||||
// just be added to the list without being detected as new.
|
||||
// Note: Our XPCOM plugin probably shouldn't be in this list. If it is, it has been
|
||||
// cached twice in the registry:
|
||||
// a) ApplicationComponentRegistry: probably by the installer or regxpcom
|
||||
// b) ApplicationRegistry: by us in |nsPluginHostImpl::CachePluginsInfo|
|
||||
nsPluginTag *cachedTag = RemoveCachedPluginsInfo(filename.get());
|
||||
if (cachedTag) {
|
||||
cachedTag->Mark(NS_PLUGIN_FLAG_UNWANTED);
|
||||
cachedTag->mNext = mCachedPlugins;
|
||||
mCachedPlugins = cachedTag;
|
||||
}
|
||||
|
||||
// skip it if we already have it
|
||||
if (HaveSamePlugin(tag))
|
||||
bAddIt = PR_FALSE;
|
||||
|
||||
if(!bAddIt) {
|
||||
if(tag)
|
||||
delete tag;
|
||||
continue;
|
||||
}
|
||||
|
||||
tag->SetHost(this);
|
||||
tag->mNext = mPlugins;
|
||||
mPlugins = tag;
|
||||
|
||||
// Create an nsIDocumentLoaderFactory wrapper in case we ever see
|
||||
// any naked streams.
|
||||
RegisterPluginMimeTypesWithLayout(tag, aComponentManager);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
nsresult
|
||||
nsPluginHostImpl::LoadCachedPluginsInfo(nsIRegistry* registry)
|
||||
{
|
||||
// Loads cached plugin info from registry
|
||||
//
|
||||
// Enumerate through that list now, creating an nsPluginTag for
|
||||
// each.
|
||||
if (! registry)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
nsRegistryKey pluginsKey;
|
||||
nsresult rv = registry->GetSubtree(nsIRegistry::Common, kPluginsRootKey, &pluginsKey);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
// Make sure we are dealing with the same version number of the plugin info
|
||||
nsXPIDLCString version;
|
||||
rv = registry->GetStringUTF8(pluginsKey, kPluginsVersionKey, getter_Copies(version));
|
||||
if (NS_FAILED(rv) || PL_strcmp(version.get(), kPluginInfoVersion)) {
|
||||
// Version mismatch
|
||||
// Nuke the subtree
|
||||
registry->RemoveSubtree(nsIRegistry::Common, kPluginsRootKey);
|
||||
PR_LOG(nsPluginLogging::gPluginLog, PLUGIN_LOG_BASIC,
|
||||
("LoadCachedPluginsInfo : Version %s mismatch - Expected %s. Nuking cached info.\n",
|
||||
version.get(), kPluginInfoVersion));
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
// XXX get rid nsIEnumerator someday!
|
||||
nsCOMPtr<nsIEnumerator> enumerator;
|
||||
rv = registry->EnumerateSubtrees(pluginsKey, getter_AddRefs(enumerator));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
nsCOMPtr<nsISimpleEnumerator> plugins;
|
||||
rv = NS_NewAdapterEnumerator(getter_AddRefs(plugins), enumerator);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
for (;;) {
|
||||
PRBool hasMore;
|
||||
plugins->HasMoreElements(&hasMore);
|
||||
if (! hasMore)
|
||||
break;
|
||||
|
||||
nsCOMPtr<nsISupports> isupports;
|
||||
plugins->GetNext(getter_AddRefs(isupports));
|
||||
|
||||
nsCOMPtr<nsIRegistryNode> node = do_QueryInterface(isupports);
|
||||
NS_ASSERTION(node != nsnull, "not an nsIRegistryNode");
|
||||
if (! node)
|
||||
continue;
|
||||
|
||||
// Pull out the information for an individual plugin, and link it
|
||||
// in to the mCachedPlugins list.
|
||||
nsRegistryKey key;
|
||||
node->GetKey(&key);
|
||||
|
||||
nsPluginTag* tag = nsnull;
|
||||
rv = LoadXPCOMPlugin(registry, nsnull, key, &tag);
|
||||
if (NS_FAILED(rv))
|
||||
continue;
|
||||
|
||||
tag->SetHost(this);
|
||||
|
||||
// Mark plugin as loaded from cache
|
||||
tag->Mark(NS_PLUGIN_FLAG_FROMCACHE);
|
||||
PR_LOG(nsPluginLogging::gPluginLog, PLUGIN_LOG_BASIC,
|
||||
("LoadCachedPluginsInfo : Loading Cached plugininfo for %s\n", tag->mFileName));
|
||||
tag->mNext = mCachedPlugins;
|
||||
mCachedPlugins = tag;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsPluginHostImpl::CachePluginsInfo(nsIRegistry* registry)
|
||||
nsPluginHostImpl::WritePluginInfo()
|
||||
{
|
||||
// Save plugin info from registry
|
||||
|
||||
if (! registry)
|
||||
nsresult rv = NS_OK;
|
||||
nsCOMPtr<nsIProperties> directoryService(do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID,&rv));
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
directoryService->Get(NS_APP_APPLICATION_REGISTRY_DIR, NS_GET_IID(nsIFile),
|
||||
getter_AddRefs(mPluginsDir));
|
||||
|
||||
if (!mPluginsDir)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
// We don't want any old plugins that don't exist anymore hanging around
|
||||
// So remove and re-add the root of the plugins info
|
||||
nsresult rv = registry->RemoveSubtree(nsIRegistry::Common, kPluginsRootKey);
|
||||
|
||||
nsRegistryKey pluginsSubtreeKey;
|
||||
rv = registry->AddSubtree(nsIRegistry::Common, kPluginsRootKey, &pluginsSubtreeKey);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
PRFileDesc* fd = nsnull;
|
||||
|
||||
nsCOMPtr<nsIFile> pluginReg;
|
||||
|
||||
rv = registry->SetStringUTF8(pluginsSubtreeKey, kPluginsVersionKey, kPluginInfoVersion);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
rv = mPluginsDir->Clone(getter_AddRefs(pluginReg));
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
rv = pluginReg->AppendNative(kPluginRegistryFilename);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
int count = 0;
|
||||
nsCOMPtr<nsILocalFile> localFile = do_QueryInterface(pluginReg, &rv);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
rv = localFile->OpenNSPRFileDesc(PR_WRONLY | PR_CREATE_FILE | PR_TRUNCATE, 0600, &fd);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
PR_fprintf(fd, "Generated File. Do not edit.\n");
|
||||
|
||||
PR_fprintf(fd, "\n[HEADER]\nVersion%c%d%c%d\n",
|
||||
PLUGIN_REGISTRY_FIELD_DELIMITER,
|
||||
PLUGIN_REGISTRY_VERSION_MAJOR,
|
||||
PLUGIN_REGISTRY_FIELD_DELIMITER,
|
||||
PLUGIN_REGISTRY_VERSION_MINOR);
|
||||
|
||||
// Store all plugins in the mPlugins list - all plugins currently in use.
|
||||
char pluginKeyName[64];
|
||||
nsPluginTag *tag;
|
||||
for(tag = mPlugins; tag; tag=tag->mNext) {
|
||||
// store each plugin info into the registry
|
||||
PR_snprintf(pluginKeyName, sizeof(pluginKeyName), "plugin-%d", ++count);
|
||||
AddPluginInfoToRegistry(registry, pluginsSubtreeKey, tag, pluginKeyName);
|
||||
PR_fprintf(fd, "\n[PLUGINS]");
|
||||
|
||||
nsPluginTag *taglist[] = {mPlugins, mCachedPlugins};
|
||||
for (int i=0; i<sizeof(taglist)/sizeof(nsPluginTag *); i++) {
|
||||
for (nsPluginTag *tag = taglist[i]; tag; tag=tag->mNext) {
|
||||
// from mCachedPlugins list write down only unwanted plugins
|
||||
if ((taglist[i] == mCachedPlugins) && !(tag->mFlags & NS_PLUGIN_FLAG_UNWANTED))
|
||||
continue;
|
||||
// store each plugin info into the registry
|
||||
//filename|fullpath|lastModifiedTimeStamp|canUnload|tag->mFlags
|
||||
PR_fprintf(fd, "\n%s%c%s%c%lld%c%d%c%lu\n",
|
||||
(tag->mFileName ? tag->mFileName : ""),
|
||||
PLUGIN_REGISTRY_FIELD_DELIMITER,
|
||||
(tag->mFullPath ? tag->mFullPath : ""),
|
||||
PLUGIN_REGISTRY_FIELD_DELIMITER,
|
||||
tag->mLastModifiedTime,PLUGIN_REGISTRY_FIELD_DELIMITER,
|
||||
tag->mCanUnloadLibrary,PLUGIN_REGISTRY_FIELD_DELIMITER,
|
||||
tag->mFlags);
|
||||
|
||||
//description\n --\ on separate line, so there is no need to parse it
|
||||
//name\n --/ and check for delimiters
|
||||
//mtypecount
|
||||
PR_fprintf(fd, "%s\n%s\n%d\n",
|
||||
tag->mDescription,
|
||||
tag->mName,
|
||||
tag->mVariants);
|
||||
|
||||
// Add in each mimetype this plugin supports
|
||||
for (int i=0; i<tag->mVariants; i++) {
|
||||
PR_fprintf(fd, "%d%c%s%c%s%c%s\n",
|
||||
i,PLUGIN_REGISTRY_FIELD_DELIMITER,
|
||||
tag->mMimeTypeArray[i],PLUGIN_REGISTRY_FIELD_DELIMITER,
|
||||
tag->mMimeDescriptionArray[i],PLUGIN_REGISTRY_FIELD_DELIMITER,
|
||||
tag->mExtensionsArray[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Store any unwanted plugins info so that we wont have to load
|
||||
// them again the next time around
|
||||
tag = mCachedPlugins;
|
||||
for(tag = mCachedPlugins; tag; tag=tag->mNext) {
|
||||
// Look for unwanted plugins
|
||||
if (!(tag->mFlags & NS_PLUGIN_FLAG_UNWANTED))
|
||||
if (fd)
|
||||
PR_Close(fd);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsPluginHostImpl::ReadPluginInfo()
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
nsCOMPtr<nsIProperties> directoryService(do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID,&rv));
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
directoryService->Get(NS_APP_APPLICATION_REGISTRY_DIR, NS_GET_IID(nsIFile),
|
||||
getter_AddRefs(mPluginsDir));
|
||||
|
||||
if (!mPluginsDir)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
PRFileDesc* fd = nsnull;
|
||||
|
||||
nsCOMPtr<nsIFile> pluginReg;
|
||||
|
||||
rv = mPluginsDir->Clone(getter_AddRefs(pluginReg));
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
rv = pluginReg->AppendNative(kPluginRegistryFilename);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
nsCOMPtr<nsILocalFile> localFile = do_QueryInterface(pluginReg, &rv);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
PRInt64 fileSize;
|
||||
rv = localFile->GetFileSize(&fileSize);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
PRInt32 flen = nsInt64(fileSize);
|
||||
if (flen == 0) {
|
||||
NS_WARNING("Plugins Registry Empty!");
|
||||
return NS_OK; // ERROR CONDITION
|
||||
}
|
||||
|
||||
nsManifestLineReader reader;
|
||||
char* registry = reader.Init(flen);
|
||||
if (!registry) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
rv = localFile->OpenNSPRFileDesc(PR_RDONLY, 0444, &fd);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
// set rv to return an error on goto out
|
||||
rv = NS_ERROR_FAILURE;
|
||||
|
||||
PRInt32 bread = PR_Read(fd, registry, flen);
|
||||
PR_Close(fd);
|
||||
|
||||
if (flen > bread)
|
||||
return rv;
|
||||
|
||||
if (!ReadSectionHeader(reader, "HEADER")) {
|
||||
return rv;;
|
||||
}
|
||||
|
||||
if (!reader.NextLine()) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
char* values[6];
|
||||
|
||||
// VersionLiteral,major,minor
|
||||
if (3 != reader.ParseLine(values, 3)) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
// VersionLiteral
|
||||
if (PL_strcmp(values[0], "Version")) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
// major
|
||||
if (PLUGIN_REGISTRY_VERSION_MAJOR != atoi(values[1])) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
// minor
|
||||
if (PLUGIN_REGISTRY_VERSION_MINOR != atoi(values[2])) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
if (!ReadSectionHeader(reader, "PLUGINS")) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
while (reader.NextLine()) {
|
||||
|
||||
//filename|fullpath|lastModifiedTimeStamp|canUnload|tag.mFlag
|
||||
if (5 != reader.ParseLine(values, 5))
|
||||
return rv;
|
||||
|
||||
char *filename = values[0];
|
||||
char *fullpath = values[1];
|
||||
PRInt64 lastmod = nsCRT::atoll(values[2]);
|
||||
PRBool canunload = atoi(values[3]);
|
||||
PRUint32 tagflag = atoi(values[4]);
|
||||
|
||||
//description is whole line and can contain any chars
|
||||
if (!reader.NextLine())
|
||||
return rv;
|
||||
char *description = reader.LinePtr();
|
||||
|
||||
//name is whole line and can contain any chars
|
||||
if (!reader.NextLine())
|
||||
return rv;
|
||||
char *name = reader.LinePtr();
|
||||
|
||||
//mimetypecount
|
||||
if (!reader.NextLine())
|
||||
return rv;
|
||||
int mimetypecount = atoi(reader.LinePtr());
|
||||
|
||||
char *stackalloced[PLUGIN_REGISTRY_MAX_MIMETYPES_PER_PLUGIN * 3];
|
||||
char **mimetypes;
|
||||
char **mimedescriptions;
|
||||
char **extensions;
|
||||
char **heapalloced = 0;
|
||||
if (mimetypecount > PLUGIN_REGISTRY_MAX_MIMETYPES_PER_PLUGIN - 1) {
|
||||
heapalloced = new char *[mimetypecount * 3];
|
||||
mimetypes = heapalloced;
|
||||
} else {
|
||||
mimetypes = stackalloced;
|
||||
}
|
||||
mimedescriptions = mimetypes + mimetypecount;
|
||||
extensions = mimedescriptions + mimetypecount;
|
||||
|
||||
int mtr = 0; //mimetype read
|
||||
for (; mtr < mimetypecount; mtr++) {
|
||||
if (!reader.NextLine())
|
||||
break;
|
||||
|
||||
//line number|mimetype|description|extension
|
||||
if (4 != reader.ParseLine(values, 4))
|
||||
break;
|
||||
int line = atoi(values[0]);
|
||||
if (line != mtr)
|
||||
break;
|
||||
mimetypes[mtr] = values[1];
|
||||
mimedescriptions[mtr] = values[2];
|
||||
extensions[mtr] = values[3];
|
||||
}
|
||||
|
||||
if (mtr != mimetypecount) {
|
||||
if (heapalloced) {
|
||||
delete [] heapalloced;
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsPluginTag* tag = new nsPluginTag(name,
|
||||
description,
|
||||
filename,
|
||||
(*fullpath ? fullpath : 0), // we have to pass 0 prt if it's empty str
|
||||
(const char* const*)mimetypes,
|
||||
(const char* const*)mimedescriptions,
|
||||
(const char* const*)extensions,
|
||||
mimetypecount, lastmod, canunload);
|
||||
if (heapalloced) {
|
||||
delete [] heapalloced;
|
||||
}
|
||||
|
||||
if (!tag) {
|
||||
continue;
|
||||
|
||||
// store each plugin info into the registry
|
||||
PR_snprintf(pluginKeyName, sizeof(pluginKeyName), "plugin-%d", ++count);
|
||||
AddPluginInfoToRegistry(registry, pluginsSubtreeKey, tag, pluginKeyName);
|
||||
}
|
||||
|
||||
// Mark plugin as loaded from cache
|
||||
tag->Mark(tagflag | NS_PLUGIN_FLAG_FROMCACHE);
|
||||
PR_LOG(nsPluginLogging::gPluginLog, PLUGIN_LOG_BASIC,
|
||||
("LoadCachedPluginsInfo : Loading Cached plugininfo for %s\n", tag->mFileName));
|
||||
tag->mNext = mCachedPlugins;
|
||||
mCachedPlugins = tag;
|
||||
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -434,11 +434,11 @@ private:
|
|||
|
||||
PRBool IsRunningPlugin(nsPluginTag * plugin);
|
||||
|
||||
// Loads all cached plugins info into mCachedPlugins
|
||||
nsresult LoadCachedPluginsInfo(nsIRegistry* registry);
|
||||
|
||||
// Stores all plugins info into the registry
|
||||
nsresult CachePluginsInfo(nsIRegistry* registry);
|
||||
nsresult WritePluginInfo();
|
||||
|
||||
// Loads all cached plugins info into mCachedPlugins
|
||||
nsresult ReadPluginInfo();
|
||||
|
||||
// Given a filename, returns the plugins info from our cache
|
||||
// and removes it from the cache.
|
||||
|
@ -473,6 +473,7 @@ private:
|
|||
nsActivePluginList mActivePluginList;
|
||||
nsVoidArray mUnusedLibraries;
|
||||
|
||||
nsCOMPtr<nsIFile> mPluginsDir;
|
||||
nsCOMPtr<nsIDirectoryServiceProvider> mPrivateDirServiceProvider;
|
||||
nsWeakPtr mCurrentDocument; // weak reference, we use it to id document only
|
||||
|
||||
|
|
|
@ -0,0 +1,131 @@
|
|||
/* -*- 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):
|
||||
*
|
||||
* 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 nsPluginManifestLineReader_h__
|
||||
#define nsPluginManifestLineReader_h__
|
||||
|
||||
#include "nspr.h"
|
||||
#include "nsDebug.h"
|
||||
|
||||
|
||||
#define PLUGIN_REGISTRY_VERSION_MINOR 6
|
||||
#define PLUGIN_REGISTRY_VERSION_MAJOR 0
|
||||
#ifdef XP_WIN
|
||||
#define PLUGIN_REGISTRY_FIELD_DELIMITER '|'
|
||||
#else
|
||||
#define PLUGIN_REGISTRY_FIELD_DELIMITER ':'
|
||||
#endif
|
||||
|
||||
#define PLUGIN_REGISTRY_MAX_MIMETYPES_PER_PLUGIN 4
|
||||
|
||||
class nsManifestLineReader
|
||||
{
|
||||
public:
|
||||
nsManifestLineReader() {mBase = mCur = mNext = mLimit = 0;}
|
||||
~nsManifestLineReader() {delete [] mBase;}
|
||||
|
||||
char* Init(PRUint32 flen)
|
||||
{
|
||||
mBase = mCur = mNext = new char[flen+1];
|
||||
if (mBase) {
|
||||
mLimit = mBase + flen;
|
||||
*mLimit = 0;
|
||||
}
|
||||
mLength = 0;
|
||||
return mBase;
|
||||
}
|
||||
|
||||
PRBool NextLine()
|
||||
{
|
||||
if(mNext >= mLimit)
|
||||
return PR_FALSE;
|
||||
|
||||
mCur = mNext;
|
||||
mLength = 0;
|
||||
|
||||
while(mNext < mLimit)
|
||||
{
|
||||
if(IsEOL(*mNext))
|
||||
{
|
||||
*mNext = '\0';
|
||||
for(++mNext; mNext < mLimit; ++mNext)
|
||||
if(!IsEOL(*mNext))
|
||||
break;
|
||||
return PR_TRUE;
|
||||
}
|
||||
++mNext;
|
||||
++mLength;
|
||||
}
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
int ParseLine(char** chunks, int maxChunks)
|
||||
{
|
||||
NS_ASSERTION(mCur && maxChunks && chunks, "bad call to ParseLine");
|
||||
int found = 0;
|
||||
chunks[found++] = mCur;
|
||||
|
||||
if(found < maxChunks)
|
||||
{
|
||||
for(char* cur = mCur; *cur; cur++)
|
||||
{
|
||||
if(*cur == PLUGIN_REGISTRY_FIELD_DELIMITER)
|
||||
{
|
||||
*cur = 0;
|
||||
chunks[found++] = cur+1;
|
||||
if(found == maxChunks)
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return found;
|
||||
}
|
||||
|
||||
char* LinePtr() {return mCur;}
|
||||
PRUint32 LineLength() {return mLength;}
|
||||
|
||||
PRBool IsEOL(char c) {return c == '\n' || c == '\r';}
|
||||
|
||||
char* mBase;
|
||||
private:
|
||||
char* mCur;
|
||||
PRUint32 mLength;
|
||||
char* mNext;
|
||||
char* mLimit;
|
||||
};
|
||||
|
||||
#endif
|
Загрузка…
Ссылка в новой задаче