1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */ 3 /* This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 #ifndef nsID_h__ 8 #define nsID_h__ 9 10 #include <string.h> 11 12 #include "nscore.h" 13 14 #define NSID_LENGTH 39 15 16 /** 17 * A "unique identifier". This is modeled after OSF DCE UUIDs. 18 */ 19 20 struct nsID { 21 /** 22 * @name Identifier values 23 */ 24 25 //@{ 26 uint32_t m0; 27 uint16_t m1; 28 uint16_t m2; 29 uint8_t m3[8]; 30 //@} 31 32 /** 33 * @name Methods 34 */ 35 36 //@{ 37 /** 38 * Ensures everything is zeroed out. 39 */ 40 void Clear(); 41 42 /** 43 * Equivalency method. Compares this nsID with another. 44 * @return <b>true</b> if they are the same, <b>false</b> if not. 45 */ 46 EqualsnsID47 inline bool Equals(const nsID& aOther) const { 48 // At the time of this writing, modern compilers (namely Clang) inline this 49 // memcmp call into a single SIMD operation on x86/x86-64 architectures (as 50 // long as we compare to zero rather than returning the full integer return 51 // value), which is measurably more efficient to any manual comparisons we 52 // can do directly. 53 #if defined(__x86_64__) || defined(__i386__) 54 return !memcmp(this, &aOther, sizeof *this); 55 #else 56 // However, on ARM architectures, compilers still tend to generate a direct 57 // memcmp call, which we'd like to avoid. 58 return (((uint32_t*)&m0)[0] == ((uint32_t*)&aOther.m0)[0]) && 59 (((uint32_t*)&m0)[1] == ((uint32_t*)&aOther.m0)[1]) && 60 (((uint32_t*)&m0)[2] == ((uint32_t*)&aOther.m0)[2]) && 61 (((uint32_t*)&m0)[3] == ((uint32_t*)&aOther.m0)[3]); 62 #endif 63 } 64 65 inline bool operator==(const nsID& aOther) const { return Equals(aOther); } 66 67 /** 68 * nsID Parsing method. Turns a {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx} 69 * string into an nsID 70 */ 71 bool Parse(const char* aIDStr); 72 73 #ifndef XPCOM_GLUE_AVOID_NSPR 74 /** 75 * nsID string encoder. Returns an allocated string in 76 * {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx} format. Caller should free string. 77 * YOU SHOULD ONLY USE THIS IF YOU CANNOT USE ToProvidedString() BELOW. 78 */ 79 char* ToString() const; 80 81 /** 82 * nsID string encoder. Builds a string in 83 * {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx} format, into a char[NSID_LENGTH] 84 * buffer provided by the caller (for instance, on the stack). 85 */ 86 void ToProvidedString(char (&aDest)[NSID_LENGTH]) const; 87 88 #endif // XPCOM_GLUE_AVOID_NSPR 89 90 // Infallibly duplicate an nsID. Must be freed with free(). 91 nsID* Clone() const; 92 93 //@} 94 }; 95 96 #ifndef XPCOM_GLUE_AVOID_NSPR 97 /** 98 * A stack helper class to convert a nsID to a string. Useful 99 * for printing nsIDs. For example: 100 * nsID aID = ...; 101 * printf("%s", nsIDToCString(aID).get()); 102 */ 103 class nsIDToCString { 104 public: nsIDToCString(const nsID & aID)105 explicit nsIDToCString(const nsID& aID) { 106 aID.ToProvidedString(mStringBytes); 107 } 108 get()109 const char* get() const { return mStringBytes; } 110 111 protected: 112 char mStringBytes[NSID_LENGTH]; 113 }; 114 #endif 115 116 /* 117 * Class IDs 118 */ 119 120 typedef nsID nsCID; 121 122 // Define an CID 123 #define NS_DEFINE_CID(_name, _cidspec) const nsCID _name = _cidspec 124 125 #define NS_DEFINE_NAMED_CID(_name) static const nsCID k##_name = _name 126 127 #define REFNSCID const nsCID& 128 129 /** 130 * An "interface id" which can be used to uniquely identify a given 131 * interface. 132 */ 133 134 typedef nsID nsIID; 135 136 /** 137 * A macro shorthand for <tt>const nsIID&<tt> 138 */ 139 140 #define REFNSIID const nsIID& 141 142 /** 143 * Define an IID 144 * obsolete - do not use this macro 145 */ 146 147 #define NS_DEFINE_IID(_name, _iidspec) const nsIID _name = _iidspec 148 149 /** 150 * A macro to build the static const IID accessor method. The Dummy 151 * template parameter only exists so that the kIID symbol will be linked 152 * properly (weak symbol on linux, gnu_linkonce on mac, multiple-definitions 153 * merged on windows). Dummy should always be instantiated as "void". 154 */ 155 156 #define NS_DECLARE_STATIC_IID_ACCESSOR(the_iid) \ 157 template <typename T, typename U> \ 158 struct COMTypeInfo; 159 160 #define NS_DEFINE_STATIC_IID_ACCESSOR(the_interface, the_iid) \ 161 template <typename T> \ 162 struct the_interface::COMTypeInfo<the_interface, T> { \ 163 static const nsIID kIID NS_HIDDEN; \ 164 }; \ 165 template <typename T> \ 166 const nsIID the_interface::COMTypeInfo<the_interface, T>::kIID NS_HIDDEN = \ 167 the_iid; 168 169 /** 170 * A macro to build the static const CID accessor method 171 */ 172 173 #define NS_DEFINE_STATIC_CID_ACCESSOR(the_cid) \ 174 static const nsID& GetCID() { \ 175 static const nsID cid = the_cid; \ 176 return cid; \ 177 } 178 179 #define NS_GET_IID(T) (T::COMTypeInfo<T, void>::kIID) 180 #define NS_GET_TEMPLATE_IID(T) (T::template COMTypeInfo<T, void>::kIID) 181 182 #endif 183