diff --git a/mozilla/xpcom/base/Makefile.in b/mozilla/xpcom/base/Makefile.in index 395b67676c7..db71eccc428 100644 --- a/mozilla/xpcom/base/Makefile.in +++ b/mozilla/xpcom/base/Makefile.in @@ -62,6 +62,7 @@ CPPSRCS = \ nsMemoryImpl.cpp \ nsTraceRefcntImpl.cpp \ nsInterfaceRequestorAgg.cpp \ + nsUUIDGenerator.cpp \ $(NULL) ifdef GC_LEAK_DETECTOR @@ -118,6 +119,7 @@ XPIDLSRCS = \ nsIException.idl \ nsIExceptionService.idl \ nsIVersionComparator.idl \ + nsIUUIDGenerator.idl \ $(NULL) ifdef GC_LEAK_DETECTOR diff --git a/mozilla/xpcom/base/nsIUUIDGenerator.idl b/mozilla/xpcom/base/nsIUUIDGenerator.idl new file mode 100644 index 00000000000..d9088b850c8 --- /dev/null +++ b/mozilla/xpcom/base/nsIUUIDGenerator.idl @@ -0,0 +1,72 @@ +/* -*- Mode: C++; tab-width: 50; 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.org code. + * + * The Initial Developer of the Original Code is + * mozilla.org + * Portions created by the Initial Developer are Copyright (C) 2005 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Vladimir Vukicevic (original author) + * + * Alternatively, the contents of this file may be used under the terms of + * either of 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 "nsISupports.idl" + +[ptr] native nsNonConstIDPtr(nsID); + +/** + * nsIUUIDGenerator is implemented by a service that can generate + * universally unique identifiers, ideally using any platform-native + * method for generating UUIDs. + */ +[scriptable, uuid(138ad1b2-c694-41cc-b201-333ce936d8b8)] +interface nsIUUIDGenerator : nsISupports +{ + /** + * Obtains a new UUID using appropriate platform-specific methods to + * obtain a nsID that can be considered to be globally unique. + * + * @returns an nsID filled in with a new UUID. + * + * @throws NS_ERROR_FAILURE if a UUID cannot be generated (e.g. if + * an underlying source of randomness is not available) + */ + nsIDPtr generateUUID(); + + /** + * Obtain a new UUID like the generateUUID method, but place it in + * the provided nsID pointer instead of allocating a new nsID. + * + * @param id an existing nsID pointer where the UUID will be stored. + * + * @throws NS_ERROR_FAILURE if a UUID cannot be generated (e.g. if + * an underlying source of randomness is not available) + */ + [noscript] void generateUUIDInPlace(in nsNonConstIDPtr id); +}; diff --git a/mozilla/xpcom/base/nsUUIDGenerator.cpp b/mozilla/xpcom/base/nsUUIDGenerator.cpp new file mode 100644 index 00000000000..85944899ebe --- /dev/null +++ b/mozilla/xpcom/base/nsUUIDGenerator.cpp @@ -0,0 +1,152 @@ +/* -*- Mode: C++; tab-width: 50; 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.org code. + * + * The Initial Developer of the Original Code is + * mozilla.org + * Portions created by the Initial Developer are Copyright (C) 2005 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Vladimir Vukicevic (original author) + * + * Alternatively, the contents of this file may be used under the terms of + * either of 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 ***** */ + +#ifdef XP_WIN +#include +#else +#include +#endif + +#include + +#include "nsUUIDGenerator.h" + +#include "prrng.h" + +NS_IMPL_ISUPPORTS1(nsUUIDGenerator, nsIUUIDGenerator) + +nsUUIDGenerator::nsUUIDGenerator() + : mInitialized(PR_FALSE) +{ +} + +nsresult +nsUUIDGenerator::Init() +{ +#ifndef XP_WIN + /* initialize random number generator using NSPR random noise */ + unsigned int seed; + + PRSize bytes = 0; + while (bytes < sizeof(seed)) { + PRSize nbytes = PR_GetRandomNoise(((unsigned char *)&seed)+bytes, + sizeof(seed)-bytes); + if (nbytes == 0) { + return NS_ERROR_FAILURE; + } + bytes += nbytes; + } + + initstate(seed, mState, sizeof(mState)); + + mRBytes = 4; +#ifdef RAND_MAX + if ((unsigned long) RAND_MAX < (unsigned long)0xffffffff) + mRBytes = 3; + if ((unsigned long) RAND_MAX < (unsigned long)0x00ffffff) + mRBytes = 2; + if ((unsigned long) RAND_MAX < (unsigned long)0x0000ffff) + mRBytes = 1; + if ((unsigned long) RAND_MAX < (unsigned long)0x000000ff) + return NS_ERROR_FAILURE; +#endif + +#endif /* non XP_WIN */ + + mInitialized = PR_TRUE; + return NS_OK; +} + +NS_IMETHODIMP +nsUUIDGenerator::GenerateUUID(nsID** ret) +{ + nsID *id = NS_STATIC_CAST(nsID*, NS_Alloc(sizeof(nsID))); + if (id == nsnull) + return NS_ERROR_OUT_OF_MEMORY; + + nsresult rv = GenerateUUIDInPlace(id); + if (NS_FAILED(rv)) { + NS_Free(id); + return rv; + } + + *ret = id; + return rv; +} + +NS_IMETHODIMP +nsUUIDGenerator::GenerateUUIDInPlace(nsID* id) +{ + if (!mInitialized) { + nsresult rv = Init(); + if (NS_FAILED(rv)) + return rv; + } + +#ifdef XP_WIN + HRESULT hr = CoCreateGuid((GUID*)id); + if (NS_FAILED(hr)) + return NS_ERROR_FAILURE; +#else /* non-windows; generate randomness using random(). */ + PRSize bytesLeft = sizeof(nsID); + while (bytesLeft > 0) { + long rval = random(); + + PRUint8 *src = (PRUint8*)&rval; +#ifdef IS_LITTLE_ENDIAN + src += sizeof(rval) - mRBytes; +#endif + PRUint8 *dst = ((PRUint8*) id) + (sizeof(nsID) - bytesLeft); + PRSize toWrite = (bytesLeft < mRBytes ? bytesLeft : mRBytes); + for (PRSize i = 0; i < toWrite; i++) + dst[i] = src[i]; + + bytesLeft -= toWrite; + } + + /* Put in the version */ + id->m2 &= 0x0fff; + id->m2 |= 0x4000; + + /* Put in the variant */ + id->m3[0] &= 0x3f; + id->m3[0] |= 0x80; +#endif + + return NS_OK; +} diff --git a/mozilla/xpcom/base/nsUUIDGenerator.h b/mozilla/xpcom/base/nsUUIDGenerator.h new file mode 100644 index 00000000000..e76d38a1fc7 --- /dev/null +++ b/mozilla/xpcom/base/nsUUIDGenerator.h @@ -0,0 +1,66 @@ +/* -*- Mode: C++; tab-width: 50; 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.org code. + * + * The Initial Developer of the Original Code is + * mozilla.org + * Portions created by the Initial Developer are Copyright (C) 2005 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Vladimir Vukicevic (original author) + * + * Alternatively, the contents of this file may be used under the terms of + * either of 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 _NSUUIDGENERATOR_H_ +#define _NSUUIDGENERATOR_H_ + +#include "nsIUUIDGenerator.h" + +class nsUUIDGenerator : public nsIUUIDGenerator { +public: + nsUUIDGenerator(); + + NS_DECL_ISUPPORTS + + NS_DECL_NSIUUIDGENERATOR + +protected: + nsresult Init(); + + PRBool mInitialized; + char mState[32]; + PRUint8 mRBytes; +}; + +#define NS_UUID_GENERATOR_CONTRACTID "@mozilla.org/uuid-generator;1" +#define NS_UUID_GENERATOR_CLASSNAME "UUID Generator" +#define NS_UUID_GENERATOR_CID \ +{ 0x706d36bb, 0xbf79, 0x4293, \ +{ 0x81, 0xf2, 0x8f, 0x68, 0x28, 0xc1, 0x8f, 0x9d } } + +#endif /* _NSUUIDGENERATOR_H_ */ diff --git a/mozilla/xpcom/build/nsXPComInit.cpp b/mozilla/xpcom/build/nsXPComInit.cpp index 978b31a5ef6..76f48d6d31c 100644 --- a/mozilla/xpcom/build/nsXPComInit.cpp +++ b/mozilla/xpcom/build/nsXPComInit.cpp @@ -113,6 +113,8 @@ #include "nsVariant.h" +#include "nsUUIDGenerator.h" + #ifdef GC_LEAK_DETECTOR #include "nsLeakDetector.h" #endif @@ -210,6 +212,8 @@ NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsHashPropertyBag, Init) NS_GENERIC_AGGREGATED_CONSTRUCTOR_INIT(nsProperties, Init) +NS_GENERIC_FACTORY_CONSTRUCTOR(nsUUIDGenerator) + static NS_METHOD nsXPTIInterfaceInfoManagerGetSingleton(nsISupports* outer, const nsIID& aIID, @@ -393,6 +397,8 @@ static const nsModuleComponentInfo components[] = { #define NS_HASH_PROPERTY_BAG_CLASSNAME "Hashtable Property Bag" COMPONENT(HASH_PROPERTY_BAG, nsHashPropertyBagConstructor), + COMPONENT(UUID_GENERATOR, nsUUIDGeneratorConstructor), + #if defined(XP_WIN) && !defined(WINCE) COMPONENT(WINDOWSREGKEY, nsWindowsRegKeyConstructor), #endif