diff --git a/mozilla/browser/components/migration/src/Makefile.in b/mozilla/browser/components/migration/src/Makefile.in index 317fa1713ac..4c4c57054c2 100644 --- a/mozilla/browser/components/migration/src/Makefile.in +++ b/mozilla/browser/components/migration/src/Makefile.in @@ -71,6 +71,7 @@ CPPSRCS = nsProfileMigrator.cpp \ nsNetscapeProfileMigratorBase.cpp \ nsSeamonkeyProfileMigrator.cpp \ nsPhoenixProfileMigrator.cpp \ + nsINIParser.cpp \ $(NULL) ifneq ($(OS_ARCH),BeOS) diff --git a/mozilla/browser/components/migration/src/nsINIParser.cpp b/mozilla/browser/components/migration/src/nsINIParser.cpp new file mode 100644 index 00000000000..106641c5ea6 --- /dev/null +++ b/mozilla/browser/components/migration/src/nsINIParser.cpp @@ -0,0 +1,332 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla 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/MPL/ + * + * 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 Communicator client code, released + * March 31, 1998. + * + * 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): + * Samir Gehani + * + * 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 MPL, 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 MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + + +#include "nsINIParser.h" +#include "nsCRT.h" + +nsINIParser::nsINIParser(const char *aFilename) +{ + FILE *fd = NULL; + long eofpos = 0; + int rd = 0; + + mFileBuf = NULL; + mFileBufSize = 0; + mError = OK; + DUMP("nsINIParser"); + + /* param check */ + if (!aFilename) + { + mError = E_PARAM; + return; + } + + /* open the file */ + fd = fopen(aFilename, "r"); + if (!fd) + goto bail; + + /* get file size */ + if (fseek(fd, 0, SEEK_END) != 0) + goto bail; + eofpos = ftell(fd); + if (eofpos == 0) + goto bail; + + /* malloc an internal buf the size of the file */ + mFileBuf = (char *) malloc((eofpos+1) * sizeof(char)); + if (!mFileBuf) + { + mError = E_MEM; + return; + } + mFileBufSize = eofpos; + + /* read the file in one swoop */ + if (fseek(fd, 0, SEEK_SET) != 0) + goto bail; + rd = fread((void *)mFileBuf, 1, eofpos, fd); + if (!rd) + goto bail; + mFileBuf[mFileBufSize] = '\0'; + + /* close file */ + fclose(fd); + + return; + +bail: + mError = E_READ; + return; +} + +nsINIParser::~nsINIParser() +{ + if (mFileBuf) { + nsCRT::free(mFileBuf); + mFileBuf = nsnull; + } + DUMP("~nsINIParser"); +} + +int +nsINIParser::GetString( char *aSection, char *aKey, + char *aValBuf, int *aIOValBufSize ) +{ + char *secPtr = NULL; + mError = OK; + DUMP("GetString"); + + /* param check */ + if ( !aSection || !aKey || !aValBuf || + !aIOValBufSize || (*aIOValBufSize <= 0) ) + return E_PARAM; + + /* find the section if it exists */ + mError = FindSection(aSection, &secPtr); + if (mError != OK) + return mError; + + /* find the key if it exists in the valid section we found */ + mError = FindKey(secPtr, aKey, aValBuf, aIOValBufSize); + + return mError; +} + +int +nsINIParser::GetStringAlloc( char *aSection, char *aKey, + char **aOutBuf, int *aOutBufSize ) +{ + char buf[MAX_VAL_SIZE]; + int bufsize = MAX_VAL_SIZE; + mError = OK; + DUMP("GetStringAlloc"); + + mError = GetString(aSection, aKey, buf, &bufsize); + if (mError != OK) + return mError; + + *aOutBuf = (char *) malloc(bufsize + 1); + strncpy(*aOutBuf, buf, bufsize); + *(*aOutBuf + bufsize) = 0; + *aOutBufSize = bufsize + 1; + + return mError; +} + +int +nsINIParser::GetError() +{ + DUMP("GetError"); + return mError; +} + +char * +nsINIParser::ResolveName(char *aINIRoot) +{ + char *resolved = NULL; + char *locale = NULL; + struct stat st_exists; + + /* param check */ + if (!aINIRoot) + return NULL; + + locale = setlocale(LC_CTYPE, NULL); + if (!locale) + return NULL; + + /* resolved string: ".ini.\0" */ + resolved = (char *) malloc(strlen(aINIRoot) + 5 + strlen(locale) + 1); + if (!resolved) + return NULL; + + /* locale specific ini file name */ + sprintf(resolved, "%s.ini.%s", aINIRoot, locale); + if (0 == stat(resolved, &st_exists)) + return resolved; + + /* fallback to general ini file name */ + sprintf(resolved, "%s.ini", aINIRoot); + if (0 == stat(resolved, &st_exists)) + return resolved; + + /* neither existed so error returned */ + return NULL; +} + +int +nsINIParser::FindSection(char *aSection, char **aOutSecPtr) +{ + char *currChar = mFileBuf; + char *nextSec = NULL; + char *secClose = NULL; + char *nextNL = NULL; + mError = E_NO_SEC; + DUMP("FindSection"); + + // param check + if (!aSection || !aOutSecPtr) + { + mError = E_PARAM; + return mError; + } + + while (currChar < (mFileBuf + mFileBufSize)) + { + // look for first '[' + nextSec = NULL; + nextSec = strchr(currChar, '['); + if (!nextSec) + break; + + currChar = nextSec + 1; + + // extract section name till first ']' + secClose = NULL; nextNL = NULL; + secClose = strchr(currChar, ']'); + nextNL = strchr(currChar, NL); + if ((!nextNL) || (nextNL < secClose)) + { + currChar = nextNL; + continue; + } + + // if section name matches we succeeded + if (strncmp(aSection, currChar, strlen(aSection)) == 0) + { + *aOutSecPtr = secClose + 1; + mError = OK; + break; + } + } + + return mError; +} + +int +nsINIParser::FindKey(char *aSecPtr, char *aKey, char *aVal, int *aIOValSize) +{ + char *nextNL = NULL; + char *secEnd = NULL; + char *currLine = aSecPtr; + char *nextEq = NULL; + mError = E_NO_KEY; + DUMP("FindKey"); + + // param check + if (!aSecPtr || !aKey || !aVal || !aIOValSize || (*aIOValSize <= 0)) + { + mError = E_PARAM; + return mError; + } + + // determine the section end + secEnd = aSecPtr; +find_end: + if (secEnd) + secEnd = strchr(secEnd, '['); // search for next sec start + if (!secEnd) + { + secEnd = strchr(aSecPtr, '\0'); // else search for file end + if (!secEnd) + { + mError = E_SEC_CORRUPT; // else this data is corrupt + return mError; + } + } + + // handle start section token ('[') in values for i18n + if (*secEnd == '[' && !(secEnd == aSecPtr || *(secEnd-1) == NL)) + { + secEnd++; + goto find_end; + } + + while (currLine < secEnd) + { + nextNL = NULL; + nextNL = strchr(currLine, NL); + if (!nextNL) + nextNL = mFileBuf + mFileBufSize; + + // ignore commented lines (starting with ;) + if (currLine == strchr(currLine, ';')) + { + currLine = nextNL + 1; + continue; + } + + // extract key before '=' + nextEq = NULL; + nextEq = strchr(currLine, '='); + if (!nextEq || nextEq > nextNL) + { + currLine = nextNL + 1; + continue; + } + + // if key matches we succeeded + if (strncmp(currLine, aKey, strlen(aKey)) == 0) + { + // extract the value and return + if (*aIOValSize < nextNL - nextEq) + { + mError = E_SMALL_BUF; + *aVal = '\0'; + *aIOValSize = 0; + return mError; + } + + *aIOValSize = nextNL - (nextEq + 1); + strncpy(aVal, (nextEq + 1), *aIOValSize); + *(aVal + *aIOValSize) = 0; // null terminate + mError = OK; + return mError; + } + else + { + currLine = nextNL + 1; + } + } + + return mError; +} diff --git a/mozilla/browser/components/migration/src/nsINIParser.h b/mozilla/browser/components/migration/src/nsINIParser.h new file mode 100644 index 00000000000..201d8c62356 --- /dev/null +++ b/mozilla/browser/components/migration/src/nsINIParser.h @@ -0,0 +1,163 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla 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/MPL/ + * + * 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 Communicator client code, released + * March 31, 1998. + * + * 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): + * Samir Gehani + * + * 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 MPL, 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 MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#ifndef _NS_INIPARSER_H_ +#define _NS_INIPARSER_H_ + +#include +#include +#include +#include +#include + +class nsINIParser +{ +public: + + /** + * nsINIParser + * + * Construct a new INI parser for the file specified. + * + * @param aFilename path to INI file + */ + nsINIParser(const char *aFilename); + ~nsINIParser(); + + /** + * GetString + * + * Gets the value of the specified key in the specified section + * of the INI file represented by this instance. The value is stored + * in the supplied buffer. The buffer size is provided as input and + * the actual bytes used by the value is set in the in/out size param. + * + * @param aSection section name + * @param aKey key name + * @param aValBuf user supplied buffer + * @param aIOValBufSize buf size on input; actual buf used on output + * + * @return mError operation success code + */ + int GetString( char *aSection, char *aKey, + char *aValBuf, int *aIOValBufSize ); + + /** + * GetStringAlloc + * + * Same as GetString() except the buffer is allocated to the exact + * size of the value. Useful when the buffer is allocated everytime + * rather than reusing the same buffer when calling this function + * multiple times. + * + * @param aSection section name + * @param aKey key name + * @param aOutBuf buffer to be allocated + * @param aOutBufSize size of newly allocated buffer + * + * @return mError operation success code + */ + int GetStringAlloc( char *aSection, char *aKey, + char **aOutBuf, int *aOutBufSize ); + + /** + * GetError + * + * Exposes the last error on this instance. Useful for checking + * the state of the object after construction since the INI file + * is parsed once at object-allocation time. + * + * @return mError last error on ops on this object + */ + int GetError(); + + /** + * ResolveName + * + * Given a "root" name we append the runtime locale of the + * current system to the .ini. If such a file exists we + * return this as the name else simply return .ini. + * + * NOTE: Returned string is allocated and caller is responsible + * ---- for its deallocation. + * + * @param aINIRoot the "root" of the INI file name + * @return resolved the resolved INI file name + * (NULL if neither exist) + */ + static char *ResolveName(char *aINIRoot); + +/*--------------------------------------------------------------------* + * Errors + *--------------------------------------------------------------------*/ + enum + { + OK = 0, + E_READ = -701, + E_MEM = -702, + E_PARAM = -703, + E_NO_SEC = -704, + E_NO_KEY = -705, + E_SEC_CORRUPT = -706, + E_SMALL_BUF = -707 + }; + +private: + int FindSection(char *aSection, char **aOutSecPtr); + int FindKey(char *aSecPtr, char *aKey, char *aVal, int *aIOValSize); + + char *mFileBuf; + int mFileBufSize; + int mError; +}; + +#define NL '\n' +#define MAX_VAL_SIZE 512 + +#if defined(DUMP) +#undef DUMP +#endif +#if defined(DEBUG_sgehani) || defined(DEBUG_druidd) || defined(DEBUG_root) +#define DUMP(_msg) printf("%s %d: %s \n", __FILE__, __LINE__, _msg); +#else +#define DUMP(_msg) +#endif + + +#endif /*_NS_INIPARSER_H_ */ diff --git a/mozilla/browser/components/migration/src/nsOperaProfileMigrator.cpp b/mozilla/browser/components/migration/src/nsOperaProfileMigrator.cpp index 70c33656c35..b82a0809951 100644 --- a/mozilla/browser/components/migration/src/nsOperaProfileMigrator.cpp +++ b/mozilla/browser/components/migration/src/nsOperaProfileMigrator.cpp @@ -367,18 +367,15 @@ nsOperaProfileMigrator::SetString(void* aTransform, nsIPrefBranch* aBranch) nsresult nsOperaProfileMigrator::CopyPreferences(PRBool aReplace) { - nsresult rv; - nsCOMPtr operaPrefs; mOperaProfile->Clone(getter_AddRefs(operaPrefs)); operaPrefs->Append(OPERA_PREFERENCES_FILE_NAME); - nsCOMPtr lf(do_QueryInterface(operaPrefs)); - NS_ENSURE_TRUE(lf, NS_ERROR_UNEXPECTED); - - nsINIParser parser; - rv = parser.Init(lf); - NS_ENSURE_SUCCESS(rv, rv); + nsCAutoString path; + operaPrefs->GetNativePath(path); + nsINIParser* parser = new nsINIParser(path.get()); + if (!parser) + return NS_ERROR_OUT_OF_MEMORY; nsCOMPtr branch(do_GetService(NS_PREFSERVICE_CONTRACTID)); @@ -386,6 +383,7 @@ nsOperaProfileMigrator::CopyPreferences(PRBool aReplace) PrefTransform* transform; PrefTransform* end = gTransforms + sizeof(gTransforms)/sizeof(PrefTransform); + PRInt32 length; char* lastSectionName = nsnull; for (transform = gTransforms; transform < end; ++transform) { if (transform->sectionName) @@ -404,22 +402,22 @@ nsOperaProfileMigrator::CopyPreferences(PRBool aReplace) nsCRT::free(colorString); } else { - nsCAutoString val; - rv = parser.GetString(lastSectionName, - transform->keyName, - val); - if (NS_SUCCEEDED(rv)) { + nsXPIDLCString val; + PRInt32 err = parser->GetStringAlloc(lastSectionName, transform->keyName, getter_Copies(val), &length); + if (err == nsINIParser::OK) { PRInt32 strerr; switch (transform->type) { case _OPM(STRING): transform->stringValue = ToNewCString(val); break; case _OPM(INT): { - transform->intValue = val.ToInteger(&strerr); + nsCAutoString valStr; valStr = val; + transform->intValue = valStr.ToInteger(&strerr); } break; case _OPM(BOOL): { - transform->boolValue = val.ToInteger(&strerr) != 0; + nsCAutoString valStr; valStr = val; + transform->boolValue = valStr.ToInteger(&strerr) != 0; } break; default: @@ -442,22 +440,23 @@ nsOperaProfileMigrator::CopyPreferences(PRBool aReplace) if (aReplace) CopyUserContentSheet(parser); + delete parser; + parser = nsnull; + return NS_OK; } nsresult -nsOperaProfileMigrator::CopyProxySettings(nsINIParser &aParser, +nsOperaProfileMigrator::CopyProxySettings(nsINIParser* aParser, nsIPrefBranch* aBranch) { - nsresult rv; - PRInt32 networkProxyType = 0; const char* protocols[4] = { "HTTP", "HTTPS", "FTP", "GOPHER" }; const char* protocols_l[4] = { "http", "https", "ftp", "gopher" }; char toggleBuf[15], serverBuf[20], serverPrefBuf[20], serverPortPrefBuf[25]; - PRInt32 enabled; + PRInt32 length, err, enabled; for (PRUint32 i = 0; i < 4; ++i) { sprintf(toggleBuf, "Use %s", protocols[i]); GetInteger(aParser, "Proxy", toggleBuf, &enabled); @@ -468,9 +467,9 @@ nsOperaProfileMigrator::CopyProxySettings(nsINIParser &aParser, } sprintf(serverBuf, "%s Server", protocols[i]); - nsCAutoString proxyServer; - rv = aParser.GetString("Proxy", serverBuf, proxyServer); - if (NS_FAILED(rv)) + nsXPIDLCString proxyServer; + err = aParser->GetStringAlloc("Proxy", serverBuf, getter_Copies(proxyServer), &length); + if (err != nsINIParser::OK) continue; sprintf(serverPrefBuf, "network.proxy.%s", protocols_l[i]); @@ -481,18 +480,16 @@ nsOperaProfileMigrator::CopyProxySettings(nsINIParser &aParser, GetInteger(aParser, "Proxy", "Use Automatic Proxy Configuration", &enabled); if (enabled) networkProxyType = 2; - - nsCAutoString configURL; - rv = aParser.GetString("Proxy", "Automatic Proxy Configuration URL", - configURL); - if (NS_SUCCEEDED(rv)) - aBranch->SetCharPref("network.proxy.autoconfig_url", configURL.get()); + nsXPIDLCString configURL; + err = aParser->GetStringAlloc("Proxy", "Automatic Proxy Configuration URL", getter_Copies(configURL), &length); + if (err == nsINIParser::OK) + aBranch->SetCharPref("network.proxy.autoconfig_url", configURL); GetInteger(aParser, "Proxy", "No Proxy Servers Check", &enabled); if (enabled) { - nsCAutoString servers; - rv = aParser.GetString("Proxy", "No Proxy Servers", servers); - if (NS_SUCCEEDED(rv)) + nsXPIDLCString servers; + err = aParser->GetStringAlloc("Proxy", "No Proxy Servers", getter_Copies(servers), &length); + if (err == nsINIParser::OK) ParseOverrideServers(servers.get(), aBranch); } @@ -502,26 +499,28 @@ nsOperaProfileMigrator::CopyProxySettings(nsINIParser &aParser, } nsresult -nsOperaProfileMigrator::GetInteger(nsINIParser &aParser, +nsOperaProfileMigrator::GetInteger(nsINIParser* aParser, char* aSectionName, char* aKeyName, PRInt32* aResult) { - nsCAutoString val; + char val[20]; + PRInt32 length = 20; - nsresult rv = aParser.GetString(aSectionName, aKeyName, val); - if (NS_FAILED(rv)) - return rv; + PRInt32 err = aParser->GetString(aSectionName, aKeyName, val, &length); + if (err != nsINIParser::OK) + return NS_ERROR_FAILURE; - *aResult = val.ToInteger((PRInt32*) &rv); + nsCAutoString valueStr((char*)val); + PRInt32 stringErr; + *aResult = valueStr.ToInteger(&stringErr); - return rv; + return NS_OK; } nsresult -nsOperaProfileMigrator::ParseColor(nsINIParser &aParser, - char* aSectionName, char** aResult) +nsOperaProfileMigrator::ParseColor(nsINIParser* aParser, char* aSectionName, char** aResult) { nsresult rv; PRInt32 r, g, b; @@ -542,37 +541,34 @@ nsOperaProfileMigrator::ParseColor(nsINIParser &aParser, } nsresult -nsOperaProfileMigrator::CopyUserContentSheet(nsINIParser &aParser) +nsOperaProfileMigrator::CopyUserContentSheet(nsINIParser* aParser) { - nsresult rv; + nsresult rv = NS_OK; - nsCAutoString userContentCSS; - rv = aParser.GetString("User Prefs", "Local CSS File", userContentCSS); - if (NS_FAILED(rv) || userContentCSS.Length() == 0) - return NS_OK; + nsXPIDLCString userContentCSS; + PRInt32 size; + PRInt32 err = aParser->GetStringAlloc("User Prefs", "Local CSS File", getter_Copies(userContentCSS), &size); + if (err == nsINIParser::OK && userContentCSS.Length() > 0) { + // Copy the file + nsCOMPtr userContentCSSFile(do_CreateInstance("@mozilla.org/file/local;1")); + if (!userContentCSSFile) + return NS_ERROR_OUT_OF_MEMORY; - // Copy the file - nsCOMPtr userContentCSSFile; - rv = NS_NewNativeLocalFile(userContentCSS, PR_TRUE, - getter_AddRefs(userContentCSSFile)); - if (NS_FAILED(rv)) - return NS_OK; + userContentCSSFile->InitWithNativePath(userContentCSS); + PRBool exists; + userContentCSSFile->Exists(&exists); + if (!exists) + return NS_OK; - PRBool exists; - rv = userContentCSSFile->Exists(&exists); - if (NS_FAILED(rv) || !exists) - return NS_OK; + nsCOMPtr profileChromeDir; + NS_GetSpecialDirectory(NS_APP_USER_CHROME_DIR, + getter_AddRefs(profileChromeDir)); + if (!profileChromeDir) + return NS_ERROR_OUT_OF_MEMORY; - nsCOMPtr profileChromeDir; - NS_GetSpecialDirectory(NS_APP_USER_CHROME_DIR, - getter_AddRefs(profileChromeDir)); - if (!profileChromeDir) - return NS_OK; - - userContentCSSFile->CopyToNative(profileChromeDir, - NS_LITERAL_CSTRING("userContent.css")); - - return NS_OK; + rv = userContentCSSFile->CopyToNative(profileChromeDir, nsDependentCString("userContent.css")); + } + return rv; } nsresult @@ -1055,20 +1051,17 @@ nsOperaProfileMigrator::CopySmartKeywords(nsIBookmarksService* aBMS, nsIStringBundle* aBundle, nsIRDFResource* aParentFolder) { - nsresult rv; + nsresult rv = NS_OK; nsCOMPtr smartKeywords; mOperaProfile->Clone(getter_AddRefs(smartKeywords)); smartKeywords->Append(NS_LITERAL_STRING("search.ini")); - nsCOMPtr lf(do_QueryInterface(smartKeywords)); - if (!lf) - return NS_OK; - - nsINIParser parser; - rv = parser.Init(lf); - if (NS_FAILED(rv)) - return NS_OK; + nsCAutoString path; + smartKeywords->GetNativePath(path); + nsINIParser* parser = new nsINIParser(path.get()); + if (!parser) + return NS_ERROR_OUT_OF_MEMORY; nsXPIDLString sourceNameOpera; aBundle->GetStringFromName(NS_LITERAL_STRING("sourceNameOpera").get(), @@ -1085,32 +1078,31 @@ nsOperaProfileMigrator::CopySmartKeywords(nsIBookmarksService* aBMS, aParentFolder, -1, getter_AddRefs(keywordsFolder)); PRInt32 sectionIndex = 1; - nsCAutoString name, url, keyword; + char section[35]; + nsXPIDLCString name, url, keyword; + PRInt32 keyValueLength = 0; do { - nsCAutoString section("Search Engine "); - section.AppendInt(sectionIndex++); - - rv = parser.GetString(section.get(), "Name", name); - if (NS_FAILED(rv)) + sprintf(section, "Search Engine %d", sectionIndex++); + PRInt32 err = parser->GetStringAlloc(section, "Name", getter_Copies(name), &keyValueLength); + if (err != nsINIParser::OK) break; - rv = parser.GetString(section.get(), "URL", url); - if (NS_FAILED(rv)) + err = parser->GetStringAlloc(section, "URL", getter_Copies(url), &keyValueLength); + if (err != nsINIParser::OK) continue; - - rv = parser.GetString(section.get(), "Key", keyword); - if (NS_FAILED(rv)) + err = parser->GetStringAlloc(section, "Key", getter_Copies(keyword), &keyValueLength); + if (err != nsINIParser::OK) continue; PRInt32 post; - rv = GetInteger(parser, section.get(), "Is post", &post); - if (NS_SUCCEEDED(rv) && post) + err = GetInteger(parser, section, "Is post", &post); + if (post) continue; if (url.IsEmpty() || keyword.IsEmpty() || name.IsEmpty()) continue; - NS_ConvertUTF8toUCS2 nameStr(name); + nsAutoString nameStr; nameStr.Assign(NS_ConvertUTF8toUCS2(name)); PRUint32 length = nameStr.Length(); PRInt32 index = 0; do { @@ -1160,6 +1152,11 @@ nsOperaProfileMigrator::CopySmartKeywords(nsIBookmarksService* aBMS, } while (1); + if (parser) { + delete parser; + parser = nsnull; + } + return rv; } #endif diff --git a/mozilla/browser/components/migration/src/nsOperaProfileMigrator.h b/mozilla/browser/components/migration/src/nsOperaProfileMigrator.h index 45c74046193..2927dd3efa0 100644 --- a/mozilla/browser/components/migration/src/nsOperaProfileMigrator.h +++ b/mozilla/browser/components/migration/src/nsOperaProfileMigrator.h @@ -92,10 +92,10 @@ public: protected: nsresult CopyPreferences(PRBool aReplace); - nsresult ParseColor(nsINIParser &aParser, char* aSectionName, char** aResult); - nsresult CopyUserContentSheet(nsINIParser &aParser); - nsresult CopyProxySettings(nsINIParser &aParser, nsIPrefBranch* aBranch); - nsresult GetInteger(nsINIParser &aParser, char* aSectionName, + nsresult ParseColor(nsINIParser* aParser, char* aSectionName, char** aResult); + nsresult CopyUserContentSheet(nsINIParser* aParser); + nsresult CopyProxySettings(nsINIParser* aParser, nsIPrefBranch* aBranch); + nsresult GetInteger(nsINIParser* aParser, char* aSectionName, char* aKeyName, PRInt32* aResult); nsresult CopyCookies(PRBool aReplace); diff --git a/mozilla/dom/src/base/nsScriptNameSpaceManager.cpp b/mozilla/dom/src/base/nsScriptNameSpaceManager.cpp index 966552f7ac6..5a50c953fca 100644 --- a/mozilla/dom/src/base/nsScriptNameSpaceManager.cpp +++ b/mozilla/dom/src/base/nsScriptNameSpaceManager.cpp @@ -51,7 +51,6 @@ #include "xptinfo.h" #include "nsXPIDLString.h" #include "nsReadableUtils.h" -#include "nsHashKeys.h" #include "nsDOMClassInfo.h" #include "nsCRT.h" diff --git a/mozilla/js/src/jsdhash.c b/mozilla/js/src/jsdhash.c index cd3006685ad..bbb909fc56c 100644 --- a/mozilla/js/src/jsdhash.c +++ b/mozilla/js/src/jsdhash.c @@ -207,9 +207,7 @@ JS_DHashTableInit(JSDHashTable *table, const JSDHashTableOps *ops, void *data, table->data = data; if (capacity < JS_DHASH_MIN_SIZE) capacity = JS_DHASH_MIN_SIZE; - - JS_CEILING_LOG2(log2, capacity); - + log2 = JS_CeilingLog2(capacity); capacity = JS_BIT(log2); if (capacity >= JS_DHASH_SIZE_LIMIT) return JS_FALSE; @@ -603,7 +601,7 @@ JS_PUBLIC_API(uint32) JS_DHashTableEnumerate(JSDHashTable *table, JSDHashEnumerator etor, void *arg) { char *entryAddr, *entryLimit; - uint32 i, capacity, entrySize, ceiling; + uint32 i, capacity, entrySize; JSBool didRemove; JSDHashEntryHdr *entry; JSDHashOperator op; @@ -645,11 +643,9 @@ JS_DHashTableEnumerate(JSDHashTable *table, JSDHashEnumerator etor, void *arg) capacity += capacity >> 1; if (capacity < JS_DHASH_MIN_SIZE) capacity = JS_DHASH_MIN_SIZE; - - JS_CEILING_LOG2(ceiling, capacity); - ceiling -= JS_DHASH_BITS - table->hashShift; - - (void) ChangeTable(table, ceiling); + (void) ChangeTable(table, + JS_CeilingLog2(capacity) + - (JS_DHASH_BITS - table->hashShift)); } return i; } diff --git a/mozilla/js/src/jsdhash.h b/mozilla/js/src/jsdhash.h index 42a7993c714..2aa1be4a711 100644 --- a/mozilla/js/src/jsdhash.h +++ b/mozilla/js/src/jsdhash.h @@ -439,7 +439,7 @@ JS_DHashTableInit(JSDHashTable *table, const JSDHashTableOps *ops, void *data, * we don't shrink on the very next remove after growing a table upon adding * an entry that brings entryCount past maxAlpha * tableSize. */ -extern JS_PUBLIC_API(void) +JS_PUBLIC_API(void) JS_DHashTableSetAlphaBounds(JSDHashTable *table, float maxAlpha, float minAlpha); diff --git a/mozilla/js/src/plify_jsdhash.sed b/mozilla/js/src/plify_jsdhash.sed index ea3b2e73428..0677cdafd65 100644 --- a/mozilla/js/src/plify_jsdhash.sed +++ b/mozilla/js/src/plify_jsdhash.sed @@ -4,7 +4,7 @@ * GENERATED BY js/src/plify_jsdhash.sed -- DO NOT EDIT!!! s/jsdhash_h___/pldhash_h___/ s/jsdhash\.bigdump/pldhash.bigdump/ -s/jstypes\.h/nscore.h/ +s/jstypes\.h/prtypes.h/ s/jsbit\.h/prbit.h/ s/jsdhash\.h/pldhash.h/ s/jsdhash\.c/pldhash.c/ @@ -23,8 +23,8 @@ s/\([^U]\)int32/\1PRInt32/g s/uint16/PRUint16/g s/\([^U]\)int16/\1PRInt16/g s/JSBool/PRBool/g -s/extern JS_PUBLIC_API(\([^()]*\))/NS_COM_GLUE \1/ -s/JS_PUBLIC_API(\([^()]*\))/\1/ +s/extern JS_PUBLIC_API/PR_EXTERN/ +s/JS_PUBLIC_API/PR_IMPLEMENT/ s/JS_DLL_CALLBACK/PR_CALLBACK/ s/JS_STATIC_DLL_CALLBACK/PR_STATIC_CALLBACK/ s/JS_NewDHashTable/PL_NewDHashTable/ diff --git a/mozilla/layout/style/nsCSSStyleSheet.cpp b/mozilla/layout/style/nsCSSStyleSheet.cpp index ae19fc817c9..195d14e65a0 100644 --- a/mozilla/layout/style/nsCSSStyleSheet.cpp +++ b/mozilla/layout/style/nsCSSStyleSheet.cpp @@ -91,7 +91,6 @@ #include "nsITextContent.h" #include "prlog.h" #include "nsCOMPtr.h" -#include "nsHashKeys.h" #include "nsStyleUtil.h" #include "nsQuickSort.h" #include "nsContentUtils.h" diff --git a/mozilla/toolkit/profile/src/Makefile.in b/mozilla/toolkit/profile/src/Makefile.in index e8cf7990276..7815a4a7889 100644 --- a/mozilla/toolkit/profile/src/Makefile.in +++ b/mozilla/toolkit/profile/src/Makefile.in @@ -60,6 +60,7 @@ LOCAL_INCLUDES = \ CPPSRCS = \ nsProfileLock.cpp \ nsToolkitProfileService.cpp \ + nsINIParser.cpp \ $(NULL) GARBAGE += nsProfileLock.cpp diff --git a/mozilla/toolkit/profile/src/nsINIParser.cpp b/mozilla/toolkit/profile/src/nsINIParser.cpp new file mode 100644 index 00000000000..159030df715 --- /dev/null +++ b/mozilla/toolkit/profile/src/nsINIParser.cpp @@ -0,0 +1,269 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla 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/MPL/ + * + * 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 Communicator client code, released + * March 31, 1998. + * + * 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): + * Samir Gehani + * Benjamin Smedberg + * + * 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 MPL, 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 MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + + +#include "nsINIParser.h" +#include "nsError.h" +#include "nsILocalFile.h" + +#include +#include + +nsINIParser::nsINIParser() : + mFileBuf(nsnull), + mFileBufSize(0) +{ } + +nsresult +nsINIParser::Init(nsILocalFile* aFile) +{ + NS_ASSERTION(aFile, "Null param."); + + nsresult rv; + FILE *fd; + long eofpos = 0; + int rd = 0; + + /* open the file */ + rv = aFile->OpenANSIFileDesc("r", &fd); + if (NS_FAILED(rv)) + return rv; + + /* get file size */ + if (fseek(fd, 0, SEEK_END) != 0) { + rv = NS_BASE_STREAM_OSERROR; + goto bail; + } + + eofpos = ftell(fd); + if (eofpos == 0) { + rv = NS_BASE_STREAM_OSERROR; + goto bail; + } + + /* malloc an internal buf the size of the file */ + mFileBuf = (char *) malloc((eofpos+1) * sizeof(char)); + if (!mFileBuf) { + rv = NS_ERROR_OUT_OF_MEMORY; + goto bail; + } + + mFileBufSize = eofpos; + + /* read the file in one swoop */ + if (fseek(fd, 0, SEEK_SET) != 0) { + rv = NS_BASE_STREAM_OSERROR; + goto bail; + } + + rd = fread((void *)mFileBuf, 1, eofpos, fd); + if (!rd) { + rv = NS_BASE_STREAM_OSERROR; + goto bail; + } + mFileBuf[mFileBufSize] = '\0'; + + /* close file */ + fclose(fd); + return NS_OK; + +bail: + if (fd) + fclose(fd); + + if (mFileBuf) { + free(mFileBuf); + mFileBuf = nsnull; + } + return NS_ERROR_FAILURE; +} + +nsINIParser::~nsINIParser() +{ + if (mFileBuf) { + free(mFileBuf); + mFileBuf = nsnull; + } +} + +nsresult +nsINIParser::GetString(const char *aSection, const char *aKey, + char *aValBuf, PRUint32 aIOValBufSize) +{ + NS_ASSERTION(aSection && aKey && aValBuf && aIOValBufSize, + "Null param!"); + + nsresult rv; + char *secPtr; + + /* find the section if it exists */ + rv = FindSection(aSection, &secPtr); + if (NS_FAILED(rv)) return rv; + + /* find the key if it exists in the valid section we found */ + rv = FindKey(secPtr, aKey, aValBuf, aIOValBufSize); + return rv; +} + +nsresult +nsINIParser::FindSection(const char *aSection, char **aOutSecPtr) +{ + char *currChar = mFileBuf; + char *nextSec = nsnull; + char *secClose = nsnull; + char *nextNL = nsnull; + int aSectionLen = strlen(aSection); + nsresult rv = NS_ERROR_FAILURE; + + while (currChar < (mFileBuf + mFileBufSize)) + { + // look for first '[' + nextSec = NULL; + nextSec = strchr(currChar, '['); + if (!nextSec) + break; + + currChar = nextSec + 1; + + // extract section name till first ']' + secClose = NULL; nextNL = NULL; + secClose = strchr(currChar, ']'); + nextNL = strchr(currChar, '\n'); + if ((!nextNL) || (nextNL < secClose)) + { + currChar = nextNL; + continue; + } + + // if section name matches we succeeded + if (strncmp(aSection, currChar, aSectionLen) == 0 + && secClose-currChar == aSectionLen) + { + *aOutSecPtr = secClose + 1; + rv = NS_OK; + break; + } + } + + return rv; +} + +nsresult +nsINIParser::FindKey(const char *aSecPtr, const char *aKey, char *aVal, int aIOValSize) +{ + const char *nextNL = nsnull; + const char *secEnd = nsnull; + const char *currLine = aSecPtr; + const char *nextEq = nsnull; + int aKeyLen = strlen(aKey); + + // determine the section end + secEnd = aSecPtr; +find_end: + if (secEnd) + secEnd = strchr(secEnd, '['); // search for next sec start + if (!secEnd) + { + secEnd = strchr(aSecPtr, '\0'); // else search for file end + if (!secEnd) + { + return NS_ERROR_FILE_CORRUPTED; + } + } + + // handle start section token ('[') in values for i18n + if (*secEnd == '[' && !(secEnd == aSecPtr || *(secEnd-1) == '\n')) + { + secEnd++; + goto find_end; + } + + while (currLine < secEnd) + { + nextNL = NULL; + nextNL = strchr(currLine, '\n'); + if (!nextNL) + nextNL = mFileBuf + mFileBufSize; + + // ignore commented lines (starting with ;) + if (currLine == strchr(currLine, ';')) + { + currLine = nextNL + 1; + continue; + } + + // extract key before '=' + nextEq = NULL; + nextEq = strchr(currLine, '='); + if (!nextEq || nextEq > nextNL) + { + currLine = nextNL + 1; + continue; + } + + // if key matches we succeeded + if (strncmp(currLine, aKey, aKeyLen) == 0 + && nextEq-currLine == aKeyLen) + { + // extract the value and return + if (aIOValSize < nextNL - nextEq) + { + *aVal = '\0'; + return NS_ERROR_LOSS_OF_SIGNIFICANT_DATA; + } + + PRUint32 len = nextNL - (nextEq + 1); + + // allows win32-style \r\n line endings + if ( *(nextEq + len) == '\r' ) + --len; + + strncpy(aVal, (nextEq + 1), len); + *(aVal + len) = 0; // null terminate + return NS_OK; + } + else + { + currLine = nextNL + 1; + } + } + + return NS_ERROR_FAILURE; +} diff --git a/mozilla/toolkit/profile/src/nsINIParser.h b/mozilla/toolkit/profile/src/nsINIParser.h new file mode 100644 index 00000000000..3cc30a70aa8 --- /dev/null +++ b/mozilla/toolkit/profile/src/nsINIParser.h @@ -0,0 +1,111 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla 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/MPL/ + * + * 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 Communicator client code, released + * March 31, 1998. + * + * 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): + * Samir Gehani + * Benjamin Smedberg + * + * 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 MPL, 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 MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +// This file was shamelessly copied from mozilla/xpinstall/wizard/unix/src2 + +#ifndef nsINIParser_h__ +#define nsINIParser_h__ + +#include "nscore.h" + +// hack alert: in static builds, nsINIParser here conflicts with nsINIParser +// in browser/components/migration. So we use a #define to make the symbols +// unique. +#define nsINIParser nsINITParser + +class nsILocalFile; + +class nsINIParser +{ +public: + nsINIParser(); + ~nsINIParser(); + +#if 0 // use nsresult instead + /** + * Errors + */ + enum INIResult + { + OK = 0, + E_READ = -701, + E_MEM = -702, + E_PARAM = -703, + E_NO_SEC = -704, + E_NO_KEY = -705, + E_SEC_CORRUPT = -706, + E_SMALL_BUF = -707 + }; +#endif + + /** + * Initialize the INIParser with a nsILocalFile. If this method fails, no + * other methods should be called. + */ + nsresult Init(nsILocalFile* aFile); + + /** + * GetString + * + * Gets the value of the specified key in the specified section + * of the INI file represented by this instance. The value is stored + * in the supplied buffer. The buffer size is provided as input and + * the actual bytes used by the value is set in the in/out size param. + * + * @param aSection section name + * @param aKey key name + * @param aValBuf user supplied buffer + * @param aIOValBufSize buf size on input; actual buf used on output + * + * @return mError operation success code + */ + nsresult GetString(const char *aSection, const char *aKey, + char *aValBuf, PRUint32 aIOValBufSize ); + +private: + nsresult FindSection(const char *aSection, char **aOutSecPtr); + nsresult FindKey(const char *aSecPtr, const char *aKey, + char *aVal, int aIOValSize); + + char *mFileBuf; + int mFileBufSize; +}; + +#endif /* nsINIParser_h__ */ diff --git a/mozilla/toolkit/profile/src/nsToolkitProfileService.cpp b/mozilla/toolkit/profile/src/nsToolkitProfileService.cpp index fe48a39579c..b91ad5b62ce 100644 --- a/mozilla/toolkit/profile/src/nsToolkitProfileService.cpp +++ b/mozilla/toolkit/profile/src/nsToolkitProfileService.cpp @@ -403,37 +403,37 @@ nsToolkitProfileService::Init() nsINIParser parser; rv = parser.Init(mListFile); - // Init does not fail on parsing errors, only on OOM/really unexpected - // conditions. - if (NS_FAILED(rv)) - return rv; + // Parsing errors are troublesome... we're gonna continue even on + // parsing errors, and let people manually re-locate their profile + // if something goes wacky - nsCAutoString buffer; - rv = parser.GetString("General", "StartWithLastProfile", buffer); - if (NS_SUCCEEDED(rv) && buffer.EqualsLiteral("0")) + char parserBuf[MAXPATHLEN]; + rv = parser.GetString("General", "StartWithLastProfile", parserBuf, MAXPATHLEN); + if (NS_SUCCEEDED(rv) && strcmp("0", parserBuf) == 0) mStartWithLast = PR_FALSE; nsToolkitProfile* currentProfile = nsnull; + nsCAutoString filePath; unsigned int c = 0; for (c = 0; PR_TRUE; ++c) { - nsCAutoString profileID("Profile"); - profileID.AppendInt(c); + char profileID[12]; + sprintf(profileID, "Profile%u", c); - rv = parser.GetString(profileID.get(), "IsRelative", buffer); + rv = parser.GetString(profileID, "IsRelative", parserBuf, MAXPATHLEN); if (NS_FAILED(rv)) break; - PRBool isRelative = buffer.EqualsLiteral("1"); + PRBool isRelative = (strcmp(parserBuf, "1") == 0); - nsCAutoString filePath; - - rv = parser.GetString(profileID.get(), "Path", filePath); + rv = parser.GetString(profileID, "Path", parserBuf, MAXPATHLEN); if (NS_FAILED(rv)) { NS_ERROR("Malformed profiles.ini: Path= not found"); continue; } - rv = parser.GetString(profileID.get(), "Name", buffer); + filePath = parserBuf; + + rv = parser.GetString(profileID, "Name", parserBuf, MAXPATHLEN); if (NS_FAILED(rv)) { NS_ERROR("Malformed profiles.ini: Name= not found"); continue; @@ -462,13 +462,13 @@ nsToolkitProfileService::Init() localDir = rootDir; } - currentProfile = new nsToolkitProfile(buffer, + currentProfile = new nsToolkitProfile(nsDependentCString(parserBuf), rootDir, localDir, currentProfile); NS_ENSURE_TRUE(currentProfile, NS_ERROR_OUT_OF_MEMORY); - rv = parser.GetString(profileID.get(), "Default", buffer); - if (NS_SUCCEEDED(rv) && buffer.EqualsLiteral("1")) + rv = parser.GetString(profileID, "Default", parserBuf, MAXPATHLEN); + if (NS_SUCCEEDED(rv) && strcmp("1", parserBuf) == 0) mChosen = currentProfile; } diff --git a/mozilla/toolkit/xre/nsAppRunner.cpp b/mozilla/toolkit/xre/nsAppRunner.cpp index f42a0303d95..8aef73474dd 100644 --- a/mozilla/toolkit/xre/nsAppRunner.cpp +++ b/mozilla/toolkit/xre/nsAppRunner.cpp @@ -1647,20 +1647,21 @@ CheckCompatibility(nsIFile* aProfileDir, const nsCString& aVersion, if (NS_FAILED(rv)) return PR_FALSE; - nsCAutoString buf; - rv = parser.GetString("Compatibility", "LastVersion", buf); + char buffer[MAXPATHLEN]; + rv = parser.GetString("Compatibility", "LastVersion", buffer, sizeof(buffer)); if (NS_FAILED(rv)) return PR_FALSE; - if (!aVersion.Equals(buf)) + if (!aVersion.Equals(buffer)) return PR_FALSE; - rv = parser.GetString("Compatibility", "LastPlatformDir", buf); + rv = parser.GetString("Compatibility", "LastPlatformDir", + buffer, sizeof(buffer)); if (NS_FAILED(rv)) return PR_FALSE; nsCOMPtr lf; - rv = NS_NewNativeLocalFile(buf, PR_FALSE, + rv = NS_NewNativeLocalFile(nsDependentCString(buffer), PR_FALSE, getter_AddRefs(lf)); if (NS_FAILED(rv)) return PR_FALSE; @@ -1671,11 +1672,12 @@ CheckCompatibility(nsIFile* aProfileDir, const nsCString& aVersion, return PR_FALSE; if (aAppDir) { - rv = parser.GetString("Compatibility", "LastAppDir", buf); + rv = parser.GetString("Compatibility", "LastAppDir", + buffer, sizeof(buffer)); if (NS_FAILED(rv)) return PR_FALSE; - rv = NS_NewNativeLocalFile(buf, PR_FALSE, + rv = NS_NewNativeLocalFile(nsDependentCString(buffer), PR_FALSE, getter_AddRefs(lf)); if (NS_FAILED(rv)) return PR_FALSE; diff --git a/mozilla/toolkit/xre/nsXREDirProvider.cpp b/mozilla/toolkit/xre/nsXREDirProvider.cpp index 2bd31d2d80d..0fcbb29b5f2 100644 --- a/mozilla/toolkit/xre/nsXREDirProvider.cpp +++ b/mozilla/toolkit/xre/nsXREDirProvider.cpp @@ -314,9 +314,7 @@ LoadDirsIntoArray(nsIFile* aComponentsList, const char* aSection, { nsINIParser parser; nsCOMPtr lf(do_QueryInterface(aComponentsList)); - nsresult rv = parser.Init(lf); - if (NS_FAILED(rv)) - return; + parser.Init(lf); NS_NAMED_LITERAL_CSTRING(platform, "platform"); NS_NAMED_LITERAL_CSTRING(osTarget, OS_TARGET); @@ -324,13 +322,14 @@ LoadDirsIntoArray(nsIFile* aComponentsList, const char* aSection, NS_NAMED_LITERAL_CSTRING(targetOSABI, TARGET_OS_ABI); #endif + nsresult rv; + char parserBuf[MAXPATHLEN]; + char buf[18]; PRInt32 i = 0; do { - nsCAutoString buf("Extension"); - buf.AppendInt(i++); + sprintf(buf, "Extension%d", i++); - nsCAutoString path; - rv = parser.GetString(aSection, buf.get(), path); + rv = parser.GetString(aSection, buf, parserBuf, MAXPATHLEN); if (NS_FAILED(rv)) break; @@ -342,7 +341,7 @@ LoadDirsIntoArray(nsIFile* aComponentsList, const char* aSection, #ifdef TARGET_OS_ABI nsCOMPtr platformABIDir; #endif - rv = dir->SetPersistentDescriptor(path); + rv = dir->SetPersistentDescriptor(nsDependentCString(parserBuf)); if (NS_FAILED(rv)) continue; diff --git a/mozilla/xpcom/build/Makefile.in b/mozilla/xpcom/build/Makefile.in index 5b6a954cc14..9b48ae4ac54 100644 --- a/mozilla/xpcom/build/Makefile.in +++ b/mozilla/xpcom/build/Makefile.in @@ -73,13 +73,9 @@ ifneq (,$(filter mac cocoa,$(MOZ_WIDGET_TOOLKIT))) REQUIRES += macmorefiles endif -CSRCS = \ - $(XPCOM_GLUE_SRC_LCSRCS) \ - $(NULL) - CPPSRCS = \ - $(XPCOM_GLUE_SRC_LCPPSRCS) \ - $(XPCOM_GLUENS_SRC_LCPPSRCS) \ + $(XPCOM_GLUE_SRC_LCSRCS) \ + $(XPCOM_GLUENS_SRC_LCSRCS) \ nsXPComInit.cpp \ nsStringAPI.cpp \ $(NULL) @@ -182,5 +178,5 @@ EXTRA_DSO_LDOPTS += $(call EXPAND_LIBNAME,imagehlp) endif endif # WINNT -export:: $(XPCOM_GLUE_SRC_CSRCS) $(XPCOM_GLUE_SRC_CPPSRCS) $(XPCOM_GLUENS_SRC_CPPSRCS) +export:: $(XPCOM_GLUE_SRC_CSRCS) $(XPCOM_GLUENS_SRC_CSRCS) $(INSTALL) $^ . diff --git a/mozilla/xpcom/ds/Makefile.in b/mozilla/xpcom/ds/Makefile.in index 638cfd09a3d..0e9edade293 100644 --- a/mozilla/xpcom/ds/Makefile.in +++ b/mozilla/xpcom/ds/Makefile.in @@ -52,6 +52,10 @@ REQUIRES = \ string \ $(NULL) +CSRCS = \ + pldhash.c \ + $(NULL) + CPPSRCS = \ nsAtomTable.cpp \ nsAtomService.cpp \ @@ -75,6 +79,7 @@ CPPSRCS = \ nsSupportsArray.cpp \ nsSupportsArrayEnumerator.cpp \ nsSupportsPrimitives.cpp \ + nsTHashtable.cpp \ nsUnicharBuffer.cpp \ nsVariant.cpp \ nsVoidArray.cpp \ @@ -89,29 +94,37 @@ CPPSRCS = \ EXPORTS = \ nsAtomService.h \ + nsBaseHashtable.h \ nsCheapSets.h \ + nsClassHashtable.h \ nsCppSharedAllocator.h \ nsCRT.h \ + nsDataHashtable.h \ nsDeque.h \ nsDoubleHashtable.h \ nsEnumeratorUtils.h \ nsFixedSizeAllocator.h \ nsHashSets.h \ + nsHashKeys.h \ nsHashtable.h \ nsIByteBuffer.h \ nsIUnicharBuffer.h \ nsInt64.h \ + nsInterfaceHashtable.h \ nsObserverService.h \ nsQuickSort.h \ nsRecyclingAllocator.h \ + nsRefPtrHashtable.h \ nsStaticNameTable.h \ nsStaticAtom.h \ nsSupportsArray.h \ nsSupportsPrimitives.h \ + nsTHashtable.h \ nsTime.h \ nsUnitConversion.h \ nsVariant.h \ nsVoidArray.h \ + pldhash.h \ nsTextFormatter.h \ nsValueArray.h \ nsArray.h \ diff --git a/mozilla/xpcom/ds/nsBaseHashtable.h b/mozilla/xpcom/ds/nsBaseHashtable.h new file mode 100644 index 00000000000..ad06492b3c2 --- /dev/null +++ b/mozilla/xpcom/ds/nsBaseHashtable.h @@ -0,0 +1,458 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla 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/MPL/ + * + * 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 C++ hashtable templates. + * + * The Initial Developer of the Original Code is + * Benjamin Smedberg. + * Portions created by the Initial Developer are Copyright (C) 2002 + * 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 MPL, 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 MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#ifndef nsBaseHashtable_h__ +#define nsBaseHashtable_h__ + +#include "nsTHashtable.h" +#include "prlock.h" +#include "nsDebug.h" + +template +class nsBaseHashtable; // forward declaration + +/** + * the private nsTHashtable::EntryType class used by nsBaseHashtable + * @see nsTHashtable for the specification of this class + * @see nsBaseHashtable for template parameters + */ +template +class nsBaseHashtableET : public KeyClass +{ +public: + DataType mData; + friend class nsTHashtable< nsBaseHashtableET >; + +private: + typedef typename KeyClass::KeyType KeyType; + typedef typename KeyClass::KeyTypePointer KeyTypePointer; + + nsBaseHashtableET(KeyTypePointer aKey); + nsBaseHashtableET(nsBaseHashtableET& toCopy); + ~nsBaseHashtableET(); +}; + +/** + * templated hashtable for simple data types + * This class manages simple data types that do not need construction or + * destruction. Thread-safety is optional, via a flag in Init() + * + * @param KeyClass a wrapper-class for the hashtable key, see nsHashKeys.h + * for a complete specification. + * @param DataType the datatype stored in the hashtable, + * for example, PRUint32 or nsCOMPtr. If UserDataType is not the same, + * DataType must implicitly cast to UserDataType + * @param UserDataType the user sees, for example PRUint32 or nsISupports* + */ +template +class nsBaseHashtable : + protected nsTHashtable< nsBaseHashtableET > +{ +public: + typedef typename KeyClass::KeyType KeyType; + typedef nsBaseHashtableET EntryType; + + // default constructor+destructor are fine + + /** + * Initialize the object. + * @param initSize the initial number of buckets in the hashtable, + * default 16 + * @param threadSafe whether to provide read/write + * locking on all class methods + * @return PR_TRUE if the object was initialized properly. + */ + PRBool Init(PRUint32 initSize = PL_DHASH_MIN_SIZE) + { return nsTHashtable::Init(initSize); } + + /** + * Check whether the table has been initialized. + * This function is especially useful for static hashtables. + * @return PR_TRUE if the table has been initialized. + */ + PRBool IsInitialized() const { return this->mTable.entrySize; } + + /** + * Return the number of entries in the table. + * @return number of entries + */ + PRUint32 Count() const + { return nsTHashtable::Count(); } + + /** + * retrieve the value for a key. + * @param aKey the key to retreive + * @param pData data associated with this key will be placed at this + * pointer. If you only need to check if the key exists, pData + * may be null. + * @return PR_TRUE if the key exists. If key does not exist, pData is not + * modified. + */ + PRBool Get(KeyType aKey, UserDataType* pData) const + { + EntryType* ent = GetEntry(aKey); + + if (!ent) + return PR_FALSE; + + if (pData) + *pData = ent->mData; + + return PR_TRUE; + } + + /** + * put a new value for the associated key + * @param aKey the key to put + * @param aData the new data + * @return always PR_TRUE, unless memory allocation failed + */ + PRBool Put(KeyType aKey, UserDataType aData) + { + EntryType* ent = PutEntry(aKey); + + if (!ent) + return PR_FALSE; + + ent->mData = aData; + + return PR_TRUE; + } + + /** + * remove the data for the associated key + * @param aKey the key to remove from the hashtable + */ + void Remove(KeyType aKey) { RemoveEntry(aKey); } + + /** + * function type provided by the application for enumeration. + * @param aKey the key being enumerated + * @param aData data being enumerated + * @parm userArg passed unchanged from Enumerate + * @return either + * @link PLDHashOperator::PL_DHASH_NEXT PL_DHASH_NEXT @endlink or + * @link PLDHashOperator::PL_DHASH_STOP PL_DHASH_STOP @endlink + */ + typedef PLDHashOperator + (*PR_CALLBACK EnumReadFunction)(KeyType aKey, + UserDataType aData, + void* userArg); + + /** + * enumerate entries in the hashtable, without allowing changes + * this function read-locks the hashtable, so other threads may read keys + * at the same time in multi-thread environments. + * @param enumFunc enumeration callback + * @param userArg passed unchanged to the EnumReadFunction + */ + PRUint32 EnumerateRead(EnumReadFunction enumFunc, void* userArg) const + { + NS_ASSERTION(this->mTable.entrySize, + "nsBaseHashtable was not initialized properly."); + + s_EnumReadArgs enumData = { enumFunc, userArg }; + return PL_DHashTableEnumerate(NS_CONST_CAST(PLDHashTable*, &this->mTable), + s_EnumReadStub, + &enumData); + } + + /** + * function type provided by the application for enumeration. + * @param aKey the key being enumerated + * @param aData Reference to data being enumerated, may be altered. e.g. for + * nsInterfaceHashtable this is an nsCOMPtr reference... + * @parm userArg passed unchanged from Enumerate + * @return bitflag combination of + * @link PLDHashOperator::PL_DHASH_REMOVE @endlink, + * @link PLDHashOperator::PL_DHASH_NEXT PL_DHASH_NEXT @endlink, or + * @link PLDHashOperator::PL_DHASH_STOP PL_DHASH_STOP @endlink + */ + typedef PLDHashOperator + (*PR_CALLBACK EnumFunction)(KeyType aKey, + DataType& aData, + void* userArg); + + /** + * enumerate entries in the hashtable, allowing changes. This + * functions write-locks the hashtable. + * @param enumFunc enumeration callback + * @param userArg passed unchanged to the EnumFunction + */ + PRUint32 Enumerate(EnumFunction enumFunc, void* userArg) + { + NS_ASSERTION(this->mTable.entrySize, + "nsBaseHashtable was not initialized properly."); + + s_EnumArgs enumData = { enumFunc, userArg }; + return PL_DHashTableEnumerate(&this->mTable, + s_EnumStub, + &enumData); + } + + /** + * reset the hashtable, removing all entries + */ + void Clear() { nsTHashtable::Clear(); } + +protected: + /** + * used internally during EnumerateRead. Allocated on the stack. + * @param func the enumerator passed to EnumerateRead + * @param userArg the userArg passed to EnumerateRead + */ + struct s_EnumReadArgs + { + EnumReadFunction func; + void* userArg; + }; + + static PLDHashOperator s_EnumReadStub(PLDHashTable *table, + PLDHashEntryHdr *hdr, + PRUint32 number, + void *arg); + + struct s_EnumArgs + { + EnumFunction func; + void* userArg; + }; + + static PLDHashOperator s_EnumStub(PLDHashTable *table, + PLDHashEntryHdr *hdr, + PRUint32 number, + void *arg); +}; + +/** + * This class is a thread-safe version of nsBaseHashtable. + */ +template +class nsBaseHashtableMT : + protected nsBaseHashtable +{ +public: + typedef typename + nsBaseHashtable::EntryType EntryType; + typedef typename + nsBaseHashtable::KeyType KeyType; + typedef typename + nsBaseHashtable::EnumFunction EnumFunction; + typedef typename + nsBaseHashtable::EnumReadFunction EnumReadFunction; + + nsBaseHashtableMT() : mLock(nsnull) { } + ~nsBaseHashtableMT(); + + PRBool Init(PRUint32 initSize = PL_DHASH_MIN_SIZE); + PRBool IsInitialized() const { return (PRBool) mLock; } + PRUint32 Count() const; + PRBool Get(KeyType aKey, UserDataType* pData) const; + PRBool Put(KeyType aKey, UserDataType aData); + void Remove(KeyType aKey); + + PRUint32 EnumerateRead(EnumReadFunction enumFunc, void* userArg) const; + PRUint32 Enumerate(EnumFunction enumFunc, void* userArg); + void Clear(); + +protected: + PRLock* mLock; +}; + + +// +// nsBaseHashtableET definitions +// + +template +nsBaseHashtableET::nsBaseHashtableET(KeyTypePointer aKey) : + KeyClass(aKey) +{ } + +template +nsBaseHashtableET::nsBaseHashtableET + (nsBaseHashtableET& toCopy) : + KeyClass(toCopy), + mData(toCopy.mData) +{ } + +template +nsBaseHashtableET::~nsBaseHashtableET() +{ } + + +// +// nsBaseHashtable definitions +// + +template +PLDHashOperator +nsBaseHashtable::s_EnumReadStub + (PLDHashTable *table, PLDHashEntryHdr *hdr, PRUint32 number, void* arg) +{ + EntryType* ent = NS_STATIC_CAST(EntryType*, hdr); + s_EnumReadArgs* eargs = (s_EnumReadArgs*) arg; + + PLDHashOperator res = (eargs->func)(ent->GetKey(), ent->mData, eargs->userArg); + + NS_ASSERTION( !(res & PL_DHASH_REMOVE ), + "PL_DHASH_REMOVE return during const enumeration; ignoring."); + + if (res & PL_DHASH_STOP) + return PL_DHASH_STOP; + + return PL_DHASH_NEXT; +} + +template +PLDHashOperator +nsBaseHashtable::s_EnumStub + (PLDHashTable *table, PLDHashEntryHdr *hdr, PRUint32 number, void* arg) +{ + EntryType* ent = NS_STATIC_CAST(EntryType*, hdr); + s_EnumArgs* eargs = (s_EnumArgs*) arg; + + return (eargs->func)(ent->GetKey(), ent->mData, eargs->userArg); +} + + +// +// nsBaseHashtableMT definitions +// + +template +nsBaseHashtableMT::~nsBaseHashtableMT() +{ + if (this->mLock) + PR_DestroyLock(this->mLock); +} + +template +PRBool +nsBaseHashtableMT::Init(PRUint32 initSize) +{ + if (!nsTHashtable::IsInitialized() && !nsTHashtable::Init(initSize)) + return PR_FALSE; + + this->mLock = PR_NewLock(); + NS_WARN_IF_FALSE(this->mLock, "Error creating lock during nsBaseHashtableL::Init()"); + + return (this->mLock != nsnull); +} + +template +PRUint32 +nsBaseHashtableMT::Count() const +{ + PR_Lock(this->mLock); + PRUint32 count = nsTHashtable::Count(); + PR_Unlock(this->mLock); + + return count; +} + +template +PRBool +nsBaseHashtableMT::Get(KeyType aKey, + UserDataType* pData) const +{ + PR_Lock(this->mLock); + PRBool res = + nsBaseHashtable::Get(aKey, pData); + PR_Unlock(this->mLock); + + return res; +} + +template +PRBool +nsBaseHashtableMT::Put(KeyType aKey, + UserDataType aData) +{ + PR_Lock(this->mLock); + PRBool res = + nsBaseHashtable::Put(aKey, aData); + PR_Unlock(this->mLock); + + return res; +} + +template +void +nsBaseHashtableMT::Remove(KeyType aKey) +{ + PR_Lock(this->mLock); + nsBaseHashtable::Remove(aKey); + PR_Unlock(this->mLock); +} + +template +PRUint32 +nsBaseHashtableMT::EnumerateRead + (EnumReadFunction fEnumCall, void* userArg) const +{ + PR_Lock(this->mLock); + PRUint32 count = + nsBaseHashtable::EnumerateRead(fEnumCall, userArg); + PR_Unlock(this->mLock); + + return count; +} + +template +PRUint32 +nsBaseHashtableMT::Enumerate + (EnumFunction fEnumCall, void* userArg) +{ + PR_Lock(this->mLock); + PRUint32 count = + nsBaseHashtable::Enumerate(fEnumCall, userArg); + PR_Unlock(this->mLock); + + return count; +} + +template +void +nsBaseHashtableMT::Clear() +{ + PR_Lock(this->mLock); + nsBaseHashtable::Clear(); + PR_Unlock(this->mLock); +} + +#endif // nsBaseHashtable_h__ diff --git a/mozilla/xpcom/ds/nsClassHashtable.h b/mozilla/xpcom/ds/nsClassHashtable.h new file mode 100644 index 00000000000..53ec165f83d --- /dev/null +++ b/mozilla/xpcom/ds/nsClassHashtable.h @@ -0,0 +1,149 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla 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/MPL/ + * + * 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 C++ hashtable templates. + * + * The Initial Developer of the Original Code is + * Benjamin Smedberg. + * Portions created by the Initial Developer are Copyright (C) 2002 + * 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 MPL, 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 MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#ifndef nsClassHashtable_h__ +#define nsClassHashtable_h__ + +#include "nsBaseHashtable.h" +#include "nsHashKeys.h" +#include "nsAutoPtr.h" + +/** + * templated hashtable class maps keys to C++ object pointers. + * See nsBaseHashtable for complete declaration. + * @param KeyClass a wrapper-class for the hashtable key, see nsHashKeys.h + * for a complete specification. + * @param Class the class-type being wrapped + * @see nsInterfaceHashtable, nsClassHashtable + */ +template +class nsClassHashtable : + public nsBaseHashtable< KeyClass, nsAutoPtr, T* > +{ +public: + typedef typename KeyClass::KeyType KeyType; + typedef T* UserDataType; + + /** + * @copydoc nsBaseHashtable::Get + * @param pData if the key doesn't exist, pData will be set to nsnull. + */ + PRBool Get(KeyType aKey, UserDataType* pData) const; +}; + + +/** + * Thread-safe version of nsClassHashtable + * @param KeyClass a wrapper-class for the hashtable key, see nsHashKeys.h + * for a complete specification. + * @param Class the class-type being wrapped + * @see nsInterfaceHashtable, nsClassHashtable + */ +template +class nsClassHashtableMT : + public nsBaseHashtableMT< KeyClass, nsAutoPtr, T* > +{ +public: + typedef typename KeyClass::KeyType KeyType; + typedef T* UserDataType; + + /** + * @copydoc nsBaseHashtable::Get + * @param pData if the key doesn't exist, pData will be set to nsnull. + */ + PRBool Get(KeyType aKey, UserDataType* pData) const; +}; + + +// +// nsClassHashtable definitions +// + +template +PRBool +nsClassHashtable::Get(KeyType aKey, T** retVal) const +{ + typename nsBaseHashtable,T*>::EntryType* ent = + GetEntry(aKey); + + if (ent) + { + if (retVal) + *retVal = ent->mData; + + return PR_TRUE; + } + + if (retVal) + *retVal = nsnull; + + return PR_FALSE; +} + + +// +// nsClassHashtableMT definitions +// + +template +PRBool +nsClassHashtableMT::Get(KeyType aKey, T** retVal) const +{ + PR_Lock(this->mLock); + + typename nsBaseHashtableMT,T*>::EntryType* ent = + GetEntry(aKey); + + if (ent) + { + if (retVal) + *retVal = ent->mData; + + PR_Unlock(this->mLock); + + return PR_TRUE; + } + + if (retVal) + *retVal = nsnull; + + PR_Unlock(this->mLock); + + return PR_FALSE; +} + +#endif // nsClassHashtable_h__ diff --git a/mozilla/xpcom/ds/nsDoubleHashtable.h b/mozilla/xpcom/ds/nsDoubleHashtable.h index 36c10d621c4..27bf4ce53cd 100644 --- a/mozilla/xpcom/ds/nsDoubleHashtable.h +++ b/mozilla/xpcom/ds/nsDoubleHashtable.h @@ -45,7 +45,7 @@ #include "pldhash.h" #include "nscore.h" #include "nsString.h" -#include "nsHashKeys.h" +#include "nsReadableUtils.h" /* * This file provides several major things to make PLDHashTable easier to use: diff --git a/mozilla/xpcom/ds/nsHashKeys.h b/mozilla/xpcom/ds/nsHashKeys.h new file mode 100644 index 00000000000..8a6d272eaf9 --- /dev/null +++ b/mozilla/xpcom/ds/nsHashKeys.h @@ -0,0 +1,315 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla 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/MPL/ + * + * 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 C++ hashtable templates. + * + * The Initial Developer of the Original Code is + * Benjamin Smedberg. + * Portions created by the Initial Developer are Copyright (C) 2002 + * 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 MPL, 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 MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#ifndef nsTHashKeys_h__ +#define nsTHashKeys_h__ + +#include "nsAString.h" +#include "nsString.h" +#include "nsID.h" +#include "nsCRT.h" +#include "nsReadableUtils.h" +#include "nsISupports.h" +#include "nsCOMPtr.h" +#include "pldhash.h" +#include NEW_H + +/** @file nsHashKeys.h + * standard HashKey classes for nsBaseHashtable and relatives. Each of these + * classes follows the nsTHashtable::EntryType specification + * + * Lightweight keytypes provided here: + * nsStringHashKey + * nsCStringHashKey + * nsUint32HashKey + * nsISupportsHashKey + * nsIDHashKey + * nsDepCharHashKey + */ + +/** + * hashkey wrapper using nsAString KeyType + * + * @see nsTHashtable::EntryType for specification + */ +class NS_COM nsStringHashKey : public PLDHashEntryHdr +{ +public: + typedef const nsAString& KeyType; + typedef const nsAString* KeyTypePointer; + + nsStringHashKey(KeyTypePointer aStr) : mStr(*aStr) { } + nsStringHashKey(const nsStringHashKey& toCopy) : mStr(toCopy.mStr) { } + ~nsStringHashKey() { } + + KeyType GetKey() const { return mStr; } + KeyTypePointer GetKeyPointer() const { return &mStr; } + PRBool KeyEquals(const KeyTypePointer aKey) const + { + return mStr.Equals(*aKey); + } + + static KeyTypePointer KeyToPointer(KeyType aKey) { return &aKey; } + static PLDHashNumber HashKey(const KeyTypePointer aKey) + { + return HashString(*aKey); + } + enum { ALLOW_MEMMOVE = PR_TRUE }; + +private: + const nsString mStr; +}; + +/** + * hashkey wrapper using nsACString KeyType + * + * @see nsTHashtable::EntryType for specification + */ +class NS_COM nsCStringHashKey : public PLDHashEntryHdr +{ +public: + typedef const nsACString& KeyType; + typedef const nsACString* KeyTypePointer; + + nsCStringHashKey(const nsACString* aStr) : mStr(*aStr) { } + nsCStringHashKey(const nsCStringHashKey& toCopy) : mStr(toCopy.mStr) { } + ~nsCStringHashKey() { } + + KeyType GetKey() const { return mStr; } + KeyTypePointer GetKeyPointer() const { return &mStr; } + + PRBool KeyEquals(KeyTypePointer aKey) const { return mStr.Equals(*aKey); } + + static KeyTypePointer KeyToPointer(KeyType aKey) { return &aKey; } + static PLDHashNumber HashKey(KeyTypePointer aKey) + { + return HashString(*aKey); + } + enum { ALLOW_MEMMOVE = PR_TRUE }; + +private: + const nsCString mStr; +}; + +/** + * hashkey wrapper using PRUint32 KeyType + * + * @see nsTHashtable::EntryType for specification + */ +class NS_COM nsUint32HashKey : public PLDHashEntryHdr +{ +public: + typedef const PRUint32& KeyType; + typedef const PRUint32* KeyTypePointer; + + nsUint32HashKey(KeyTypePointer aKey) : mValue(*aKey) { } + nsUint32HashKey(const nsUint32HashKey& toCopy) : mValue(toCopy.mValue) { } + ~nsUint32HashKey() { } + + KeyType GetKey() const { return mValue; } + KeyTypePointer GetKeyPointer() const { return &mValue; } + PRBool KeyEquals(KeyTypePointer aKey) const { return *aKey == mValue; } + + static KeyTypePointer KeyToPointer(KeyType aKey) { return &aKey; } + static PLDHashNumber HashKey(KeyTypePointer aKey) { return *aKey; } + enum { ALLOW_MEMMOVE = PR_TRUE }; + +private: + const PRUint32 mValue; +}; + +/** + * hashkey wrapper using nsISupports* KeyType + * + * @see nsTHashtable::EntryType for specification + */ +class NS_COM nsISupportsHashKey : public PLDHashEntryHdr +{ +public: + typedef nsISupports* KeyType; + typedef const nsISupports* KeyTypePointer; + + nsISupportsHashKey(const nsISupports* key) : + mSupports(NS_CONST_CAST(nsISupports*,key)) { } + nsISupportsHashKey(const nsISupportsHashKey& toCopy) : + mSupports(toCopy.mSupports) { } + ~nsISupportsHashKey() { } + + KeyType GetKey() const { return mSupports; } + KeyTypePointer GetKeyPointer() const { return mSupports; } + + PRBool KeyEquals(KeyTypePointer aKey) const { return aKey == mSupports; } + + static KeyTypePointer KeyToPointer(KeyType aKey) { return aKey; } + static PLDHashNumber HashKey(KeyTypePointer aKey) + { + return NS_PTR_TO_INT32(aKey) >>2; + } + enum { ALLOW_MEMMOVE = PR_TRUE }; + +private: + nsCOMPtr mSupports; +}; + +/** + * hashkey wrapper using void* KeyType + * + * @see nsTHashtable::EntryType for specification + */ +class NS_COM nsVoidPtrHashKey : public PLDHashEntryHdr +{ +public: + typedef const void* KeyType; + typedef const void* KeyTypePointer; + + nsVoidPtrHashKey(const void* key) : + mKey(key) { } + nsVoidPtrHashKey(const nsVoidPtrHashKey& toCopy) : + mKey(toCopy.mKey) { } + ~nsVoidPtrHashKey() { } + + KeyType GetKey() const { return mKey; } + KeyTypePointer GetKeyPointer() const { return mKey; } + + PRBool KeyEquals(KeyTypePointer aKey) const { return aKey == mKey; } + + static KeyTypePointer KeyToPointer(KeyType aKey) { return aKey; } + static PLDHashNumber HashKey(KeyTypePointer aKey) + { + return NS_PTR_TO_INT32(aKey) >>2; + } + enum { ALLOW_MEMMOVE = PR_TRUE }; + +private: + const void* mKey; +}; + +/** + * hashkey wrapper using nsID KeyType + * + * @see nsTHashtable::EntryType for specification + */ +class NS_COM nsIDHashKey : public PLDHashEntryHdr +{ +public: + typedef const nsID& KeyType; + typedef const nsID* KeyTypePointer; + + nsIDHashKey(const nsID* id) : mID(*id) { } + nsIDHashKey(const nsIDHashKey& toCopy) : mID(toCopy.mID) { } + ~nsIDHashKey() { } + + KeyType GetKey() const { return mID; } + KeyTypePointer GetKeyPointer() const { return &mID; } + + PRBool KeyEquals(KeyTypePointer aKey) const { return aKey->Equals(mID); } + + static KeyTypePointer KeyToPointer(KeyType aKey) { return &aKey; } + static PLDHashNumber HashKey(KeyTypePointer aKey); + enum { ALLOW_MEMMOVE = PR_TRUE }; + +private: + const nsID mID; +}; + +/** + * hashkey wrapper for "dependent" const char*; this class does not "own" + * its string pointer. + * + * This class must only be used if the strings have a lifetime longer than + * the hashtable they occupy. This normally occurs only for static + * strings or strings that have been arena-allocated. + * + * @see nsTHashtable::EntryType for specification + */ +class NS_COM nsDepCharHashKey : public PLDHashEntryHdr +{ +public: + typedef const char* KeyType; + typedef const char* KeyTypePointer; + + nsDepCharHashKey(const char* aKey) { mKey = aKey; } + nsDepCharHashKey(const nsDepCharHashKey& toCopy) { mKey = toCopy.mKey; } + ~nsDepCharHashKey() { } + + const char* GetKey() const { return mKey; } + const char* GetKeyPointer() const { return mKey; } + PRBool KeyEquals(const char* aKey) const + { + return !strcmp(mKey, aKey); + } + + static const char* KeyToPointer(const char* aKey) { return aKey; } + static PLDHashNumber HashKey(const char* aKey) { return nsCRT::HashCode(aKey); } + enum { ALLOW_MEMMOVE = PR_TRUE }; + +private: + const char* mKey; +}; + +/** + * hashkey wrapper for const char*; at construction, this class duplicates + * a string pointed to by the pointer so that it doesn't matter whether or not + * the string lives longer than the hash table. + */ +class NS_COM nsCharPtrHashKey : public PLDHashEntryHdr +{ +public: + typedef const char* KeyType; + typedef const char* KeyTypePointer; + + nsCharPtrHashKey(const char* aKey) : mKey(strdup(aKey)) { } + nsCharPtrHashKey(const nsCharPtrHashKey& toCopy) : mKey(strdup(toCopy.mKey)) { } + ~nsCharPtrHashKey() { if (mKey) free(NS_CONST_CAST(char *, mKey)); } + + const char* GetKey() const { return mKey; } + const char* GetKeyPointer() const { return mKey; } + PRBool KeyEquals(KeyTypePointer aKey) const + { + return !strcmp(mKey, aKey); + } + + static KeyTypePointer KeyToPointer(KeyType aKey) { return aKey; } + static PLDHashNumber HashKey(KeyTypePointer aKey) { return nsCRT::HashCode(aKey); } + + enum { ALLOW_MEMMOVE = PR_TRUE }; + +private: + const char* mKey; +}; + +#endif // nsTHashKeys_h__ diff --git a/mozilla/xpcom/ds/nsInterfaceHashtable.h b/mozilla/xpcom/ds/nsInterfaceHashtable.h new file mode 100644 index 00000000000..5f01922efac --- /dev/null +++ b/mozilla/xpcom/ds/nsInterfaceHashtable.h @@ -0,0 +1,196 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla 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/MPL/ + * + * 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 C++ hashtable templates. + * + * The Initial Developer of the Original Code is + * Benjamin Smedberg. + * Portions created by the Initial Developer are Copyright (C) 2002 + * 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 MPL, 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 MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#ifndef nsInterfaceHashtable_h__ +#define nsInterfaceHashtable_h__ + +#include "nsBaseHashtable.h" +#include "nsHashKeys.h" +#include "nsCOMPtr.h" + +/** + * templated hashtable class maps keys to interface pointers. + * See nsBaseHashtable for complete declaration. + * @param KeyClass a wrapper-class for the hashtable key, see nsHashKeys.h + * for a complete specification. + * @param Interface the interface-type being wrapped + * @see nsDataHashtable, nsClassHashtable + */ +template +class nsInterfaceHashtable : + public nsBaseHashtable< KeyClass, nsCOMPtr , Interface* > +{ +public: + typedef typename KeyClass::KeyType KeyType; + typedef Interface* UserDataType; + + /** + * @copydoc nsBaseHashtable::Get + * @param pData This is an XPCOM getter, so pData is already_addrefed. + * If the key doesn't exist, pData will be set to nsnull. + */ + PRBool Get(KeyType aKey, UserDataType* pData) const; + + /** + * Gets a weak reference to the hashtable entry. + * @param aFound If not nsnull, will be set to PR_TRUE if the entry is found, + * to PR_FALSE otherwise. + * @return The entry, or nsnull if not found. Do not release this pointer! + */ + Interface* GetWeak(KeyType aKey, PRBool* aFound = nsnull) const; +}; + +/** + * Thread-safe version of nsInterfaceHashtable + * @param KeyClass a wrapper-class for the hashtable key, see nsHashKeys.h + * for a complete specification. + * @param Interface the interface-type being wrapped + */ +template +class nsInterfaceHashtableMT : + public nsBaseHashtableMT< KeyClass, nsCOMPtr , Interface* > +{ +public: + typedef typename KeyClass::KeyType KeyType; + typedef Interface* UserDataType; + + /** + * @copydoc nsBaseHashtable::Get + * @param pData This is an XPCOM getter, so pData is already_addrefed. + * If the key doesn't exist, pData will be set to nsnull. + */ + PRBool Get(KeyType aKey, UserDataType* pData) const; + + // GetWeak does not make sense on a multi-threaded hashtable, where another + // thread may remove the entry (and hence release it) as soon as GetWeak + // returns +}; + + +// +// nsInterfaceHashtable definitions +// + +template +PRBool +nsInterfaceHashtable::Get + (KeyType aKey, UserDataType* pInterface) const +{ + typename nsBaseHashtable, Interface*>::EntryType* ent = + GetEntry(aKey); + + if (ent) + { + if (pInterface) + { + *pInterface = ent->mData; + + NS_IF_ADDREF(*pInterface); + } + + return PR_TRUE; + } + + // if the key doesn't exist, set *pInterface to null + // so that it is a valid XPCOM getter + if (pInterface) + *pInterface = nsnull; + + return PR_FALSE; +} + +template +Interface* +nsInterfaceHashtable::GetWeak + (KeyType aKey, PRBool* aFound) const +{ + typename nsBaseHashtable, Interface*>::EntryType* ent = + GetEntry(aKey); + + if (ent) + { + if (aFound) + *aFound = PR_TRUE; + + return ent->mData; + } + + // Key does not exist, return nsnull and set aFound to PR_FALSE + if (aFound) + *aFound = PR_FALSE; + return nsnull; +} + +// +// nsInterfaceHashtableMT definitions +// + +template +PRBool +nsInterfaceHashtableMT::Get + (KeyType aKey, UserDataType* pInterface) const +{ + PR_Lock(this->mLock); + + typename nsBaseHashtableMT, Interface*>::EntryType* ent = + GetEntry(aKey); + + if (ent) + { + if (pInterface) + { + *pInterface = ent->mData; + + NS_IF_ADDREF(*pInterface); + } + + PR_Unlock(this->mLock); + + return PR_TRUE; + } + + // if the key doesn't exist, set *pInterface to null + // so that it is a valid XPCOM getter + if (pInterface) + *pInterface = nsnull; + + PR_Unlock(this->mLock); + + return PR_FALSE; +} + +#endif // nsInterfaceHashtable_h__ diff --git a/mozilla/xpcom/ds/nsProperties.cpp b/mozilla/xpcom/ds/nsProperties.cpp index 79d5ed5f31c..ff68bf72563 100644 --- a/mozilla/xpcom/ds/nsProperties.cpp +++ b/mozilla/xpcom/ds/nsProperties.cpp @@ -37,7 +37,6 @@ #include "nsProperties.h" #include "nsString.h" -#include "nsCRT.h" //////////////////////////////////////////////////////////////////////////////// diff --git a/mozilla/xpcom/tests/TestINIParser.cpp b/mozilla/xpcom/ds/nsTHashtable.cpp similarity index 58% rename from mozilla/xpcom/tests/TestINIParser.cpp rename to mozilla/xpcom/ds/nsTHashtable.cpp index 636bb73e747..37fa998fa2e 100644 --- a/mozilla/xpcom/tests/TestINIParser.cpp +++ b/mozilla/xpcom/ds/nsTHashtable.cpp @@ -1,3 +1,4 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * @@ -11,12 +12,11 @@ * for the specific language governing rights and limitations under the * License. * - * The Original Code is Mozilla XPCOM tests. + * The Original Code is C++ hashtable templates. * * The Initial Developer of the Original Code is - * Benjamin Smedberg . - * - * Portions created by the Initial Developer are Copyright (C) 2005 + * Benjamin Smedberg. + * Portions created by the Initial Developer are Copyright (C) 2002 * the Initial Developer. All Rights Reserved. * * Contributor(s): @@ -35,59 +35,28 @@ * * ***** END LICENSE BLOCK ***** */ -#include +#include "nsTHashtable.h" +#include "nsHashKeys.h" -#include "nsINIParser.h" -#include "nsILocalFile.h" - -static PRBool -StringCB(const char *aKey, const char *aValue, void* aClosure) +PR_IMPLEMENT(PLDHashOperator) +PL_DHashStubEnumRemove(PLDHashTable *table, + PLDHashEntryHdr *entry, + PRUint32 ordinal, + void *userarg) { - printf("%s=%s\n", aKey, aValue); - - return PR_TRUE; + return PL_DHASH_REMOVE; } -static PRBool -SectionCB(const char *aSection, void* aClosure) +PRUint32 nsIDHashKey::HashKey(const nsID* id) { - nsINIParser *ini = NS_REINTERPRET_CAST(nsINIParser*, aClosure); + PRUint32 h = id->m0; + PRUint32 i; - printf("[%s]\n", aSection); + h = (h>>28) ^ (h<<4) ^ id->m1; + h = (h>>28) ^ (h<<4) ^ id->m2; - ini->GetStrings(aSection, StringCB, nsnull); + for (i = 0; i < 8; i++) + h = (h>>28) ^ (h<<4) ^ id->m3[i]; - printf("\n"); - - return PR_TRUE; + return h; } - -int main(int argc, char **argv) -{ - if (argc < 2) { - fprintf(stderr, "Usage: %s \n", argv[0]); - return 255; - } - - nsCOMPtr lf; - - nsresult rv = NS_NewNativeLocalFile(nsDependentCString(argv[1]), - PR_TRUE, - getter_AddRefs(lf)); - if (NS_FAILED(rv)) { - fprintf(stderr, "Error: NS_NewNativeLocalFile failed\n"); - return 1; - } - - nsINIParser ini; - rv = ini.Init(lf); - if (NS_FAILED(rv)) { - fprintf(stderr, "Error: Init failed."); - return 2; - } - - ini.GetSections(SectionCB, &ini); - - return 0; -} - diff --git a/mozilla/xpcom/ds/nsTHashtable.h b/mozilla/xpcom/ds/nsTHashtable.h new file mode 100644 index 00000000000..1e55ada62c3 --- /dev/null +++ b/mozilla/xpcom/ds/nsTHashtable.h @@ -0,0 +1,429 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla 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/MPL/ + * + * 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 C++ hashtable templates. + * + * The Initial Developer of the Original Code is + * Benjamin Smedberg. + * Portions created by the Initial Developer are Copyright (C) 2002 + * 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 MPL, 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 MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#ifndef nsTHashtable_h__ +#define nsTHashtable_h__ + +#include "nscore.h" +#include "pldhash.h" +#include "nsDebug.h" +#include NEW_H + +// helper function for nsTHashtable::Clear() +PR_EXTERN(PLDHashOperator) PR_CALLBACK +PL_DHashStubEnumRemove(PLDHashTable *table, + PLDHashEntryHdr *entry, + PRUint32 ordinal, + void *userArg); + + +/** + * a base class for templated hashtables. + * + * Clients will rarely need to use this class directly. Check the derived + * classes first, to see if they will meet your needs. + * + * @param EntryType the templated entry-type class that is managed by the + * hashtable. EntryType must extend the following declaration, + * and must not declare any virtual functions or derive from classes + * with virtual functions. Any vtable pointer would break the + * PLDHashTable code. + *
   class EntryType : public PLDHashEntryHdr
+ *   {
+ *   public: or friend nsTHashtable;
+ *     // KeyType is what we use when Get()ing or Put()ing this entry
+ *     // this should either be a simple datatype (PRUint32, nsISupports*) or
+ *     // a const reference (const nsAString&)
+ *     typedef something KeyType;
+ *     // KeyTypePointer is the pointer-version of KeyType, because pldhash.h
+ *     // requires keys to cast to const void*
+ *     typedef const something* KeyTypePointer;
+ *
+ *     EntryType(KeyTypePointer aKey);
+ *
+ *     // the copy constructor must be defined, even if AllowMemMove() == true
+ *     // or you will cause link errors!
+ *     EntryType(const EntryType& aEnt);
+ *
+ *     // the destructor must be defined... or you will cause link errors!
+ *     ~EntryType();
+ *
+ *     // return the key of this entry
+ *     const KeyTypePointer GetKeyPointer() const;
+ *
+ *     // KeyEquals(): does this entry match this key?
+ *     PRBool KeyEquals(KeyTypePointer aKey) const;
+ *
+ *     // KeyToPointer(): Convert KeyType to KeyTypePointer
+ *     static KeyTypePointer KeyToPointer(KeyType aKey);
+ *
+ *     // HashKey(): calculate the hash number
+ *     static PLDHashNumber HashKey(KeyTypePointer aKey);
+ *
+ *     // ALLOW_MEMMOVE can we move this class with memmove(), or do we have
+ *     // to use the copy constructor?
+ *     enum { ALLOW_MEMMOVE = PR_(TRUE or FALSE) };
+ *   }
+ * + * @see nsInterfaceHashtable + * @see nsDataHashtable + * @see nsClassHashtable + * @author "Benjamin Smedberg " + */ + +template +class nsTHashtable +{ +public: + /** + * A dummy constructor; you must call Init() before using this class. + */ + nsTHashtable(); + + /** + * destructor, cleans up and deallocates + */ + ~nsTHashtable(); + + /** + * Initialize the table. This function must be called before any other + * class operations. This can fail due to OOM conditions. + * @param initSize the initial number of buckets in the hashtable, default 16 + * @return PR_TRUE if the class was initialized properly. + */ + PRBool Init(PRUint32 initSize = PL_DHASH_MIN_SIZE); + + /** + * Check whether the table has been initialized. This can be useful for static hashtables. + * @return the initialization state of the class. + */ + PRBool IsInitialized() const { return mTable.entrySize; } + + /** + * KeyType is typedef'ed for ease of use. + */ + typedef typename EntryType::KeyType KeyType; + + /** + * KeyTypePointer is typedef'ed for ease of use. + */ + typedef typename EntryType::KeyTypePointer KeyTypePointer; + + /** + * Return the number of entries in the table. + * @return number of entries + */ + PRUint32 Count() const { return mTable.entryCount; } + + /** + * Get the entry associated with a key. + * @param aKey the key to retrieve + * @return pointer to the entry class, if the key exists; nsnull if the + * key doesn't exist + */ + EntryType* GetEntry(KeyType aKey) const + { + NS_ASSERTION(mTable.entrySize, "nsTHashtable was not initialized properly."); + + EntryType* entry = + NS_REINTERPRET_CAST(EntryType*, + PL_DHashTableOperate( + NS_CONST_CAST(PLDHashTable*,&mTable), + EntryType::KeyToPointer(aKey), + PL_DHASH_LOOKUP)); + return PL_DHASH_ENTRY_IS_BUSY(entry) ? entry : nsnull; + } + + /** + * Get the entry associated with a key, or create a new entry, + * @param aKey the key to retrieve + * @return pointer to the entry class retreived; nsnull only if memory + can't be allocated + */ + EntryType* PutEntry(KeyType aKey) + { + NS_ASSERTION(mTable.entrySize, "nsTHashtable was not initialized properly."); + + return NS_STATIC_CAST(EntryType*, + PL_DHashTableOperate( + &mTable, + EntryType::KeyToPointer(aKey), + PL_DHASH_ADD)); + } + + /** + * Remove the entry associated with a key. + * @param aKey of the entry to remove + */ + void RemoveEntry(KeyType aKey) + { + NS_ASSERTION(mTable.entrySize, "nsTHashtable was not initialized properly."); + + PL_DHashTableOperate(&mTable, + EntryType::KeyToPointer(aKey), + PL_DHASH_REMOVE); + } + + /** + * Remove the entry associated with a key, but don't resize the hashtable. + * This is a low-level method, and is not recommended unless you know what + * you're doing and you need the extra performance. This method can be used + * during enumeration, while RemoveEntry() cannot. + * @param aEntry the entry-pointer to remove (obtained from GetEntry or + * the enumerator + */ + void RawRemoveEntry(EntryType* aEntry) + { + PL_DHashTableRawRemove(&mTable, aEntry); + } + + /** + * client must provide an Enumerator function for + * EnumerateEntries + * @param aEntry the entry being enumerated + * @param userArg passed unchanged from EnumerateEntries + * @return combination of flags + * @link PLDHashOperator::PL_DHASH_NEXT PL_DHASH_NEXT @endlink , + * @link PLDHashOperator::PL_DHASH_STOP PL_DHASH_STOP @endlink , + * @link PLDHashOperator::PL_DHASH_REMOVE PL_DHASH_REMOVE @endlink + */ + typedef PLDHashOperator (*PR_CALLBACK Enumerator)(EntryType* aEntry, void* userArg); + + /** + * Enumerate all the entries of the function. + * @param enumFunc the Enumerator function to call + * @param userArg a pointer to pass to the + * Enumerator function + * @return the number of entries actually enumerated + */ + PRUint32 EnumerateEntries(Enumerator enumFunc, void* userArg) + { + NS_ASSERTION(mTable.entrySize, "nsTHashtable was not initialized properly."); + + s_EnumArgs args = { enumFunc, userArg }; + return PL_DHashTableEnumerate(&mTable, s_EnumStub, &args); + } + + /** + * remove all entries, return hashtable to "pristine" state ;) + */ + void Clear() + { + NS_ASSERTION(mTable.entrySize, "nsTHashtable was not initialized properly."); + + PL_DHashTableEnumerate(&mTable, PL_DHashStubEnumRemove, nsnull); + } + +protected: + PLDHashTable mTable; + + static const void* PR_CALLBACK s_GetKey(PLDHashTable *table, + PLDHashEntryHdr *entry); + + static PLDHashNumber PR_CALLBACK s_HashKey(PLDHashTable *table, + const void *key); + + static PRBool PR_CALLBACK s_MatchEntry(PLDHashTable *table, + const PLDHashEntryHdr *entry, + const void *key); + + static void PR_CALLBACK s_CopyEntry(PLDHashTable *table, + const PLDHashEntryHdr *from, + PLDHashEntryHdr *to); + + static void PR_CALLBACK s_ClearEntry(PLDHashTable *table, + PLDHashEntryHdr *entry); + + static PRBool PR_CALLBACK s_InitEntry(PLDHashTable *table, + PLDHashEntryHdr *entry, + const void *key); + + /** + * passed internally during enumeration. Allocated on the stack. + * + * @param userFunc the Enumerator function passed to + * EnumerateEntries by the client + * @param userArg the userArg passed unaltered + */ + struct s_EnumArgs + { + Enumerator userFunc; + void* userArg; + }; + + static PLDHashOperator PR_CALLBACK s_EnumStub(PLDHashTable *table, + PLDHashEntryHdr *entry, + PRUint32 number, + void *arg); +private: + // copy constructor, not implemented + nsTHashtable(nsTHashtable& toCopy); + + // assignment operator, not implemented + nsTHashtable& operator= (nsTHashtable& toEqual); +}; + +// +// template definitions +// + +template +nsTHashtable::nsTHashtable() +{ + // entrySize is our "I'm initialized" indicator + mTable.entrySize = 0; +} + +template +nsTHashtable::~nsTHashtable() +{ + if (mTable.entrySize) + PL_DHashTableFinish(&mTable); +} + +template +PRBool +nsTHashtable::Init(PRUint32 initSize) +{ + if (mTable.entrySize) + { + NS_ERROR("nsTHashtable::Init() should not be called twice."); + return PR_TRUE; + } + + static PLDHashTableOps sOps = + { + ::PL_DHashAllocTable, + ::PL_DHashFreeTable, + s_GetKey, + s_HashKey, + s_MatchEntry, + ::PL_DHashMoveEntryStub, + s_ClearEntry, + ::PL_DHashFinalizeStub, + s_InitEntry + }; + + if (!EntryType::ALLOW_MEMMOVE) + { + sOps.moveEntry = s_CopyEntry; + } + + if (!PL_DHashTableInit(&mTable, &sOps, nsnull, sizeof(EntryType), initSize)) + { + // if failed, reset "flag" + mTable.entrySize = 0; + return PR_FALSE; + } + + return PR_TRUE; +} + +// static definitions + +template +const void* +nsTHashtable::s_GetKey(PLDHashTable *table, + PLDHashEntryHdr *entry) +{ + return ((EntryType*) entry)->GetKeyPointer(); +} + +template +PLDHashNumber +nsTHashtable::s_HashKey(PLDHashTable *table, + const void *key) +{ + return EntryType::HashKey(NS_REINTERPRET_CAST(const KeyTypePointer, key)); +} + +template +PRBool +nsTHashtable::s_MatchEntry(PLDHashTable *table, + const PLDHashEntryHdr *entry, + const void *key) +{ + return ((const EntryType*) entry)->KeyEquals( + NS_REINTERPRET_CAST(const KeyTypePointer, key)); +} + +template +void +nsTHashtable::s_CopyEntry(PLDHashTable *table, + const PLDHashEntryHdr *from, + PLDHashEntryHdr *to) +{ + EntryType* fromEntry = + NS_CONST_CAST(EntryType*, NS_REINTERPRET_CAST(const EntryType*, from)); + + new(to) EntryType(*fromEntry); + + fromEntry->~EntryType(); +} + +template +void +nsTHashtable::s_ClearEntry(PLDHashTable *table, + PLDHashEntryHdr *entry) +{ + NS_REINTERPRET_CAST(EntryType*,entry)->~EntryType(); +} + +template +PRBool +nsTHashtable::s_InitEntry(PLDHashTable *table, + PLDHashEntryHdr *entry, + const void *key) +{ + new(entry) EntryType(NS_REINTERPRET_CAST(KeyTypePointer,key)); + return PR_TRUE; +} + +template +PLDHashOperator +nsTHashtable::s_EnumStub(PLDHashTable *table, + PLDHashEntryHdr *entry, + PRUint32 number, + void *arg) +{ + // dereferences the function-pointer to the user's enumeration function + return (* NS_REINTERPRET_CAST(s_EnumArgs*,arg)->userFunc)( + NS_REINTERPRET_CAST(EntryType*,entry), + NS_REINTERPRET_CAST(s_EnumArgs*,arg)->userArg); +} + +#endif // nsTHashtable_h__ diff --git a/mozilla/xpcom/glue/pldhash.c b/mozilla/xpcom/ds/pldhash.c similarity index 96% rename from mozilla/xpcom/glue/pldhash.c rename to mozilla/xpcom/ds/pldhash.c index cee4f27d024..8fe2a096739 100644 --- a/mozilla/xpcom/glue/pldhash.c +++ b/mozilla/xpcom/ds/pldhash.c @@ -39,7 +39,7 @@ /* * Double hashing implementation. -* GENERATED BY js/src/plify_jsdhash.sed -- DO NOT EDIT!!! + * GENERATED BY js/src/plify_jsdhash.sed -- DO NOT EDIT!!! */ #include #include @@ -57,19 +57,19 @@ # define METER(x) /* nothing */ #endif -void * +PR_IMPLEMENT(void *) PL_DHashAllocTable(PLDHashTable *table, PRUint32 nbytes) { return malloc(nbytes); } -void +PR_IMPLEMENT(void) PL_DHashFreeTable(PLDHashTable *table, void *ptr) { free(ptr); } -PLDHashNumber +PR_IMPLEMENT(PLDHashNumber) PL_DHashStringKey(PLDHashTable *table, const void *key) { PLDHashNumber h; @@ -81,7 +81,7 @@ PL_DHashStringKey(PLDHashTable *table, const void *key) return h; } -const void * +PR_IMPLEMENT(const void *) PL_DHashGetKeyStub(PLDHashTable *table, PLDHashEntryHdr *entry) { PLDHashEntryStub *stub = (PLDHashEntryStub *)entry; @@ -89,13 +89,13 @@ PL_DHashGetKeyStub(PLDHashTable *table, PLDHashEntryHdr *entry) return stub->key; } -PLDHashNumber +PR_IMPLEMENT(PLDHashNumber) PL_DHashVoidPtrKeyStub(PLDHashTable *table, const void *key) { - return (PLDHashNumber)(unsigned long)key >> 2; + return (PLDHashNumber)key >> 2; } -PRBool +PR_IMPLEMENT(PRBool) PL_DHashMatchEntryStub(PLDHashTable *table, const PLDHashEntryHdr *entry, const void *key) @@ -105,7 +105,7 @@ PL_DHashMatchEntryStub(PLDHashTable *table, return stub->key == key; } -PRBool +PR_IMPLEMENT(PRBool) PL_DHashMatchStringKey(PLDHashTable *table, const PLDHashEntryHdr *entry, const void *key) @@ -117,7 +117,7 @@ PL_DHashMatchStringKey(PLDHashTable *table, (stub->key && key && strcmp(stub->key, key) == 0); } -void +PR_IMPLEMENT(void) PL_DHashMoveEntryStub(PLDHashTable *table, const PLDHashEntryHdr *from, PLDHashEntryHdr *to) @@ -125,13 +125,13 @@ PL_DHashMoveEntryStub(PLDHashTable *table, memcpy(to, from, table->entrySize); } -void +PR_IMPLEMENT(void) PL_DHashClearEntryStub(PLDHashTable *table, PLDHashEntryHdr *entry) { memset(entry, 0, table->entrySize); } -void +PR_IMPLEMENT(void) PL_DHashFreeStringKey(PLDHashTable *table, PLDHashEntryHdr *entry) { const PLDHashEntryStub *stub = (const PLDHashEntryStub *)entry; @@ -140,7 +140,7 @@ PL_DHashFreeStringKey(PLDHashTable *table, PLDHashEntryHdr *entry) memset(entry, 0, table->entrySize); } -void +PR_IMPLEMENT(void) PL_DHashFinalizeStub(PLDHashTable *table) { } @@ -157,13 +157,13 @@ static const PLDHashTableOps stub_ops = { NULL }; -const PLDHashTableOps * +PR_IMPLEMENT(const PLDHashTableOps *) PL_DHashGetStubOps(void) { return &stub_ops; } -PLDHashTable * +PR_IMPLEMENT(PLDHashTable *) PL_NewDHashTable(const PLDHashTableOps *ops, void *data, PRUint32 entrySize, PRUint32 capacity) { @@ -179,14 +179,14 @@ PL_NewDHashTable(const PLDHashTableOps *ops, void *data, PRUint32 entrySize, return table; } -void +PR_IMPLEMENT(void) PL_DHashTableDestroy(PLDHashTable *table) { PL_DHashTableFinish(table); free(table); } -PRBool +PR_IMPLEMENT(PRBool) PL_DHashTableInit(PLDHashTable *table, const PLDHashTableOps *ops, void *data, PRUint32 entrySize, PRUint32 capacity) { @@ -208,9 +208,7 @@ PL_DHashTableInit(PLDHashTable *table, const PLDHashTableOps *ops, void *data, table->data = data; if (capacity < PL_DHASH_MIN_SIZE) capacity = PL_DHASH_MIN_SIZE; - - PR_CEILING_LOG2(log2, capacity); - + log2 = PR_CeilingLog2(capacity); capacity = PR_BIT(log2); if (capacity >= PL_DHASH_SIZE_LIMIT) return PR_FALSE; @@ -236,7 +234,7 @@ PL_DHashTableInit(PLDHashTable *table, const PLDHashTableOps *ops, void *data, #define MAX_LOAD(table, size) (((table)->maxAlphaFrac * (size)) >> 8) #define MIN_LOAD(table, size) (((table)->minAlphaFrac * (size)) >> 8) -void +PR_IMPLEMENT(void) PL_DHashTableSetAlphaBounds(PLDHashTable *table, float maxAlpha, float minAlpha) @@ -312,7 +310,7 @@ PL_DHashTableSetAlphaBounds(PLDHashTable *table, #define ADDRESS_ENTRY(table, index) \ ((PLDHashEntryHdr *)((table)->entryStore + (index) * (table)->entrySize)) -void +PR_IMPLEMENT(void) PL_DHashTableFinish(PLDHashTable *table) { char *entryAddr, *entryLimit; @@ -481,7 +479,7 @@ ChangeTable(PLDHashTable *table, int deltaLog2) return PR_TRUE; } -PLDHashEntryHdr * PL_DHASH_FASTCALL +PR_IMPLEMENT(PLDHashEntryHdr *) PL_DHASH_FASTCALL PL_DHashTableOperate(PLDHashTable *table, const void *key, PLDHashOperator op) { PLDHashNumber keyHash; @@ -582,7 +580,7 @@ PL_DHashTableOperate(PLDHashTable *table, const void *key, PLDHashOperator op) return entry; } -void +PR_IMPLEMENT(void) PL_DHashTableRawRemove(PLDHashTable *table, PLDHashEntryHdr *entry) { PLDHashNumber keyHash; /* load first in case clearEntry goofs it */ @@ -600,11 +598,11 @@ PL_DHashTableRawRemove(PLDHashTable *table, PLDHashEntryHdr *entry) table->entryCount--; } -PRUint32 +PR_IMPLEMENT(PRUint32) PL_DHashTableEnumerate(PLDHashTable *table, PLDHashEnumerator etor, void *arg) { char *entryAddr, *entryLimit; - PRUint32 i, capacity, entrySize, ceiling; + PRUint32 i, capacity, entrySize; PRBool didRemove; PLDHashEntryHdr *entry; PLDHashOperator op; @@ -646,11 +644,9 @@ PL_DHashTableEnumerate(PLDHashTable *table, PLDHashEnumerator etor, void *arg) capacity += capacity >> 1; if (capacity < PL_DHASH_MIN_SIZE) capacity = PL_DHASH_MIN_SIZE; - - PR_CEILING_LOG2(ceiling, capacity); - ceiling -= PL_DHASH_BITS - table->hashShift; - - (void) ChangeTable(table, ceiling); + (void) ChangeTable(table, + PR_CeilingLog2(capacity) + - (PL_DHASH_BITS - table->hashShift)); } return i; } @@ -658,7 +654,7 @@ PL_DHashTableEnumerate(PLDHashTable *table, PLDHashEnumerator etor, void *arg) #ifdef PL_DHASHMETER #include -void +PR_IMPLEMENT(void) PL_DHashTableDumpMeter(PLDHashTable *table, PLDHashEnumerator dump, FILE *fp) { char *entryAddr; diff --git a/mozilla/xpcom/glue/pldhash.h b/mozilla/xpcom/ds/pldhash.h similarity index 97% rename from mozilla/xpcom/glue/pldhash.h rename to mozilla/xpcom/ds/pldhash.h index 7c2bba92c45..03f98cf7d2c 100644 --- a/mozilla/xpcom/glue/pldhash.h +++ b/mozilla/xpcom/ds/pldhash.h @@ -40,22 +40,22 @@ #define pldhash_h___ /* * Double hashing, a la Knuth 6. -* GENERATED BY js/src/plify_jsdhash.sed -- DO NOT EDIT!!! + * GENERATED BY js/src/plify_jsdhash.sed -- DO NOT EDIT!!! */ -#include "nscore.h" +#include "prtypes.h" PR_BEGIN_EXTERN_C +#ifdef DEBUG_XXXbrendan +#define PL_DHASHMETER 1 +#endif + #if defined(__GNUC__) && defined(__i386__) && (__GNUC__ >= 3) && !defined(XP_OS2) && !defined(XP_MACOSX) #define PL_DHASH_FASTCALL __attribute__ ((regparm (3),stdcall)) #else #define PL_DHASH_FASTCALL #endif -#ifdef DEBUG_XXXbrendan -#define PL_DHASHMETER 1 -#endif - /* Table size limit, do not equal or exceed (see min&maxAlphaFrac, below). */ #undef PL_DHASH_SIZE_LIMIT #define PL_DHASH_SIZE_LIMIT PR_BIT(24) @@ -352,13 +352,13 @@ struct PLDHashTableOps { /* * Default implementations for the above ops. */ -NS_COM_GLUE void * +PR_EXTERN(void *) PL_DHashAllocTable(PLDHashTable *table, PRUint32 nbytes); -NS_COM_GLUE void +PR_EXTERN(void) PL_DHashFreeTable(PLDHashTable *table, void *ptr); -NS_COM_GLUE PLDHashNumber +PR_EXTERN(PLDHashNumber) PL_DHashStringKey(PLDHashTable *table, const void *key); /* A minimal entry contains a keyHash header and a void key pointer. */ @@ -367,34 +367,34 @@ struct PLDHashEntryStub { const void *key; }; -NS_COM_GLUE const void * +PR_EXTERN(const void *) PL_DHashGetKeyStub(PLDHashTable *table, PLDHashEntryHdr *entry); -NS_COM_GLUE PLDHashNumber +PR_EXTERN(PLDHashNumber) PL_DHashVoidPtrKeyStub(PLDHashTable *table, const void *key); -NS_COM_GLUE PRBool +PR_EXTERN(PRBool) PL_DHashMatchEntryStub(PLDHashTable *table, const PLDHashEntryHdr *entry, const void *key); -NS_COM_GLUE PRBool +PR_EXTERN(PRBool) PL_DHashMatchStringKey(PLDHashTable *table, const PLDHashEntryHdr *entry, const void *key); -NS_COM_GLUE void +PR_EXTERN(void) PL_DHashMoveEntryStub(PLDHashTable *table, const PLDHashEntryHdr *from, PLDHashEntryHdr *to); -NS_COM_GLUE void +PR_EXTERN(void) PL_DHashClearEntryStub(PLDHashTable *table, PLDHashEntryHdr *entry); -NS_COM_GLUE void +PR_EXTERN(void) PL_DHashFreeStringKey(PLDHashTable *table, PLDHashEntryHdr *entry); -NS_COM_GLUE void +PR_EXTERN(void) PL_DHashFinalizeStub(PLDHashTable *table); /* @@ -402,7 +402,7 @@ PL_DHashFinalizeStub(PLDHashTable *table); * if your entries move via memcpy and clear via memset(0), you can use these * stub operations. */ -NS_COM_GLUE const PLDHashTableOps * +PR_EXTERN(const PLDHashTableOps *) PL_DHashGetStubOps(void); /* @@ -411,7 +411,7 @@ PL_DHashGetStubOps(void); * Note that the entry storage at table->entryStore will be allocated using * the ops->allocTable callback. */ -NS_COM_GLUE PLDHashTable * +PR_EXTERN(PLDHashTable *) PL_NewDHashTable(const PLDHashTableOps *ops, void *data, PRUint32 entrySize, PRUint32 capacity); @@ -419,7 +419,7 @@ PL_NewDHashTable(const PLDHashTableOps *ops, void *data, PRUint32 entrySize, * Finalize table's data, free its entry storage (via table->ops->freeTable), * and return the memory starting at table to the malloc heap. */ -NS_COM_GLUE void +PR_EXTERN(void) PL_DHashTableDestroy(PLDHashTable *table); /* @@ -428,7 +428,7 @@ PL_DHashTableDestroy(PLDHashTable *table); * than 75% loaded (the table will grow or shrink as needed; capacity serves * only to avoid inevitable early growth from PL_DHASH_MIN_SIZE). */ -NS_COM_GLUE PRBool +PR_EXTERN(PRBool) PL_DHashTableInit(PLDHashTable *table, const PLDHashTableOps *ops, void *data, PRUint32 entrySize, PRUint32 capacity); @@ -440,7 +440,7 @@ PL_DHashTableInit(PLDHashTable *table, const PLDHashTableOps *ops, void *data, * we don't shrink on the very next remove after growing a table upon adding * an entry that brings entryCount past maxAlpha * tableSize. */ -NS_COM_GLUE void +PR_IMPLEMENT(void) PL_DHashTableSetAlphaBounds(PLDHashTable *table, float maxAlpha, float minAlpha); @@ -460,7 +460,7 @@ PL_DHashTableSetAlphaBounds(PLDHashTable *table, * pointers dangling). If you want to burn cycles clearing table, it's up to * your code to call memset. */ -NS_COM_GLUE void +PR_EXTERN(void) PL_DHashTableFinish(PLDHashTable *table); /* @@ -507,7 +507,7 @@ typedef enum PLDHashOperator { * the entry is marked so that PL_DHASH_ENTRY_IS_FREE(entry). This operation * returns null unconditionally; you should ignore its return value. */ -NS_COM_GLUE PLDHashEntryHdr * PL_DHASH_FASTCALL +PR_EXTERN(PLDHashEntryHdr *) PL_DHASH_FASTCALL PL_DHashTableOperate(PLDHashTable *table, const void *key, PLDHashOperator op); /* @@ -519,7 +519,7 @@ PL_DHashTableOperate(PLDHashTable *table, const void *key, PLDHashOperator op); * shrink the table if it is underloaded. It does not update stats #ifdef * PL_DHASHMETER, either. */ -NS_COM_GLUE void +PR_EXTERN(void) PL_DHashTableRawRemove(PLDHashTable *table, PLDHashEntryHdr *entry); /* @@ -565,13 +565,13 @@ typedef PLDHashOperator (* PR_CALLBACK PLDHashEnumerator)(PLDHashTable *table, PLDHashEntryHdr *hdr, PRUint32 number, void *arg); -NS_COM_GLUE PRUint32 +PR_EXTERN(PRUint32) PL_DHashTableEnumerate(PLDHashTable *table, PLDHashEnumerator etor, void *arg); #ifdef PL_DHASHMETER #include -NS_COM_GLUE void +PR_EXTERN(void) PL_DHashTableDumpMeter(PLDHashTable *table, PLDHashEnumerator dump, FILE *fp); #endif diff --git a/mozilla/xpcom/glue/Makefile.in b/mozilla/xpcom/glue/Makefile.in index 1646f54d615..5357f7d188c 100644 --- a/mozilla/xpcom/glue/Makefile.in +++ b/mozilla/xpcom/glue/Makefile.in @@ -56,25 +56,9 @@ LOCAL_INCLUDES = \ -I$(srcdir)/../build \ $(NULL) -CSRCS = \ - $(XPCOM_GLUE_SRC_LCSRCS) \ - $(NULL) - CPPSRCS = \ - $(XPCOM_GLUE_SRC_LCPPSRCS) \ - $(XPCOM_GLUENS_SRC_LCPPSRCS) \ - $(NULL) - -EXPORTS = \ - pldhash.h \ - nsBaseHashtable.h \ - nsClassHashtable.h \ - nsDataHashtable.h \ - nsHashKeys.h \ - nsINIParser.h \ - nsInterfaceHashtable.h \ - nsRefPtrHashtable.h \ - nsTHashtable.h \ + $(XPCOM_GLUE_SRC_LCSRCS) \ + $(XPCOM_GLUENS_SRC_LCSRCS) \ $(NULL) SDK_HEADERS = \ diff --git a/mozilla/xpcom/glue/nsHashKeys.h b/mozilla/xpcom/glue/nsHashKeys.h index c50b1f075c9..8a6d272eaf9 100644 --- a/mozilla/xpcom/glue/nsHashKeys.h +++ b/mozilla/xpcom/glue/nsHashKeys.h @@ -38,22 +38,16 @@ #ifndef nsTHashKeys_h__ #define nsTHashKeys_h__ +#include "nsAString.h" +#include "nsString.h" #include "nsID.h" +#include "nsCRT.h" +#include "nsReadableUtils.h" #include "nsISupports.h" #include "nsCOMPtr.h" #include "pldhash.h" #include NEW_H -#ifdef MOZILLA_INTERNAL_API -#include "nsAString.h" -#include "nsString.h" -#else -#include "nsStringAPI.h" -#endif - -#include -#include - /** @file nsHashKeys.h * standard HashKey classes for nsBaseHashtable and relatives. Each of these * classes follows the nsTHashtable::EntryType specification @@ -67,10 +61,6 @@ * nsDepCharHashKey */ -NS_COM_GLUE PRUint32 HashString(const nsAString& aStr); -NS_COM_GLUE PRUint32 HashString(const nsACString& aStr); -NS_COM_GLUE PRUint32 HashCString(const char* aKey); - /** * hashkey wrapper using nsAString KeyType * @@ -284,7 +274,7 @@ public: } static const char* KeyToPointer(const char* aKey) { return aKey; } - static PLDHashNumber HashKey(const char* aKey) { return HashCString(aKey); } + static PLDHashNumber HashKey(const char* aKey) { return nsCRT::HashCode(aKey); } enum { ALLOW_MEMMOVE = PR_TRUE }; private: @@ -314,7 +304,7 @@ public: } static KeyTypePointer KeyToPointer(KeyType aKey) { return aKey; } - static PLDHashNumber HashKey(KeyTypePointer aKey) { return HashCString(aKey); } + static PLDHashNumber HashKey(KeyTypePointer aKey) { return nsCRT::HashCode(aKey); } enum { ALLOW_MEMMOVE = PR_TRUE }; diff --git a/mozilla/xpcom/glue/nsINIParser.cpp b/mozilla/xpcom/glue/nsINIParser.cpp deleted file mode 100644 index e6e4aa6b0a6..00000000000 --- a/mozilla/xpcom/glue/nsINIParser.cpp +++ /dev/null @@ -1,310 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla 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/MPL/ - * - * 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 Communicator client code, released - * March 31, 1998. - * - * 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): - * Samir Gehani - * Benjamin Smedberg - * - * 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 MPL, 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 MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#include "nsINIParser.h" -#include "nsError.h" -#include "nsILocalFile.h" - -#include -#include - -// Stack based FILE wrapper to ensure that fclose is called, copied from -// toolkit/mozapps/update/src/updater/readstrings.cpp - -class AutoFILE { -public: - AutoFILE(FILE *fp = nsnull) : fp_(fp) {} - ~AutoFILE() { if (fp_) fclose(fp_); } - operator FILE *() { return fp_; } - FILE** operator &() { return &fp_; } -private: - FILE *fp_; -}; - -nsresult -nsINIParser::Init(nsILocalFile* aFile) -{ - nsresult rv; - - /* open the file */ - AutoFILE fd; - rv = aFile->OpenANSIFileDesc("r", &fd); - if (NS_FAILED(rv)) - return rv; - - return InitFromFILE(fd); -} - -nsresult -nsINIParser::Init(const char *aPath) -{ - /* open the file */ - AutoFILE fd = fopen(aPath, "r"); - if (!fd) - return NS_ERROR_FAILURE; - - return InitFromFILE(fd); -} - -// copied from toolkit/mozapps/updater/src/updater/updater.cpp -// we could use nsCRT::strtok except that nsCRT isn't part of the glue, -// and may never be due to NSPR dependencies. This should probably be declared -// and exported in a string-management glue header. - -static char* -mstrtok(const char *delims, char **str) -{ - if (!*str || !**str) - return NULL; - - // skip leading "whitespace" - char *ret = *str; - const char *d; - do { - for (d = delims; *d != '\0'; ++d) { - if (*ret == *d) { - ++ret; - break; - } - } - } while (*d); - - if (!*ret) { - *str = ret; - return NULL; - } - - char *i = ret; - do { - for (d = delims; *d != '\0'; ++d) { - if (*i == *d) { - *i = '\0'; - *str = ++i; - return ret; - } - } - ++i; - } while (*i); - - *str = NULL; - return ret; -} - -static const char kNL[] = "\r\n"; -static const char kEquals[] = "="; -static const char kWhitespace[] = " \t"; -static const char kRBracket[] = "]"; - -nsresult -nsINIParser::InitFromFILE(FILE *fd) -{ - if (!mSections.Init()) - return NS_ERROR_OUT_OF_MEMORY; - - /* get file size */ - if (fseek(fd, 0, SEEK_END) != 0) - return NS_ERROR_FAILURE; - - long flen = ftell(fd); - if (flen == 0) - return NS_ERROR_FAILURE; - - /* malloc an internal buf the size of the file */ - mFileContents = new char[flen + 1]; - if (!mFileContents) - return NS_ERROR_OUT_OF_MEMORY; - - /* read the file in one swoop */ - if (fseek(fd, 0, SEEK_SET) != 0) - return NS_BASE_STREAM_OSERROR; - - int rd = fread(mFileContents, sizeof(char), flen, fd); - if (rd != flen) - return NS_BASE_STREAM_OSERROR; - - mFileContents[flen] = '\0'; - - char *buffer = mFileContents; - char *currSection = nsnull; - INIValue *last = nsnull; - - // outer loop tokenizes into lines - while (char *line = mstrtok(kNL, &buffer)) { - if (line[0] == '#') // it's a comment - continue; - - char *token = mstrtok(kWhitespace, &line); - if (!token) // empty line - continue; - - if (token[0] == '[') { // section header! - ++token; - currSection = token; - last = nsnull; - - char *rb = mstrtok(kRBracket, &token); - if (!rb || mstrtok(kWhitespace, &token)) { - // there's either an unclosed [Section or a [Section]Moretext! - // we could frankly decide that this INI file is malformed right - // here and stop, but we won't... keep going, looking for - // a well-formed [section] to continue working with - currSection = nsnull; - } - - continue; - } - - if (!currSection) { - // If we haven't found a section header (or we found a malformed - // section header), don't bother parsing this line. - continue; - } - - char *key = token; - char *e = mstrtok(kEquals, &token); - if (!e) - continue; - - INIValue *val = new INIValue(key, token); - if (!val) - return NS_ERROR_OUT_OF_MEMORY; - - // If we haven't already added something to this section, "last" will - // be null. - if (!last) { - mSections.Get(currSection, &last); - while (last && last->next) - last = last->next; - } - - if (last) { - // Add this element on to the tail of the existing list - - last->next = val; - last = val; - continue; - } - - // We've never encountered this section before, add it to the head - mSections.Put(currSection, val); - } - - return NS_OK; -} - -nsresult -nsINIParser::GetString(const char *aSection, const char *aKey, - nsACString &aResult) -{ - INIValue *val; - mSections.Get(aSection, &val); - - while (val) { - if (strcmp(val->key, aKey) == 0) { - aResult.Assign(val->value); - return NS_OK; - } - - val = val->next; - } - - return NS_ERROR_FAILURE; -} - -nsresult -nsINIParser::GetString(const char *aSection, const char *aKey, - char *aResult, PRUint32 aResultLen) -{ - INIValue *val; - mSections.Get(aSection, &val); - - while (val) { - if (strcmp(val->key, aKey) == 0) { - strncpy(aResult, val->value, aResultLen); - aResult[aResultLen - 1] = '\0'; - if (strlen(val->value) >= aResultLen) - return NS_ERROR_LOSS_OF_SIGNIFICANT_DATA; - - return NS_OK; - } - - val = val->next; - } - - return NS_ERROR_FAILURE; -} - -PLDHashOperator -nsINIParser::GetSectionsCB(const char *aKey, INIValue *aData, - void *aClosure) -{ - GSClosureStruct *cs = NS_REINTERPRET_CAST(GSClosureStruct*, aClosure); - - return cs->usercb(aKey, cs->userclosure) ? PL_DHASH_NEXT : PL_DHASH_STOP; -} - -nsresult -nsINIParser::GetSections(INISectionCallback aCB, void *aClosure) -{ - GSClosureStruct gs = { - aCB, - aClosure - }; - - mSections.EnumerateRead(GetSectionsCB, &gs); - return NS_OK; -} - -nsresult -nsINIParser::GetStrings(const char *aSection, - INIStringCallback aCB, void *aClosure) -{ - INIValue *val; - - for (mSections.Get(aSection, &val); - val; - val = val->next) { - - if (!aCB(val->key, val->value, aClosure)) - return NS_OK; - } - - return NS_OK; -} diff --git a/mozilla/xpcom/glue/nsINIParser.h b/mozilla/xpcom/glue/nsINIParser.h deleted file mode 100644 index 345d6d88b05..00000000000 --- a/mozilla/xpcom/glue/nsINIParser.h +++ /dev/null @@ -1,158 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla 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/MPL/ - * - * 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 Communicator client code, released - * March 31, 1998. - * - * 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): - * Samir Gehani - * Benjamin Smedberg - * - * 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 MPL, 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 MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -// This file was shamelessly copied from mozilla/xpinstall/wizard/unix/src2 - -#ifndef nsINIParser_h__ -#define nsINIParser_h__ - -#include "nscore.h" -#include "nsClassHashtable.h" -#include "nsAutoPtr.h" - -#include - -class nsILocalFile; - -class NS_COM_GLUE nsINIParser -{ -public: - nsINIParser() { } - ~nsINIParser() { } - - /** - * Initialize the INIParser with a nsILocalFile. If this method fails, no - * other methods should be called. This method reads and parses the file, - * the class does not hold a file handle open. An instance must only be - * initialized once. - */ - nsresult Init(nsILocalFile* aFile); - - /** - * Initialize the INIParser with a file path. If this method fails, no - * other methods should be called. This method reads and parses the file, - * the class does not hold a file handle open. An instance must only - * be initialized once. - */ - nsresult Init(const char *aPath); - - /** - * Callback for GetSections - * @return PR_FALSE to stop enumeration, or PR_TRUE to continue. - */ - typedef PRBool - (* PR_CALLBACK INISectionCallback)(const char *aSection, - void *aClosure); - - /** - * Enumerate the sections within the INI file. - */ - nsresult GetSections(INISectionCallback aCB, void *aClosure); - - /** - * Callback for GetStrings - * @return PR_FALSE to stop enumeration, or PR_TRUE to continue - */ - typedef PRBool - (* PR_CALLBACK INIStringCallback)(const char *aString, - const char *aValue, - void *aClosure); - - /** - * Enumerate the strings within a section. If the section does - * not exist, this function will silently return. - */ - nsresult GetStrings(const char *aSection, - INIStringCallback aCB, void *aClosure); - - /** - * Get the value of the specified key in the specified section - * of the INI file represented by this instance. - * - * @param aSection section name - * @param aKey key name - * @param aResult the value found - * @throws NS_ERROR_FAILURE if the specified section/key could not be - * found. - */ - nsresult GetString(const char *aSection, const char *aKey, - nsACString &aResult); - - /** - * Alternate signature of GetString that uses a pre-allocated buffer - * instead of a nsACString (for use in the standalone glue before - * the glue is initialized). - * - * @throws NS_ERROR_LOSS_OF_SIGNIFICANT_DATA if the aResult buffer is not - * large enough for the data. aResult will be filled with as - * much data as possible. - * - * @see GetString [1] - */ - nsresult GetString(const char *aSection, const char* aKey, - char *aResult, PRUint32 aResultLen); - -private: - struct INIValue - { - INIValue(const char *aKey, const char *aValue) - : key(aKey), value(aValue) { } - - const char *key; - const char *value; - nsAutoPtr next; - }; - - struct GSClosureStruct - { - INISectionCallback usercb; - void *userclosure; - }; - - nsClassHashtable mSections; - nsAutoArrayPtr mFileContents; - - nsresult InitFromFILE(FILE *fd); - - static PLDHashOperator GetSectionsCB(const char *aKey, - INIValue *aData, void *aClosure); -}; - -#endif /* nsINIParser_h__ */ diff --git a/mozilla/xpcom/glue/nsTHashtable.cpp b/mozilla/xpcom/glue/nsTHashtable.cpp index 05507633b4d..37fa998fa2e 100644 --- a/mozilla/xpcom/glue/nsTHashtable.cpp +++ b/mozilla/xpcom/glue/nsTHashtable.cpp @@ -38,65 +38,6 @@ #include "nsTHashtable.h" #include "nsHashKeys.h" -PRUint32 -HashString( const nsAString& aStr ) -{ - PRUint32 code = 0; - -#ifdef MOZILLA_INTERNAL_API - nsAString::const_iterator begin, end; - aStr.BeginReading(begin); - aStr.EndReading(end); -#else - const PRUnichar *begin, *end; - PRUint32 len = NS_StringGetData(aStr, &begin); - end = begin + len; -#endif - - while (begin != end) { - code = (code>>28) ^ (code<<4) ^ PRUint32(*begin); - ++begin; - } - - return code; -} - -PRUint32 -HashString( const nsACString& aStr ) -{ - PRUint32 code = 0; - -#ifdef MOZILLA_INTERNAL_API - nsACString::const_iterator begin, end; - aStr.BeginReading(begin); - aStr.EndReading(end); -#else - const char *begin, *end; - PRUint32 len = NS_CStringGetData(aStr, &begin); - end = begin + len; -#endif - - while (begin != end) { - code = (code>>28) ^ (code<<4) ^ PRUint32(*begin); - ++begin; - } - - return code; -} - -PRUint32 -HashCString(const char *str) -{ - PRUint32 code = 0; - - while (*str) { - code = (code>>28) ^ (code<<4) ^ PRUint32(*str); - ++str; - } - - return code; -} - PR_IMPLEMENT(PLDHashOperator) PL_DHashStubEnumRemove(PLDHashTable *table, PLDHashEntryHdr *entry, diff --git a/mozilla/xpcom/glue/objs.mk b/mozilla/xpcom/glue/objs.mk index c1376aa4cc2..09d1a32bb91 100644 --- a/mozilla/xpcom/glue/objs.mk +++ b/mozilla/xpcom/glue/objs.mk @@ -34,35 +34,27 @@ # # ***** END LICENSE BLOCK ***** -XPCOM_GLUE_SRC_LCSRCS = \ - pldhash.c \ - $(NULL) +XPCOM_GLUE_SRC_LCSRCS = \ + nsCOMPtr.cpp \ + nsComponentManagerUtils.cpp \ + nsDebug.cpp \ + nsID.cpp \ + nsIInterfaceRequestorUtils.cpp \ + nsMemory.cpp \ + nsTraceRefcnt.cpp \ + nsWeakReference.cpp \ + nsGREGlue.cpp \ + nsVersionComparator.cpp \ + $(NULL) -XPCOM_GLUE_SRC_CSRCS = $(addprefix $(topsrcdir)/xpcom/glue/, $(XPCOM_GLUE_SRC_LCSRCS)) - -XPCOM_GLUE_SRC_LCPPSRCS = \ - nsCOMPtr.cpp \ - nsComponentManagerUtils.cpp \ - nsDebug.cpp \ - nsID.cpp \ - nsIInterfaceRequestorUtils.cpp \ - nsINIParser.cpp \ - nsMemory.cpp \ - nsTraceRefcnt.cpp \ - nsWeakReference.cpp \ - nsGREGlue.cpp \ - nsVersionComparator.cpp \ - nsTHashtable.cpp \ - $(NULL) - -XPCOM_GLUE_SRC_CPPSRCS = $(addprefix $(topsrcdir)/xpcom/glue/, $(XPCOM_GLUE_SRC_LCPPSRCS)) +XPCOM_GLUE_SRC_CSRCS := $(addprefix $(topsrcdir)/xpcom/glue/, $(XPCOM_GLUE_SRC_LCSRCS)) # nsGenericFactory is not really all that helpful in the standalone glue, # and it has a bad dependency on the NSPR AtomicIncrement function, so we # only build it for the dependent XPCOM glue and builtin to xpcom-core. -XPCOM_GLUENS_SRC_LCPPSRCS = \ - nsGenericFactory.cpp \ - $(NULL) +XPCOM_GLUENS_SRC_LCSRCS = \ + nsGenericFactory.cpp \ + $(NULL) -XPCOM_GLUENS_SRC_CPPSRCS = $(addprefix $(topsrcdir)/xpcom/glue/,$(XPCOM_GLUENS_SRC_LCPPSRCS)) +XPCOM_GLUENS_SRC_CSRCS := $(addprefix $(topsrcdir)/xpcom/glue/,$(XPCOM_GLUENS_SRC_LCSRCS)) diff --git a/mozilla/xpcom/glue/standalone/Makefile.in b/mozilla/xpcom/glue/standalone/Makefile.in index efeb0c29703..0569eaae478 100644 --- a/mozilla/xpcom/glue/standalone/Makefile.in +++ b/mozilla/xpcom/glue/standalone/Makefile.in @@ -71,12 +71,8 @@ LINKSRC = nsGlueLinkingNull.cpp $(warning TinderboxPrint:Error: XPCOM Glue) endif -CSRCS = \ - $(XPCOM_GLUE_SRC_LCSRCS) \ - $(NULL) - CPPSRCS = \ - $(XPCOM_GLUE_SRC_LCPPSRCS) \ + $(XPCOM_GLUE_SRC_LCSRCS) \ nsXPCOMGlue.cpp \ nsGREDirServiceProvider.cpp \ $(LINKSRC) \ @@ -102,7 +98,7 @@ SRCS_IN_OBJDIR = 1 include $(topsrcdir)/config/rules.mk -export:: $(XPCOM_GLUE_SRC_CSRCS) $(XPCOM_GLUE_SRC_CPPSRCS) +export:: $(XPCOM_GLUE_SRC_CSRCS) $(INSTALL) $^ . DEFINES += -DXPCOM_GLUE diff --git a/mozilla/xpcom/string/public/nsReadableUtils.h b/mozilla/xpcom/string/public/nsReadableUtils.h index f20f9dbb2ce..13f94c09ba0 100755 --- a/mozilla/xpcom/string/public/nsReadableUtils.h +++ b/mozilla/xpcom/string/public/nsReadableUtils.h @@ -360,6 +360,9 @@ StringEndsWith( const nsACString& aSource, const nsACString& aSubstring, const nsCStringComparator& aComparator = nsDefaultCStringComparator() ); +NS_COM PRUint32 HashString( const nsAString& aStr ); +NS_COM PRUint32 HashString( const nsACString& aStr ); + NS_COM const nsAFlatString& EmptyString(); NS_COM const nsAFlatCString& EmptyCString(); diff --git a/mozilla/xpcom/string/public/nsStringAPI.h b/mozilla/xpcom/string/public/nsStringAPI.h index 9f645acf2a7..57c6fabe5ac 100644 --- a/mozilla/xpcom/string/public/nsStringAPI.h +++ b/mozilla/xpcom/string/public/nsStringAPI.h @@ -38,8 +38,6 @@ #ifndef nsStringAPI_h__ #define nsStringAPI_h__ -#include - /** * nsStringAPI.h * @@ -923,18 +921,6 @@ public: NS_HIDDEN_(void) Cut( index_type cutStart, size_type cutLength ) { Replace(cutStart, cutLength, nsnull, 0); } - NS_HIDDEN_(PRBool) Equals( const self_type &other ) const { - const char_type *cself; - const char_type *cother; - PRUint32 selflen = NS_StringGetData(*this, &cself); - PRUint32 otherlen = NS_StringGetData(other, &cother); - - if (selflen != otherlen) - return PR_FALSE; - - return memcmp(cself, cother, selflen * sizeof(char_type)) == 0; - } - #endif // MOZILLA_INTERNAL_API protected: @@ -1040,18 +1026,6 @@ public: NS_HIDDEN_(void) Cut( index_type cutStart, size_type cutLength ) { Replace(cutStart, cutLength, nsnull, 0); } - NS_HIDDEN_(PRBool) Equals( const self_type &other ) const { - const char_type *cself; - const char_type *cother; - PRUint32 selflen = NS_CStringGetData(*this, &cself); - PRUint32 otherlen = NS_CStringGetData(other, &cother); - - if (selflen != otherlen) - return PR_FALSE; - - return memcmp(cself, cother, selflen * sizeof(char_type)) == 0; - } - #endif // MOZILLA_INTERNAL_API protected: diff --git a/mozilla/xpcom/string/src/nsReadableUtils.cpp b/mozilla/xpcom/string/src/nsReadableUtils.cpp index 3d56e4fd368..5a50873e900 100755 --- a/mozilla/xpcom/string/src/nsReadableUtils.cpp +++ b/mozilla/xpcom/string/src/nsReadableUtils.cpp @@ -1079,6 +1079,48 @@ StringEndsWith( const nsACString& aSource, const nsACString& aSubstring, +template +class CalculateHashCode + { + public: + typedef CharT char_type; + typedef PRUint32 hashcode_type; + typedef CharT value_type; + + CalculateHashCode() : mHashCode(0) { } + hashcode_type GetHashCode() const { return mHashCode; } + + PRUint32 write( const CharT* chars, PRUint32 N ) + { + for ( const CharT *end = chars + N; chars < end; ++chars) + mHashCode = (mHashCode>>28) ^ (mHashCode<<4) ^ PRUint32(*chars); + return N; + } + + private: + hashcode_type mHashCode; + }; + +NS_COM PRUint32 HashString( const nsAString& aStr ) + { + CalculateHashCode sink; + nsAString::const_iterator begin, end; + aStr.BeginReading(begin); + aStr.EndReading(end); + copy_string(begin, end, sink); + return sink.GetHashCode(); + } + +NS_COM PRUint32 HashString( const nsACString& aStr ) + { + CalculateHashCode sink; + nsACString::const_iterator begin, end; + aStr.BeginReading(begin); + aStr.EndReading(end); + copy_string(begin, end, sink); + return sink.GetHashCode(); + } + static const PRUnichar empty_buffer[1] = { '\0' }; NS_COM const nsAFlatString& EmptyString() diff --git a/mozilla/xpcom/tests/Makefile.in b/mozilla/xpcom/tests/Makefile.in index d94f28905f7..924d1784149 100644 --- a/mozilla/xpcom/tests/Makefile.in +++ b/mozilla/xpcom/tests/Makefile.in @@ -67,7 +67,6 @@ CPPSRCS = \ TestFactory.cpp \ TestHashtables.cpp \ TestID.cpp \ - TestINIParser.cpp \ TestObserverService.cpp \ TestPermanentAtoms.cpp \ TestPipes.cpp \ diff --git a/mozilla/xulrunner/app/Makefile.in b/mozilla/xulrunner/app/Makefile.in index 74b8e5a29fe..962a5a5ef88 100644 --- a/mozilla/xulrunner/app/Makefile.in +++ b/mozilla/xulrunner/app/Makefile.in @@ -82,6 +82,10 @@ CPPSRCS += nsRegisterGREUnix.cpp endif endif +ifdef MOZ_ENABLE_LIBXUL +CPPSRCS += nsINIParser.cpp +endif + LOCAL_INCLUDES += \ -I$(topsrcdir)/toolkit/xre \ -I$(topsrcdir)/toolkit/profile/src \ @@ -325,6 +329,11 @@ endif README_FILE = $(topsrcdir)/README.txt +ifdef MOZ_ENABLE_LIBXUL +export:: + $(INSTALL) $(topsrcdir)/toolkit/profile/src/nsINIParser.cpp . +endif + libs:: $(INSTALL) $(README_FILE) $(DIST)/bin $(INSTALL) $(topsrcdir)/LICENSE $(DIST)/bin diff --git a/mozilla/xulrunner/app/nsXULRunnerApp.cpp b/mozilla/xulrunner/app/nsXULRunnerApp.cpp index 31385385b73..45f610f3607 100644 --- a/mozilla/xulrunner/app/nsXULRunnerApp.cpp +++ b/mozilla/xulrunner/app/nsXULRunnerApp.cpp @@ -139,11 +139,10 @@ static PRBool CheckMaxVersion(const char *versionStr) /** * Parse application data. */ -static int LoadAppData(const char* appDataFile, nsXREAppData* aResult, - nsCString& vendor, nsCString& name, nsCString& version, - nsCString& buildID, nsCString& appID, - nsCString& copyright) +static int LoadAppData(const char* appDataFile, nsXREAppData* aResult) { + static char vendor[256], name[256], version[32], buildID[32], appID[256], copyright[512]; + nsresult rv; nsCOMPtr lf; @@ -170,16 +169,15 @@ static int LoadAppData(const char* appDataFile, nsXREAppData* aResult, // TODO: If these version checks fail, then look for a compatible XULRunner // version on the system, and launch it instead. - nsCAutoString gkVersion; - rv = parser.GetString("Gecko", "MinVersion", gkVersion); - - if (NS_FAILED(rv) || !CheckMinVersion(gkVersion.get())) { + char gkVersion[32]; + rv = parser.GetString("Gecko", "MinVersion", gkVersion, sizeof(gkVersion)); + if (NS_FAILED(rv) || !CheckMinVersion(gkVersion)) { Output(PR_TRUE, "Error: Gecko MinVersion requirement not met.\n"); return 1; } - rv = parser.GetString("Gecko", "MaxVersion", gkVersion); - if (NS_SUCCEEDED(rv) && !CheckMaxVersion(gkVersion.get())) { + rv = parser.GetString("Gecko", "MaxVersion", gkVersion, sizeof(gkVersion)); + if (NS_SUCCEEDED(rv) && !CheckMaxVersion(gkVersion)) { Output(PR_TRUE, "Error: Gecko MaxVersion requirement not met.\n"); return 1; } @@ -190,21 +188,22 @@ static int LoadAppData(const char* appDataFile, nsXREAppData* aResult, const struct { const char *key; const char **fill; - nsCString &buf; + char *buf; + size_t bufLen; PRBool required; } string_fields[] = { - { "Vendor", &aResult->vendor, vendor, PR_FALSE }, - { "Name", &aResult->name, name, PR_TRUE }, - { "Version", &aResult->version, version, PR_FALSE }, - { "BuildID", &aResult->buildID, buildID, PR_TRUE }, - { "ID", &aResult->ID, appID, PR_FALSE }, - { "Copyright", &aResult->copyright, copyright, PR_FALSE } + { "Vendor", &aResult->vendor, vendor, sizeof(vendor), PR_FALSE }, + { "Name", &aResult->name, name, sizeof(name), PR_TRUE }, + { "Version", &aResult->version, version, sizeof(version), PR_FALSE }, + { "BuildID", &aResult->buildID, buildID, sizeof(buildID), PR_TRUE }, + { "ID", &aResult->ID, appID, sizeof(appID), PR_FALSE }, + { "Copyright", &aResult->copyright, copyright, sizeof(copyright), PR_FALSE } }; for (i = 0; i < NS_ARRAY_LENGTH(string_fields); ++i) { - rv = parser.GetString("App", string_fields[i].key, - string_fields[i].buf); + rv = parser.GetString("App", string_fields[i].key, string_fields[i].buf, + string_fields[i].bufLen); if (NS_SUCCEEDED(rv)) { - *string_fields[i].fill = string_fields[i].buf.get(); + *string_fields[i].fill = string_fields[i].buf; } else if (string_fields[i].required) { Output(PR_TRUE, "Error: %x: No \"%s\" field.\n", @@ -402,12 +401,9 @@ int main(int argc, char* argv[]) PR_SetEnv(kAppEnv); } - nsCAutoString vendor, name, version, buildID, appID, copyright; - nsXREAppData appData = { sizeof(nsXREAppData), 0 }; - int rv = LoadAppData(appDataFile, &appData, - vendor, name, version, buildID, appID, copyright); + int rv = LoadAppData(appDataFile, &appData); if (!rv) rv = XRE_main(argc, argv, &appData);