| @@ -70,33 +70,19 @@ public: | |||
| IDispatchHelper() {} | |||
| ~IDispatchHelper() {} | |||
| var::identifier getId (const int hash) const | |||
| const String getStringFromDISPID (const DISPID hash) const | |||
| { | |||
| for (int i = knownIdentifiers.size(); --i >= 0;) | |||
| if (knownIdentifiers.getUnchecked(i)->hashCode == hash) | |||
| return *knownIdentifiers.getUnchecked(i); | |||
| for (int i = identifierPool.size(); --i >= 0;) | |||
| if (getHashFromString (identifierPool[i]) == hash) | |||
| return identifierPool[i]; | |||
| return var::identifier (String::empty); | |||
| } | |||
| var::identifier getId (const String& name) | |||
| { | |||
| for (int i = knownIdentifiers.size(); --i >= 0;) | |||
| if (knownIdentifiers.getUnchecked(i)->name == name) | |||
| return *knownIdentifiers.getUnchecked(i); | |||
| const var::identifier v (name); | |||
| knownIdentifiers.add (new var::identifier (v)); | |||
| return v; | |||
| return String::empty; | |||
| } | |||
| HRESULT doGetIDsOfNames (LPOLESTR* rgszNames, UINT cNames, DISPID* rgDispId) | |||
| { | |||
| for (unsigned int i = 0; i < cNames; ++i) | |||
| { | |||
| var::identifier id (getId (rgszNames[i])); | |||
| rgDispId[i] = (DISPID) id.hashCode; | |||
| } | |||
| rgDispId[i] = getHashFromString (identifierPool.getPooledString (String (rgszNames[i]))); | |||
| return S_OK; | |||
| } | |||
| @@ -105,9 +91,9 @@ public: | |||
| DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS* pDispParams, | |||
| VARIANT* pVarResult, EXCEPINFO* pExcepInfo, UINT* puArgErr) | |||
| { | |||
| const var::identifier memberId (getId ((int) dispIdMember)); | |||
| const Identifier memberId (getStringFromDISPID (dispIdMember)); | |||
| if (memberId.name.isEmpty() || v.getObject() == 0) | |||
| if (memberId.toString().isEmpty() || v.getObject() == 0) | |||
| return DISP_E_MEMBERNOTFOUND; | |||
| if ((wFlags & DISPATCH_METHOD) != 0) | |||
| @@ -124,16 +110,11 @@ public: | |||
| } | |||
| else | |||
| { | |||
| HeapBlock <var> args; | |||
| args.calloc (numArgs); | |||
| for (int j = 0; j < numArgs; ++j) | |||
| args[(numArgs - 1) - j] = variantTojuceVar (pDispParams->rgvarg[j]); | |||
| result = v.invoke (memberId, args, numArgs); | |||
| Array<var> args; | |||
| for (int j = numArgs; --j >= 0;) | |||
| args.add (variantTojuceVar (pDispParams->rgvarg[j])); | |||
| for (int j = 0; j < numArgs; ++j) | |||
| args[j] = var(); | |||
| result = v.invoke (memberId, args.getRawDataPointer(), numArgs); | |||
| } | |||
| if (pVarResult != 0) | |||
| @@ -165,7 +146,12 @@ public: | |||
| } | |||
| private: | |||
| OwnedArray <var::identifier> knownIdentifiers; | |||
| StringPool identifierPool; | |||
| static DISPID getHashFromString (const juce_wchar* s) throw() | |||
| { | |||
| return (DISPID) (pointer_sized_int) s; | |||
| } | |||
| IDispatchHelper (const IDispatchHelper&); | |||
| IDispatchHelper& operator= (const IDispatchHelper&); | |||
| @@ -245,11 +231,12 @@ public: | |||
| log ("num IDispatch wrapper objs: " + String (--numDOWID)); | |||
| } | |||
| const var getProperty (const var::identifier& propertyName) const | |||
| const var getProperty (const Identifier& propertyName) const | |||
| { | |||
| LPCOLESTR name = (LPCOLESTR) propertyName.name; | |||
| const String nameCopy (propertyName.toString()); | |||
| LPCOLESTR name = (LPCOLESTR) nameCopy; | |||
| DISPID id = 0; | |||
| if (source->GetIDsOfNames (IID_NULL, (LPOLESTR*)&name, 1, 0, &id) == S_OK) | |||
| if (source->GetIDsOfNames (IID_NULL, (LPOLESTR*) &name, 1, 0, &id) == S_OK) | |||
| { | |||
| EXCEPINFO excepInfo; | |||
| DISPPARAMS params; | |||
| @@ -267,21 +254,23 @@ public: | |||
| } | |||
| } | |||
| return var(); | |||
| return var::null; | |||
| } | |||
| bool hasProperty (const var::identifier& propertyName) const | |||
| bool hasProperty (const Identifier& propertyName) const | |||
| { | |||
| LPCOLESTR name = (LPCOLESTR) propertyName.name; | |||
| const String nameCopy (propertyName.toString()); | |||
| LPCOLESTR name = (LPCOLESTR) nameCopy; | |||
| DISPID id = 0; | |||
| return source->GetIDsOfNames (IID_NULL, (LPOLESTR*)&name, 1, 0, &id) == S_OK; | |||
| return source->GetIDsOfNames (IID_NULL, (LPOLESTR*) &name, 1, 0, &id) == S_OK; | |||
| } | |||
| void setProperty (const var::identifier& propertyName, const var& newValue) | |||
| void setProperty (const Identifier& propertyName, const var& newValue) | |||
| { | |||
| LPCOLESTR name = (LPCOLESTR) propertyName.name; | |||
| const String nameCopy (propertyName.toString()); | |||
| LPCOLESTR name = (LPCOLESTR) nameCopy; | |||
| DISPID id = 0; | |||
| if (source->GetIDsOfNames (IID_NULL, (LPOLESTR*)&name, 1, 0, &id) == S_OK) | |||
| if (source->GetIDsOfNames (IID_NULL, (LPOLESTR*) &name, 1, 0, &id) == S_OK) | |||
| { | |||
| VARIANT param; | |||
| zerostruct (param); | |||
| @@ -308,26 +297,26 @@ public: | |||
| } | |||
| } | |||
| void removeProperty (const var::identifier& propertyName) | |||
| void removeProperty (const Identifier& propertyName) | |||
| { | |||
| setProperty (propertyName, var()); | |||
| setProperty (propertyName, var::null); | |||
| } | |||
| bool hasMethod (const var::identifier& methodName) const | |||
| bool hasMethod (const Identifier& methodName) const | |||
| { | |||
| LPCOLESTR name = (LPCOLESTR) methodName.name; | |||
| const String nameCopy (methodName.toString()); | |||
| LPCOLESTR name = (LPCOLESTR) nameCopy; | |||
| DISPID id = 0; | |||
| return source->GetIDsOfNames (IID_NULL, (LPOLESTR*)&name, 1, 0, &id) == S_OK; | |||
| return source->GetIDsOfNames (IID_NULL, (LPOLESTR*) &name, 1, 0, &id) == S_OK; | |||
| } | |||
| const var invokeMethod (const var::identifier& methodName, | |||
| const var* parameters, | |||
| int numParameters) | |||
| const var invokeMethod (const Identifier& methodName, const var* parameters, int numParameters) | |||
| { | |||
| var returnValue; | |||
| LPCOLESTR name = (LPCOLESTR) methodName.name; | |||
| const String nameCopy (methodName.toString()); | |||
| LPCOLESTR name = (LPCOLESTR) nameCopy; | |||
| DISPID id = 0; | |||
| if (source->GetIDsOfNames (IID_NULL, (LPOLESTR*)&name, 1, 0, &id) == S_OK) | |||
| if (source->GetIDsOfNames (IID_NULL, (LPOLESTR*) &name, 1, 0, &id) == S_OK) | |||
| { | |||
| HeapBlock <VARIANT> params; | |||
| params.calloc (numParameters + 1); | |||
| @@ -409,7 +398,7 @@ const var variantTojuceVar (const VARIANT& v) | |||
| switch (v.vt & ~VT_BYREF) | |||
| { | |||
| case VT_VOID: | |||
| case VT_EMPTY: return var(); | |||
| case VT_EMPTY: return var::null; | |||
| case VT_I1: return var ((int) v.cVal); | |||
| case VT_I2: return var ((int) v.iVal); | |||
| case VT_I4: return var ((int) v.lVal); | |||
| @@ -430,7 +419,7 @@ const var variantTojuceVar (const VARIANT& v) | |||
| } | |||
| } | |||
| return var(); | |||
| return var::null; | |||
| } | |||
| //============================================================================== | |||
| @@ -542,7 +542,7 @@ public: | |||
| //============================================================================== | |||
| static NPIdentifier getIdentifierFromString (const var::identifier& s) throw() | |||
| { | |||
| return browser.getstringidentifier (s.name.toUTF8()); | |||
| return browser.getstringidentifier (s.toString().toUTF8()); | |||
| } | |||
| static const var createValueFromNPVariant (NPP npp, const NPVariant& v); | |||
| @@ -1725,7 +1725,7 @@ static void juce_testAtomics() | |||
| juce_testAtomicType ((long) 0); | |||
| juce_testAtomicType ((void*) 0); | |||
| juce_testAtomicType ((int*) 0); | |||
| #if ! ((JUCE_WINDOWS && JUCE_32BIT) || JUCE_PPC) // 64-bit intrinsics aren't available on some old platforms | |||
| #if ! JUCE_64BIT_ATOMICS_UNAVAILABLE // 64-bit intrinsics aren't available on some old platforms | |||
| juce_testAtomicType ((int64) 0); | |||
| juce_testAtomicType ((uint64) 0); | |||
| #endif | |||
| @@ -13096,6 +13096,16 @@ const juce_wchar* StringPool::getPooledString (const juce_wchar* const s) | |||
| return getPooledStringFromArray (strings, s); | |||
| } | |||
| int StringPool::size() const throw() | |||
| { | |||
| return strings.size(); | |||
| } | |||
| const juce_wchar* StringPool::operator[] (const int index) const throw() | |||
| { | |||
| return strings [index]; | |||
| } | |||
| END_JUCE_NAMESPACE | |||
| /*** End of inlined file: juce_StringPool.cpp ***/ | |||
| @@ -4731,8 +4731,12 @@ public: | |||
| /** Compares two identifiers. This is a very fast operation. */ | |||
| inline bool operator!= (const Identifier& other) const throw() { return name != other.name; } | |||
| /** Returns this identifier as a string. */ | |||
| const String toString() const { return name; } | |||
| /** Returns this identifier's raw string pointer. */ | |||
| operator const juce_wchar*() const throw() { return name; } | |||
| private: | |||
| const juce_wchar* name; | |||
| @@ -5765,6 +5769,7 @@ public: | |||
| template <typename Type> static Type OSAtomicDecrement64 (volatile Type* a) throw() { jassertfalse; return --*a; } | |||
| template <typename Type> static bool OSAtomicCompareAndSwap64Barrier (Type old, Type newValue, volatile Type* value) throw() | |||
| { jassertfalse; if (old == *value) { *value = newValue; return true; } return false; } | |||
| #define JUCE_64BIT_ATOMICS_UNAVAILABLE 1 | |||
| #endif | |||
| #elif JUCE_GCC | |||
| @@ -5773,7 +5778,7 @@ public: | |||
| #else | |||
| #define JUCE_ATOMICS_WINDOWS 1 // Windows with intrinsics | |||
| #if JUCE_USE_INTRINSICS | |||
| #if JUCE_USE_INTRINSICS || JUCE_64BIT | |||
| #pragma intrinsic (_InterlockedExchange, _InterlockedIncrement, _InterlockedDecrement, _InterlockedCompareExchange, \ | |||
| _InterlockedCompareExchange64, _InterlockedExchangeAdd, _ReadWriteBarrier) | |||
| #define juce_InterlockedExchange(a, b) _InterlockedExchange(a, b) | |||
| @@ -5806,6 +5811,7 @@ public: | |||
| template <typename Type> static Type juce_InterlockedExchange64 (volatile Type* a, Type b) throw() { jassertfalse; Type old = *a; *a = b; return old; } | |||
| template <typename Type> static Type juce_InterlockedIncrement64 (volatile Type* a) throw() { jassertfalse; return ++*a; } | |||
| template <typename Type> static Type juce_InterlockedDecrement64 (volatile Type* a) throw() { jassertfalse; return --*a; } | |||
| #define JUCE_64BIT_ATOMICS_UNAVAILABLE 1 | |||
| #endif | |||
| #endif | |||
| @@ -16801,6 +16807,7 @@ private: | |||
| class JUCE_API StringPool | |||
| { | |||
| public: | |||
| /** Creates an empty pool. */ | |||
| StringPool() throw(); | |||
| @@ -16831,6 +16838,12 @@ public: | |||
| */ | |||
| const juce_wchar* getPooledString (const juce_wchar* original); | |||
| /** Returns the number of strings in the pool. */ | |||
| int size() const throw(); | |||
| /** Returns one of the strings in the pool, by index. */ | |||
| const juce_wchar* operator[] (int index) const throw(); | |||
| private: | |||
| Array <String> strings; | |||
| }; | |||
| @@ -72,8 +72,12 @@ public: | |||
| /** Compares two identifiers. This is a very fast operation. */ | |||
| inline bool operator!= (const Identifier& other) const throw() { return name != other.name; } | |||
| /** Returns this identifier as a string. */ | |||
| const String toString() const { return name; } | |||
| /** Returns this identifier's raw string pointer. */ | |||
| operator const juce_wchar*() const throw() { return name; } | |||
| private: | |||
| //============================================================================== | |||
| const juce_wchar* name; | |||
| @@ -163,6 +163,7 @@ public: | |||
| template <typename Type> static Type OSAtomicDecrement64 (volatile Type* a) throw() { jassertfalse; return --*a; } | |||
| template <typename Type> static bool OSAtomicCompareAndSwap64Barrier (Type old, Type newValue, volatile Type* value) throw() | |||
| { jassertfalse; if (old == *value) { *value = newValue; return true; } return false; } | |||
| #define JUCE_64BIT_ATOMICS_UNAVAILABLE 1 | |||
| #endif | |||
| //============================================================================== | |||
| @@ -172,7 +173,7 @@ public: | |||
| #else | |||
| #define JUCE_ATOMICS_WINDOWS 1 // Windows with intrinsics | |||
| #if JUCE_USE_INTRINSICS | |||
| #if JUCE_USE_INTRINSICS || JUCE_64BIT | |||
| #pragma intrinsic (_InterlockedExchange, _InterlockedIncrement, _InterlockedDecrement, _InterlockedCompareExchange, \ | |||
| _InterlockedCompareExchange64, _InterlockedExchangeAdd, _ReadWriteBarrier) | |||
| #define juce_InterlockedExchange(a, b) _InterlockedExchange(a, b) | |||
| @@ -205,6 +206,7 @@ public: | |||
| template <typename Type> static Type juce_InterlockedExchange64 (volatile Type* a, Type b) throw() { jassertfalse; Type old = *a; *a = b; return old; } | |||
| template <typename Type> static Type juce_InterlockedIncrement64 (volatile Type* a) throw() { jassertfalse; return ++*a; } | |||
| template <typename Type> static Type juce_InterlockedDecrement64 (volatile Type* a) throw() { jassertfalse; return --*a; } | |||
| #define JUCE_64BIT_ATOMICS_UNAVAILABLE 1 | |||
| #endif | |||
| #endif | |||
| @@ -113,7 +113,7 @@ static void juce_testAtomics() | |||
| juce_testAtomicType ((long) 0); | |||
| juce_testAtomicType ((void*) 0); | |||
| juce_testAtomicType ((int*) 0); | |||
| #if ! ((JUCE_WINDOWS && JUCE_32BIT) || JUCE_PPC) // 64-bit intrinsics aren't available on some old platforms | |||
| #if ! JUCE_64BIT_ATOMICS_UNAVAILABLE // 64-bit intrinsics aren't available on some old platforms | |||
| juce_testAtomicType ((int64) 0); | |||
| juce_testAtomicType ((uint64) 0); | |||
| #endif | |||
| @@ -102,4 +102,14 @@ const juce_wchar* StringPool::getPooledString (const juce_wchar* const s) | |||
| return getPooledStringFromArray (strings, s); | |||
| } | |||
| int StringPool::size() const throw() | |||
| { | |||
| return strings.size(); | |||
| } | |||
| const juce_wchar* StringPool::operator[] (const int index) const throw() | |||
| { | |||
| return strings [index]; | |||
| } | |||
| END_JUCE_NAMESPACE | |||
| @@ -44,12 +44,14 @@ | |||
| class JUCE_API StringPool | |||
| { | |||
| public: | |||
| //============================================================================== | |||
| /** Creates an empty pool. */ | |||
| StringPool() throw(); | |||
| /** Destructor */ | |||
| ~StringPool(); | |||
| //============================================================================== | |||
| /** Returns a pointer to a copy of the string that is passed in. | |||
| The pool will always return the same pointer when asked for a string that matches it. | |||
| @@ -74,6 +76,13 @@ public: | |||
| */ | |||
| const juce_wchar* getPooledString (const juce_wchar* original); | |||
| //============================================================================== | |||
| /** Returns the number of strings in the pool. */ | |||
| int size() const throw(); | |||
| /** Returns one of the strings in the pool, by index. */ | |||
| const juce_wchar* operator[] (int index) const throw(); | |||
| private: | |||
| Array <String> strings; | |||
| }; | |||