diff options
Diffstat (limited to 'LibOVR/Src/Kernel')
57 files changed, 0 insertions, 33288 deletions
diff --git a/LibOVR/Src/Kernel/OVR_Alg.cpp b/LibOVR/Src/Kernel/OVR_Alg.cpp deleted file mode 100644 index c087777..0000000 --- a/LibOVR/Src/Kernel/OVR_Alg.cpp +++ /dev/null @@ -1,57 +0,0 @@ -/************************************************************************************ - -Filename : OVR_Alg.cpp -Content : Static lookup tables for Alg functions -Created : September 19, 2012 -Notes : - -Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); -you may not use the Oculus VR Rift SDK except in compliance with the License, -which is provided at the time of installation or download, or which -otherwise accompanies this software in either electronic or hard copy form. - -You may obtain a copy of the License at - -http://www.oculusvr.com/licenses/LICENSE-3.2 - -Unless required by applicable law or agreed to in writing, the Oculus VR SDK -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -************************************************************************************/ - -#include "OVR_Types.h" - -namespace OVR { namespace Alg { - -//------------------------------------------------------------------------ -extern const uint8_t UpperBitTable[256] = -{ - 0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4, - 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, - 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, - 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, - 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, - 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, - 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, - 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7 -}; - -extern const uint8_t LowerBitTable[256] = -{ - 8,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0, - 5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0, - 6,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0, - 5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0, - 7,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0, - 5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0, - 6,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0, - 5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0 -}; - - -}} // OVE::Alg diff --git a/LibOVR/Src/Kernel/OVR_Alg.h b/LibOVR/Src/Kernel/OVR_Alg.h deleted file mode 100644 index f7f461f..0000000 --- a/LibOVR/Src/Kernel/OVR_Alg.h +++ /dev/null @@ -1,1062 +0,0 @@ -/************************************************************************************ - -PublicHeader: OVR_Kernel.h -Filename : OVR_Alg.h -Content : Simple general purpose algorithms: Sort, Binary Search, etc. -Created : September 19, 2012 -Notes : - -Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); -you may not use the Oculus VR Rift SDK except in compliance with the License, -which is provided at the time of installation or download, or which -otherwise accompanies this software in either electronic or hard copy form. - -You may obtain a copy of the License at - -http://www.oculusvr.com/licenses/LICENSE-3.2 - -Unless required by applicable law or agreed to in writing, the Oculus VR SDK -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -************************************************************************************/ - -#ifndef OVR_Alg_h -#define OVR_Alg_h - -#include "OVR_Types.h" -#include <string.h> - -namespace OVR { namespace Alg { - - -//----------------------------------------------------------------------------------- -// ***** Operator extensions - -template <typename T> OVR_FORCE_INLINE void Swap(T &a, T &b) -{ T temp(a); a = b; b = temp; } - - -// ***** min/max are not implemented in Visual Studio 6 standard STL - -template <typename T> OVR_FORCE_INLINE const T Min(const T a, const T b) -{ return (a < b) ? a : b; } - -template <typename T> OVR_FORCE_INLINE const T Max(const T a, const T b) -{ return (b < a) ? a : b; } - -template <typename T> OVR_FORCE_INLINE const T Clamp(const T v, const T minVal, const T maxVal) -{ return Max<T>(minVal, Min<T>(v, maxVal)); } - -template <typename T> OVR_FORCE_INLINE int Chop(T f) -{ return (int)f; } - -template <typename T> OVR_FORCE_INLINE T Lerp(T a, T b, T f) -{ return (b - a) * f + a; } - - -// These functions stand to fix a stupid VC++ warning (with /Wp64 on): -// "warning C4267: 'argument' : conversion from 'size_t' to 'const unsigned', possible loss of data" -// Use these functions instead of gmin/gmax if the argument has size -// of the pointer to avoid the warning. Though, functionally they are -// absolutelly the same as regular gmin/gmax. -template <typename T> OVR_FORCE_INLINE const T PMin(const T a, const T b) -{ - OVR_COMPILER_ASSERT(sizeof(T) == sizeof(size_t)); - return (a < b) ? a : b; -} -template <typename T> OVR_FORCE_INLINE const T PMax(const T a, const T b) -{ - OVR_COMPILER_ASSERT(sizeof(T) == sizeof(size_t)); - return (b < a) ? a : b; -} - - -template <typename T> OVR_FORCE_INLINE const T Abs(const T v) -{ return (v>=0) ? v : -v; } - - -//----------------------------------------------------------------------------------- -// ***** OperatorLess -// -template<class T> struct OperatorLess -{ - static bool Compare(const T& a, const T& b) - { - return a < b; - } -}; - - -//----------------------------------------------------------------------------------- -// ***** QuickSortSliced -// -// Sort any part of any array: plain, Array, ArrayPaged, ArrayUnsafe. -// The range is specified with start, end, where "end" is exclusive! -// The comparison predicate must be specified. -template<class Array, class Less> -void QuickSortSliced(Array& arr, size_t start, size_t end, Less less) -{ - enum - { - Threshold = 9 - }; - - if(end - start < 2) return; - - intptr_t stack[80]; - intptr_t* top = stack; - intptr_t base = (intptr_t)start; - intptr_t limit = (intptr_t)end; - - for(;;) - { - intptr_t len = limit - base; - intptr_t i, j, pivot; - - if(len > Threshold) - { - // we use base + len/2 as the pivot - pivot = base + len / 2; - Swap(arr[base], arr[pivot]); - - i = base + 1; - j = limit - 1; - - // now ensure that *i <= *base <= *j - if(less(arr[j], arr[i])) Swap(arr[j], arr[i]); - if(less(arr[base], arr[i])) Swap(arr[base], arr[i]); - if(less(arr[j], arr[base])) Swap(arr[j], arr[base]); - - for(;;) - { - do i++; while( less(arr[i], arr[base]) ); - do j--; while( less(arr[base], arr[j]) ); - - if( i > j ) - { - break; - } - - Swap(arr[i], arr[j]); - } - - Swap(arr[base], arr[j]); - - // now, push the largest sub-array - if(j - base > limit - i) - { - top[0] = base; - top[1] = j; - base = i; - } - else - { - top[0] = i; - top[1] = limit; - limit = j; - } - top += 2; - } - else - { - // the sub-array is small, perform insertion sort - j = base; - i = j + 1; - - for(; i < limit; j = i, i++) - { - for(; less(arr[j + 1], arr[j]); j--) - { - Swap(arr[j + 1], arr[j]); - if(j == base) - { - break; - } - } - } - if(top > stack) - { - top -= 2; - base = top[0]; - limit = top[1]; - } - else - { - break; - } - } - } -} - - -//----------------------------------------------------------------------------------- -// ***** QuickSortSliced -// -// Sort any part of any array: plain, Array, ArrayPaged, ArrayUnsafe. -// The range is specified with start, end, where "end" is exclusive! -// The data type must have a defined "<" operator. -template<class Array> -void QuickSortSliced(Array& arr, size_t start, size_t end) -{ - typedef typename Array::ValueType ValueType; - QuickSortSliced(arr, start, end, OperatorLess<ValueType>::Compare); -} - -// Same as corresponding G_QuickSortSliced but with checking array limits to avoid -// crash in the case of wrong comparator functor. -template<class Array, class Less> -bool QuickSortSlicedSafe(Array& arr, size_t start, size_t end, Less less) -{ - enum - { - Threshold = 9 - }; - - if(end - start < 2) return true; - - intptr_t stack[80]; - intptr_t* top = stack; - intptr_t base = (intptr_t)start; - intptr_t limit = (intptr_t)end; - - for(;;) - { - intptr_t len = limit - base; - intptr_t i, j, pivot; - - if(len > Threshold) - { - // we use base + len/2 as the pivot - pivot = base + len / 2; - Swap(arr[base], arr[pivot]); - - i = base + 1; - j = limit - 1; - - // now ensure that *i <= *base <= *j - if(less(arr[j], arr[i])) Swap(arr[j], arr[i]); - if(less(arr[base], arr[i])) Swap(arr[base], arr[i]); - if(less(arr[j], arr[base])) Swap(arr[j], arr[base]); - - for(;;) - { - do - { - i++; - if (i >= limit) - return false; - } while( less(arr[i], arr[base]) ); - do - { - j--; - if (j < 0) - return false; - } while( less(arr[base], arr[j]) ); - - if( i > j ) - { - break; - } - - Swap(arr[i], arr[j]); - } - - Swap(arr[base], arr[j]); - - // now, push the largest sub-array - if(j - base > limit - i) - { - top[0] = base; - top[1] = j; - base = i; - } - else - { - top[0] = i; - top[1] = limit; - limit = j; - } - top += 2; - } - else - { - // the sub-array is small, perform insertion sort - j = base; - i = j + 1; - - for(; i < limit; j = i, i++) - { - for(; less(arr[j + 1], arr[j]); j--) - { - Swap(arr[j + 1], arr[j]); - if(j == base) - { - break; - } - } - } - if(top > stack) - { - top -= 2; - base = top[0]; - limit = top[1]; - } - else - { - break; - } - } - } - return true; -} - -template<class Array> -bool QuickSortSlicedSafe(Array& arr, size_t start, size_t end) -{ - typedef typename Array::ValueType ValueType; - return QuickSortSlicedSafe(arr, start, end, OperatorLess<ValueType>::Compare); -} - -//----------------------------------------------------------------------------------- -// ***** QuickSort -// -// Sort an array Array, ArrayPaged, ArrayUnsafe. -// The array must have GetSize() function. -// The comparison predicate must be specified. -template<class Array, class Less> -void QuickSort(Array& arr, Less less) -{ - QuickSortSliced(arr, 0, arr.GetSize(), less); -} - -// checks for boundaries -template<class Array, class Less> -bool QuickSortSafe(Array& arr, Less less) -{ - return QuickSortSlicedSafe(arr, 0, arr.GetSize(), less); -} - - -//----------------------------------------------------------------------------------- -// ***** QuickSort -// -// Sort an array Array, ArrayPaged, ArrayUnsafe. -// The array must have GetSize() function. -// The data type must have a defined "<" operator. -template<class Array> -void QuickSort(Array& arr) -{ - typedef typename Array::ValueType ValueType; - QuickSortSliced(arr, 0, arr.GetSize(), OperatorLess<ValueType>::Compare); -} - -template<class Array> -bool QuickSortSafe(Array& arr) -{ - typedef typename Array::ValueType ValueType; - return QuickSortSlicedSafe(arr, 0, arr.GetSize(), OperatorLess<ValueType>::Compare); -} - -//----------------------------------------------------------------------------------- -// ***** InsertionSortSliced -// -// Sort any part of any array: plain, Array, ArrayPaged, ArrayUnsafe. -// The range is specified with start, end, where "end" is exclusive! -// The comparison predicate must be specified. -// Unlike Quick Sort, the Insertion Sort works much slower in average, -// but may be much faster on almost sorted arrays. Besides, it guarantees -// that the elements will not be swapped if not necessary. For example, -// an array with all equal elements will remain "untouched", while -// Quick Sort will considerably shuffle the elements in this case. -template<class Array, class Less> -void InsertionSortSliced(Array& arr, size_t start, size_t end, Less less) -{ - size_t j = start; - size_t i = j + 1; - size_t limit = end; - - for(; i < limit; j = i, i++) - { - for(; less(arr[j + 1], arr[j]); j--) - { - Swap(arr[j + 1], arr[j]); - if(j <= start) - { - break; - } - } - } -} - - -//----------------------------------------------------------------------------------- -// ***** InsertionSortSliced -// -// Sort any part of any array: plain, Array, ArrayPaged, ArrayUnsafe. -// The range is specified with start, end, where "end" is exclusive! -// The data type must have a defined "<" operator. -template<class Array> -void InsertionSortSliced(Array& arr, size_t start, size_t end) -{ - typedef typename Array::ValueType ValueType; - InsertionSortSliced(arr, start, end, OperatorLess<ValueType>::Compare); -} - -//----------------------------------------------------------------------------------- -// ***** InsertionSort -// -// Sort an array Array, ArrayPaged, ArrayUnsafe. -// The array must have GetSize() function. -// The comparison predicate must be specified. - -template<class Array, class Less> -void InsertionSort(Array& arr, Less less) -{ - InsertionSortSliced(arr, 0, arr.GetSize(), less); -} - -//----------------------------------------------------------------------------------- -// ***** InsertionSort -// -// Sort an array Array, ArrayPaged, ArrayUnsafe. -// The array must have GetSize() function. -// The data type must have a defined "<" operator. -template<class Array> -void InsertionSort(Array& arr) -{ - typedef typename Array::ValueType ValueType; - InsertionSortSliced(arr, 0, arr.GetSize(), OperatorLess<ValueType>::Compare); -} - -//----------------------------------------------------------------------------------- -// ***** Median -// Returns a median value of the input array. -// Caveats: partially sorts the array, returns a reference to the array element -// TBD: This needs to be optimized and generalized -// -template<class Array> -typename Array::ValueType& Median(Array& arr) -{ - size_t count = arr.GetSize(); - size_t mid = (count - 1) / 2; - OVR_ASSERT(count > 0); - - for (size_t j = 0; j <= mid; j++) - { - size_t min = j; - for (size_t k = j + 1; k < count; k++) - if (arr[k] < arr[min]) - min = k; - Swap(arr[j], arr[min]); - } - return arr[mid]; -} - -//----------------------------------------------------------------------------------- -// ***** LowerBoundSliced -// -template<class Array, class Value, class Less> -size_t LowerBoundSliced(const Array& arr, size_t start, size_t end, const Value& val, Less less) -{ - intptr_t first = (intptr_t)start; - intptr_t len = (intptr_t)(end - start); - intptr_t half; - intptr_t middle; - - while(len > 0) - { - half = len >> 1; - middle = first + half; - if(less(arr[middle], val)) - { - first = middle + 1; - len = len - half - 1; - } - else - { - len = half; - } - } - return (size_t)first; -} - - -//----------------------------------------------------------------------------------- -// ***** LowerBoundSliced -// -template<class Array, class Value> -size_t LowerBoundSliced(const Array& arr, size_t start, size_t end, const Value& val) -{ - return LowerBoundSliced(arr, start, end, val, OperatorLess<Value>::Compare); -} - -//----------------------------------------------------------------------------------- -// ***** LowerBoundSized -// -template<class Array, class Value> -size_t LowerBoundSized(const Array& arr, size_t size, const Value& val) -{ - return LowerBoundSliced(arr, 0, size, val, OperatorLess<Value>::Compare); -} - -//----------------------------------------------------------------------------------- -// ***** LowerBound -// -template<class Array, class Value, class Less> -size_t LowerBound(const Array& arr, const Value& val, Less less) -{ - return LowerBoundSliced(arr, 0, arr.GetSize(), val, less); -} - - -//----------------------------------------------------------------------------------- -// ***** LowerBound -// -template<class Array, class Value> -size_t LowerBound(const Array& arr, const Value& val) -{ - return LowerBoundSliced(arr, 0, arr.GetSize(), val, OperatorLess<Value>::Compare); -} - - - -//----------------------------------------------------------------------------------- -// ***** UpperBoundSliced -// -template<class Array, class Value, class Less> -size_t UpperBoundSliced(const Array& arr, size_t start, size_t end, const Value& val, Less less) -{ - intptr_t first = (intptr_t)start; - intptr_t len = (intptr_t)(end - start); - intptr_t half; - intptr_t middle; - - while(len > 0) - { - half = len >> 1; - middle = first + half; - if(less(val, arr[middle])) - { - len = half; - } - else - { - first = middle + 1; - len = len - half - 1; - } - } - return (size_t)first; -} - - -//----------------------------------------------------------------------------------- -// ***** UpperBoundSliced -// -template<class Array, class Value> -size_t UpperBoundSliced(const Array& arr, size_t start, size_t end, const Value& val) -{ - return UpperBoundSliced(arr, start, end, val, OperatorLess<Value>::Compare); -} - - -//----------------------------------------------------------------------------------- -// ***** UpperBoundSized -// -template<class Array, class Value> -size_t UpperBoundSized(const Array& arr, size_t size, const Value& val) -{ - return UpperBoundSliced(arr, 0, size, val, OperatorLess<Value>::Compare); -} - - -//----------------------------------------------------------------------------------- -// ***** UpperBound -// -template<class Array, class Value, class Less> -size_t UpperBound(const Array& arr, const Value& val, Less less) -{ - return UpperBoundSliced(arr, 0, arr.GetSize(), val, less); -} - - -//----------------------------------------------------------------------------------- -// ***** UpperBound -// -template<class Array, class Value> -size_t UpperBound(const Array& arr, const Value& val) -{ - return UpperBoundSliced(arr, 0, arr.GetSize(), val, OperatorLess<Value>::Compare); -} - - -//----------------------------------------------------------------------------------- -// ***** ReverseArray -// -template<class Array> void ReverseArray(Array& arr) -{ - intptr_t from = 0; - intptr_t to = arr.GetSize() - 1; - while(from < to) - { - Swap(arr[from], arr[to]); - ++from; - --to; - } -} - - -// ***** AppendArray -// -template<class CDst, class CSrc> -void AppendArray(CDst& dst, const CSrc& src) -{ - size_t i; - for(i = 0; i < src.GetSize(); i++) - dst.PushBack(src[i]); -} - -//----------------------------------------------------------------------------------- -// ***** ArrayAdaptor -// -// A simple adapter that provides the GetSize() method and overloads -// operator []. Used to wrap plain arrays in QuickSort and such. -template<class T> class ArrayAdaptor -{ -public: - typedef T ValueType; - ArrayAdaptor() : Data(0), Size(0) {} - ArrayAdaptor(T* ptr, size_t size) : Data(ptr), Size(size) {} - size_t GetSize() const { return Size; } - int GetSizeI() const { return (int)GetSize(); } - const T& operator [] (size_t i) const { return Data[i]; } - T& operator [] (size_t i) { return Data[i]; } -private: - T* Data; - size_t Size; -}; - - -//----------------------------------------------------------------------------------- -// ***** GConstArrayAdaptor -// -// A simple const adapter that provides the GetSize() method and overloads -// operator []. Used to wrap plain arrays in LowerBound and such. -template<class T> class ConstArrayAdaptor -{ -public: - typedef T ValueType; - ConstArrayAdaptor() : Data(0), Size(0) {} - ConstArrayAdaptor(const T* ptr, size_t size) : Data(ptr), Size(size) {} - size_t GetSize() const { return Size; } - int GetSizeI() const { return (int)GetSize(); } - const T& operator [] (size_t i) const { return Data[i]; } -private: - const T* Data; - size_t Size; -}; - - - -//----------------------------------------------------------------------------------- -extern const uint8_t UpperBitTable[256]; -extern const uint8_t LowerBitTable[256]; - - - -//----------------------------------------------------------------------------------- -inline uint8_t UpperBit(size_t val) -{ -#ifndef OVR_64BIT_POINTERS - - if (val & 0xFFFF0000) - { - return (val & 0xFF000000) ? - UpperBitTable[(val >> 24) ] + 24: - UpperBitTable[(val >> 16) & 0xFF] + 16; - } - return (val & 0xFF00) ? - UpperBitTable[(val >> 8) & 0xFF] + 8: - UpperBitTable[(val ) & 0xFF]; - -#else - - if (val & 0xFFFFFFFF00000000) - { - if (val & 0xFFFF000000000000) - { - return (val & 0xFF00000000000000) ? - UpperBitTable[(val >> 56) ] + 56: - UpperBitTable[(val >> 48) & 0xFF] + 48; - } - return (val & 0xFF0000000000) ? - UpperBitTable[(val >> 40) & 0xFF] + 40: - UpperBitTable[(val >> 32) & 0xFF] + 32; - } - else - { - if (val & 0xFFFF0000) - { - return (val & 0xFF000000) ? - UpperBitTable[(val >> 24) ] + 24: - UpperBitTable[(val >> 16) & 0xFF] + 16; - } - return (val & 0xFF00) ? - UpperBitTable[(val >> 8) & 0xFF] + 8: - UpperBitTable[(val ) & 0xFF]; - } - -#endif -} - -//----------------------------------------------------------------------------------- -inline uint8_t LowerBit(size_t val) -{ -#ifndef OVR_64BIT_POINTERS - - if (val & 0xFFFF) - { - return (val & 0xFF) ? - LowerBitTable[ val & 0xFF]: - LowerBitTable[(val >> 8) & 0xFF] + 8; - } - return (val & 0xFF0000) ? - LowerBitTable[(val >> 16) & 0xFF] + 16: - LowerBitTable[(val >> 24) & 0xFF] + 24; - -#else - - if (val & 0xFFFFFFFF) - { - if (val & 0xFFFF) - { - return (val & 0xFF) ? - LowerBitTable[ val & 0xFF]: - LowerBitTable[(val >> 8) & 0xFF] + 8; - } - return (val & 0xFF0000) ? - LowerBitTable[(val >> 16) & 0xFF] + 16: - LowerBitTable[(val >> 24) & 0xFF] + 24; - } - else - { - if (val & 0xFFFF00000000) - { - return (val & 0xFF00000000) ? - LowerBitTable[(val >> 32) & 0xFF] + 32: - LowerBitTable[(val >> 40) & 0xFF] + 40; - } - return (val & 0xFF000000000000) ? - LowerBitTable[(val >> 48) & 0xFF] + 48: - LowerBitTable[(val >> 56) & 0xFF] + 56; - } - -#endif -} - - - -// ******* Special (optimized) memory routines -// Note: null (bad) pointer is not tested -class MemUtil -{ -public: - - // Memory compare - static int Cmp (const void* p1, const void* p2, size_t byteCount) { return memcmp(p1, p2, byteCount); } - static int Cmp16(const void* p1, const void* p2, size_t int16Count); - static int Cmp32(const void* p1, const void* p2, size_t int32Count); - static int Cmp64(const void* p1, const void* p2, size_t int64Count); -}; - -// ** Inline Implementation - -inline int MemUtil::Cmp16(const void* p1, const void* p2, size_t int16Count) -{ - int16_t* pa = (int16_t*)p1; - int16_t* pb = (int16_t*)p2; - unsigned ic = 0; - if (int16Count == 0) - return 0; - while (pa[ic] == pb[ic]) - if (++ic==int16Count) - return 0; - return pa[ic] > pb[ic] ? 1 : -1; -} -inline int MemUtil::Cmp32(const void* p1, const void* p2, size_t int32Count) -{ - int32_t* pa = (int32_t*)p1; - int32_t* pb = (int32_t*)p2; - unsigned ic = 0; - if (int32Count == 0) - return 0; - while (pa[ic] == pb[ic]) - if (++ic==int32Count) - return 0; - return pa[ic] > pb[ic] ? 1 : -1; -} -inline int MemUtil::Cmp64(const void* p1, const void* p2, size_t int64Count) -{ - int64_t* pa = (int64_t*)p1; - int64_t* pb = (int64_t*)p2; - unsigned ic = 0; - if (int64Count == 0) - return 0; - while (pa[ic] == pb[ic]) - if (++ic==int64Count) - return 0; - return pa[ic] > pb[ic] ? 1 : -1; -} - -// ** End Inline Implementation - - -//----------------------------------------------------------------------------------- -// ******* Byte Order Conversions -namespace ByteUtil { - - // *** Swap Byte Order - - // Swap the byte order of a byte array - inline void SwapOrder(void* pv, int size) - { - uint8_t* pb = (uint8_t*)pv; - uint8_t temp; - for (int i = 0; i < size>>1; i++) - { - temp = pb[size-1-i]; - pb[size-1-i] = pb[i]; - pb[i] = temp; - } - } - - // Swap the byte order of primitive types - inline uint8_t SwapOrder(uint8_t v) { return v; } - inline int8_t SwapOrder(int8_t v) { return v; } - inline uint16_t SwapOrder(uint16_t v) { return uint16_t(v>>8)|uint16_t(v<<8); } - inline int16_t SwapOrder(int16_t v) { return int16_t((uint16_t(v)>>8)|(v<<8)); } - inline uint32_t SwapOrder(uint32_t v) { return (v>>24)|((v&0x00FF0000)>>8)|((v&0x0000FF00)<<8)|(v<<24); } - inline int32_t SwapOrder(int32_t p) { return (int32_t)SwapOrder(uint32_t(p)); } - inline uint64_t SwapOrder(uint64_t v) - { - return (v>>56) | - ((v&uint64_t(0x00FF000000000000ULL))>>40) | - ((v&uint64_t(0x0000FF0000000000ULL))>>24) | - ((v&uint64_t(0x000000FF00000000ULL))>>8) | - ((v&uint64_t(0x00000000FF000000ULL))<<8) | - ((v&uint64_t(0x0000000000FF0000ULL))<<24) | - ((v&uint64_t(0x000000000000FF00ULL))<<40) | - (v<<56); - } - inline int64_t SwapOrder(int64_t v) { return (int64_t)SwapOrder(uint64_t(v)); } - inline float SwapOrder(float p) - { - union { - float p; - uint32_t v; - } u; - u.p = p; - u.v = SwapOrder(u.v); - return u.p; - } - - inline double SwapOrder(double p) - { - union { - double p; - uint64_t v; - } u; - u.p = p; - u.v = SwapOrder(u.v); - return u.p; - } - - // *** Byte-order conversion - -#if (OVR_BYTE_ORDER == OVR_LITTLE_ENDIAN) - // Little Endian to System (LE) - inline uint8_t LEToSystem(uint8_t v) { return v; } - inline int8_t LEToSystem(int8_t v) { return v; } - inline uint16_t LEToSystem(uint16_t v) { return v; } - inline int16_t LEToSystem(int16_t v) { return v; } - inline uint32_t LEToSystem(uint32_t v) { return v; } - inline int32_t LEToSystem(int32_t v) { return v; } - inline uint64_t LEToSystem(uint64_t v) { return v; } - inline int64_t LEToSystem(int64_t v) { return v; } - inline float LEToSystem(float v) { return v; } - inline double LEToSystem(double v) { return v; } - - // Big Endian to System (LE) - inline uint8_t BEToSystem(uint8_t v) { return SwapOrder(v); } - inline int8_t BEToSystem(int8_t v) { return SwapOrder(v); } - inline uint16_t BEToSystem(uint16_t v) { return SwapOrder(v); } - inline int16_t BEToSystem(int16_t v) { return SwapOrder(v); } - inline uint32_t BEToSystem(uint32_t v) { return SwapOrder(v); } - inline int32_t BEToSystem(int32_t v) { return SwapOrder(v); } - inline uint64_t BEToSystem(uint64_t v) { return SwapOrder(v); } - inline int64_t BEToSystem(int64_t v) { return SwapOrder(v); } - inline float BEToSystem(float v) { return SwapOrder(v); } - inline double BEToSystem(double v) { return SwapOrder(v); } - - // System (LE) to Little Endian - inline uint8_t SystemToLE(uint8_t v) { return v; } - inline int8_t SystemToLE(int8_t v) { return v; } - inline uint16_t SystemToLE(uint16_t v) { return v; } - inline int16_t SystemToLE(int16_t v) { return v; } - inline uint32_t SystemToLE(uint32_t v) { return v; } - inline int32_t SystemToLE(int32_t v) { return v; } - inline uint64_t SystemToLE(uint64_t v) { return v; } - inline int64_t SystemToLE(int64_t v) { return v; } - inline float SystemToLE(float v) { return v; } - inline double SystemToLE(double v) { return v; } - - // System (LE) to Big Endian - inline uint8_t SystemToBE(uint8_t v) { return SwapOrder(v); } - inline int8_t SystemToBE(int8_t v) { return SwapOrder(v); } - inline uint16_t SystemToBE(uint16_t v) { return SwapOrder(v); } - inline int16_t SystemToBE(int16_t v) { return SwapOrder(v); } - inline uint32_t SystemToBE(uint32_t v) { return SwapOrder(v); } - inline int32_t SystemToBE(int32_t v) { return SwapOrder(v); } - inline uint64_t SystemToBE(uint64_t v) { return SwapOrder(v); } - inline int64_t SystemToBE(int64_t v) { return SwapOrder(v); } - inline float SystemToBE(float v) { return SwapOrder(v); } - inline double SystemToBE(double v) { return SwapOrder(v); } - -#elif (OVR_BYTE_ORDER == OVR_BIG_ENDIAN) - // Little Endian to System (BE) - inline uint8_t LEToSystem(uint8_t v) { return SwapOrder(v); } - inline int8_t LEToSystem(int8_t v) { return SwapOrder(v); } - inline uint16_t LEToSystem(uint16_t v) { return SwapOrder(v); } - inline int16_t LEToSystem(int16_t v) { return SwapOrder(v); } - inline uint32_t LEToSystem(uint32_t v) { return SwapOrder(v); } - inline int32_t LEToSystem(int32_t v) { return SwapOrder(v); } - inline uint64_t LEToSystem(uint64_t v) { return SwapOrder(v); } - inline int64_t LEToSystem(int64_t v) { return SwapOrder(v); } - inline float LEToSystem(float v) { return SwapOrder(v); } - inline double LEToSystem(double v) { return SwapOrder(v); } - - // Big Endian to System (BE) - inline uint8_t BEToSystem(uint8_t v) { return v; } - inline int8_t BEToSystem(int8_t v) { return v; } - inline uint16_t BEToSystem(uint16_t v) { return v; } - inline int16_t BEToSystem(int16_t v) { return v; } - inline uint32_t BEToSystem(uint32_t v) { return v; } - inline int32_t BEToSystem(int32_t v) { return v; } - inline uint64_t BEToSystem(uint64_t v) { return v; } - inline int64_t BEToSystem(int64_t v) { return v; } - inline float BEToSystem(float v) { return v; } - inline double BEToSystem(double v) { return v; } - - // System (BE) to Little Endian - inline uint8_t SystemToLE(uint8_t v) { return SwapOrder(v); } - inline int8_t SystemToLE(int8_t v) { return SwapOrder(v); } - inline uint16_t SystemToLE(uint16_t v) { return SwapOrder(v); } - inline int16_t SystemToLE(int16_t v) { return SwapOrder(v); } - inline uint32_t SystemToLE(uint32_t v) { return SwapOrder(v); } - inline int32_t SystemToLE(int32_t v) { return SwapOrder(v); } - inline uint64_t SystemToLE(uint64_t v) { return SwapOrder(v); } - inline int64_t SystemToLE(int64_t v) { return SwapOrder(v); } - inline float SystemToLE(float v) { return SwapOrder(v); } - inline double SystemToLE(double v) { return SwapOrder(v); } - - // System (BE) to Big Endian - inline uint8_t SystemToBE(uint8_t v) { return v; } - inline int8_t SystemToBE(int8_t v) { return v; } - inline uint16_t SystemToBE(uint16_t v) { return v; } - inline int16_t SystemToBE(int16_t v) { return v; } - inline uint32_t SystemToBE(uint32_t v) { return v; } - inline int32_t SystemToBE(int32_t v) { return v; } - inline uint64_t SystemToBE(uint64_t v) { return v; } - inline int64_t SystemToBE(int64_t v) { return v; } - inline float SystemToBE(float v) { return v; } - inline double SystemToBE(double v) { return v; } - -#else - #error "OVR_BYTE_ORDER must be defined to OVR_LITTLE_ENDIAN or OVR_BIG_ENDIAN" -#endif - -} // namespace ByteUtil - - - -// Used primarily for hardware interfacing such as sensor reports, firmware, etc. -// Reported data is all little-endian. -inline uint16_t DecodeUInt16(const uint8_t* buffer) -{ - return ByteUtil::LEToSystem ( *(const uint16_t*)buffer ); -} - -inline int16_t DecodeSInt16(const uint8_t* buffer) -{ - return ByteUtil::LEToSystem ( *(const int16_t*)buffer ); -} - -inline uint32_t DecodeUInt32(const uint8_t* buffer) -{ - return ByteUtil::LEToSystem ( *(const uint32_t*)buffer ); -} - -inline int32_t DecodeSInt32(const uint8_t* buffer) -{ - return ByteUtil::LEToSystem ( *(const int32_t*)buffer ); -} - -inline float DecodeFloat(const uint8_t* buffer) -{ - union { - uint32_t U; - float F; - }; - - U = DecodeUInt32(buffer); - return F; -} - -inline void EncodeUInt16(uint8_t* buffer, uint16_t val) -{ - *(uint16_t*)buffer = ByteUtil::SystemToLE ( val ); -} - -inline void EncodeSInt16(uint8_t* buffer, int16_t val) -{ - *(int16_t*)buffer = ByteUtil::SystemToLE ( val ); -} - -inline void EncodeUInt32(uint8_t* buffer, uint32_t val) -{ - *(uint32_t*)buffer = ByteUtil::SystemToLE ( val ); -} - -inline void EncodeSInt32(uint8_t* buffer, int32_t val) -{ - *(int32_t*)buffer = ByteUtil::SystemToLE ( val ); -} - -inline void EncodeFloat(uint8_t* buffer, float val) -{ - union { - uint32_t U; - float F; - }; - - F = val; - EncodeUInt32(buffer, U); -} - -// Converts an 8-bit binary-coded decimal -inline int8_t DecodeBCD(uint8_t byte) -{ - uint8_t digit1 = (byte >> 4) & 0x0f; - uint8_t digit2 = byte & 0x0f; - int decimal = digit1 * 10 + digit2; // maximum value = 99 - return (int8_t)decimal; -} - - -}} // OVR::Alg - -#endif diff --git a/LibOVR/Src/Kernel/OVR_Allocator.cpp b/LibOVR/Src/Kernel/OVR_Allocator.cpp deleted file mode 100644 index f963d08..0000000 --- a/LibOVR/Src/Kernel/OVR_Allocator.cpp +++ /dev/null @@ -1,141 +0,0 @@ -/************************************************************************************ - -Filename : OVR_Allocator.cpp -Content : Installable memory allocator implementation -Created : September 19, 2012 -Notes : - -Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); -you may not use the Oculus VR Rift SDK except in compliance with the License, -which is provided at the time of installation or download, or which -otherwise accompanies this software in either electronic or hard copy form. - -You may obtain a copy of the License at - -http://www.oculusvr.com/licenses/LICENSE-3.2 - -Unless required by applicable law or agreed to in writing, the Oculus VR SDK -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -************************************************************************************/ - -#include "OVR_Allocator.h" -#ifdef OVR_OS_MAC - #include <stdlib.h> -#else - #include <malloc.h> -#endif - -#if defined(OVR_OS_MS) - #include <Windows.h> -#elif defined(OVR_OS_MAC) || defined(OVR_OS_UNIX) - #include <unistd.h> - #include <sys/mman.h> -#endif - - -namespace OVR { - -//----------------------------------------------------------------------------------- -// ***** Allocator - -Allocator* Allocator::pInstance = 0; - -// Default AlignedAlloc implementation will delegate to Alloc/Free after doing rounding. -void* Allocator::AllocAligned(size_t size, size_t align) -{ - OVR_ASSERT((align & (align-1)) == 0); - align = (align > sizeof(size_t)) ? align : sizeof(size_t); - size_t p = (size_t)Alloc(size+align); - size_t aligned = 0; - if (p) - { - aligned = (size_t(p) + align-1) & ~(align-1); - if (aligned == p) - aligned += align; - *(((size_t*)aligned)-1) = aligned-p; - } - return (void*)aligned; -} - -void Allocator::FreeAligned(void* p) -{ - size_t src = size_t(p) - *(((size_t*)p)-1); - Free((void*)src); -} - - -//------------------------------------------------------------------------ -// ***** Default Allocator - -// This allocator is created and used if no other allocator is installed. -// Default allocator delegates to system malloc. - -void* DefaultAllocator::Alloc(size_t size) -{ - return malloc(size); -} -void* DefaultAllocator::AllocDebug(size_t size, const char* file, unsigned line) -{ - OVR_UNUSED2(file, line); // should be here for debugopt config -#if defined(OVR_CC_MSVC) && defined(_CRTDBG_MAP_ALLOC) - return _malloc_dbg(size, _NORMAL_BLOCK, file, line); -#else - return malloc(size); -#endif -} - -void* DefaultAllocator::Realloc(void* p, size_t newSize) -{ - return realloc(p, newSize); -} -void DefaultAllocator::Free(void *p) -{ - return free(p); -} - - - - -void* MMapAlloc(size_t size) -{ - #if defined(OVR_OS_MS) - return VirtualAlloc(NULL, size, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE); // size is rounded up to a page. // Returned memory is 0-filled. - - #elif defined(OVR_OS_MAC) || defined(OVR_OS_UNIX) - #if !defined(MAP_FAILED) - #define MAP_FAILED ((void*)-1) - #endif - - void* result = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0); // Returned memory is 0-filled. - if(result == MAP_FAILED) // mmap returns MAP_FAILED (-1) upon failure. - result = NULL; - return result; - #endif -} - - - - -void MMapFree(void* memory, size_t size) -{ - #if defined(OVR_OS_MS) - OVR_UNUSED(size); - VirtualFree(memory, 0, MEM_RELEASE); - - #elif defined(OVR_OS_MAC) || defined(OVR_OS_UNIX) - size_t pageSize = getpagesize(); - size = (((size + (pageSize - 1)) / pageSize) * pageSize); - munmap(memory, size); // Must supply the size to munmap. - #endif -} - - - - -} // OVR diff --git a/LibOVR/Src/Kernel/OVR_Allocator.h b/LibOVR/Src/Kernel/OVR_Allocator.h deleted file mode 100644 index dcf097d..0000000 --- a/LibOVR/Src/Kernel/OVR_Allocator.h +++ /dev/null @@ -1,360 +0,0 @@ -/************************************************************************************ - -PublicHeader: OVR_Kernel.h -Filename : OVR_Allocator.h -Content : Installable memory allocator -Created : September 19, 2012 -Notes : - -Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); -you may not use the Oculus VR Rift SDK except in compliance with the License, -which is provided at the time of installation or download, or which -otherwise accompanies this software in either electronic or hard copy form. - -You may obtain a copy of the License at - -http://www.oculusvr.com/licenses/LICENSE-3.2 - -Unless required by applicable law or agreed to in writing, the Oculus VR SDK -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -************************************************************************************/ - -#ifndef OVR_Allocator_h -#define OVR_Allocator_h - -#include "OVR_Types.h" - -//----------------------------------------------------------------------------------- - -// ***** Disable template-unfriendly MS VC++ warnings -#if defined(OVR_CC_MSVC) -// Pragma to prevent long name warnings in in VC++ -#pragma warning(disable : 4503) -#pragma warning(disable : 4786) -// In MSVC 7.1, warning about placement new POD default initializer -#pragma warning(disable : 4345) -#endif - -// Un-define new so that placement constructors work -#undef new - - -//----------------------------------------------------------------------------------- -// ***** Placement new overrides - -// Calls constructor on own memory created with "new(ptr) type" -#ifndef __PLACEMENT_NEW_INLINE -#define __PLACEMENT_NEW_INLINE - -# if defined(OVR_CC_MWERKS) || defined(OVR_CC_BORLAND) || defined(OVR_CC_GNU) -# include <new> -# else - // Useful on MSVC - OVR_FORCE_INLINE void* operator new (size_t n, void *ptr) { OVR_UNUSED(n); return ptr; } - OVR_FORCE_INLINE void operator delete (void *, void *) { } -# endif - -#endif // __PLACEMENT_NEW_INLINE - - - -//------------------------------------------------------------------------ -// ***** Macros to redefine class new/delete operators - -// Types specifically declared to allow disambiguation of address in -// class member operator new. - -#define OVR_MEMORY_REDEFINE_NEW_IMPL(class_name, check_delete) \ - void* operator new(size_t sz) \ - { void *p = OVR_ALLOC_DEBUG(sz, __FILE__, __LINE__); return p; } \ - void* operator new(size_t sz, const char* file, int line) \ - { void* p = OVR_ALLOC_DEBUG(sz, file, line); OVR_UNUSED2(file, line); return p; } \ - void operator delete(void *p) \ - { check_delete(class_name, p); OVR_FREE(p); } \ - void operator delete(void *p, const char*, int) \ - { check_delete(class_name, p); OVR_FREE(p); } - -#define OVR_MEMORY_DEFINE_PLACEMENT_NEW \ - void* operator new (size_t n, void *ptr) { OVR_UNUSED(n); return ptr; } \ - void operator delete (void *ptr, void *ptr2) { OVR_UNUSED2(ptr,ptr2); } - - -#define OVR_MEMORY_CHECK_DELETE_NONE(class_name, p) - -// Redefined all delete/new operators in a class without custom memory initialization -#define OVR_MEMORY_REDEFINE_NEW(class_name) \ - OVR_MEMORY_REDEFINE_NEW_IMPL(class_name, OVR_MEMORY_CHECK_DELETE_NONE) - - -namespace OVR { - -//----------------------------------------------------------------------------------- -// ***** Construct / Destruct - -// Construct/Destruct functions are useful when new is redefined, as they can -// be called instead of placement new constructors. - - -template <class T> -OVR_FORCE_INLINE T* Construct(void *p) -{ - return ::new(p) T(); -} - -template <class T> -OVR_FORCE_INLINE T* Construct(void *p, const T& source) -{ - return ::new(p) T(source); -} - -// Same as above, but allows for a different type of constructor. -template <class T, class S> -OVR_FORCE_INLINE T* ConstructAlt(void *p, const S& source) -{ - return ::new(p) T(source); -} - -template <class T, class S1, class S2> -OVR_FORCE_INLINE T* ConstructAlt(void *p, const S1& src1, const S2& src2) -{ - return ::new(p) T(src1, src2); -} - -template <class T> -OVR_FORCE_INLINE void ConstructArray(void *p, size_t count) -{ - uint8_t *pdata = (uint8_t*)p; - for (size_t i=0; i< count; ++i, pdata += sizeof(T)) - { - Construct<T>(pdata); - } -} - -template <class T> -OVR_FORCE_INLINE void ConstructArray(void *p, size_t count, const T& source) -{ - uint8_t *pdata = (uint8_t*)p; - for (size_t i=0; i< count; ++i, pdata += sizeof(T)) - { - Construct<T>(pdata, source); - } -} - -template <class T> -OVR_FORCE_INLINE void Destruct(T *pobj) -{ - pobj->~T(); - OVR_UNUSED1(pobj); // Fix incorrect 'unused variable' MSVC warning. -} - -template <class T> -OVR_FORCE_INLINE void DestructArray(T *pobj, size_t count) -{ - for (size_t i=0; i<count; ++i, ++pobj) - pobj->~T(); -} - - -//----------------------------------------------------------------------------------- -// ***** Allocator - -// Allocator defines a memory allocation interface that developers can override -// to to provide memory for OVR; an instance of this class is typically created on -// application startup and passed into System or OVR::System constructor. -// -// -// Users implementing this interface must provide three functions: Alloc, Free, -// and Realloc. Implementations of these functions must honor the requested alignment. -// Although arbitrary alignment requests are possible, requested alignment will -// typically be small, such as 16 bytes or less. - -class Allocator -{ - friend class System; -public: - virtual ~Allocator(){} - - // *** Standard Alignment Alloc/Free - - // Allocate memory of specified size with default alignment. - // Alloc of size==0 will allocate a tiny block & return a valid pointer; - // this makes it suitable for new operator. - virtual void* Alloc(size_t size) = 0; - // Same as Alloc, but provides an option of passing debug data. - virtual void* AllocDebug(size_t size, const char* file, unsigned line) - { OVR_UNUSED2(file, line); return Alloc(size); } - - // Reallocate memory block to a new size, copying data if necessary. Returns the pointer to - // new memory block, which may be the same as original pointer. Will return 0 if reallocation - // failed, in which case previous memory is still valid. - // Realloc to decrease size will never fail. - // Realloc of pointer == 0 is equivalent to Alloc - // Realloc to size == 0, shrinks to the minimal size, pointer remains valid and requires Free(). - virtual void* Realloc(void* p, size_t newSize) = 0; - - // Frees memory allocated by Alloc/Realloc. - // Free of null pointer is valid and will do nothing. - virtual void Free(void *p) = 0; - - - // *** Standard Alignment Alloc/Free - - // Allocate memory of specified alignment. - // Memory allocated with AllocAligned MUST be freed with FreeAligned. - // Default implementation will delegate to Alloc/Free after doing rounding. - virtual void* AllocAligned(size_t size, size_t align); - // Frees memory allocated with AllocAligned. - virtual void FreeAligned(void* p); - - // Returns the pointer to the current globally installed Allocator instance. - // This pointer is used for most of the memory allocations. - static Allocator* GetInstance() { return pInstance; } - - -protected: - // onSystemShutdown is called on the allocator during System::Shutdown. - // At this point, all allocations should've been freed. - virtual void onSystemShutdown() { } - -public: - static void setInstance(Allocator* palloc) - { - OVR_ASSERT((pInstance == 0) || (palloc == 0)); - pInstance = palloc; - } - -private: - - static Allocator* pInstance; -}; - - - -//------------------------------------------------------------------------ -// ***** Allocator_SingletonSupport - -// Allocator_SingletonSupport is a Allocator wrapper class that implements -// the InitSystemSingleton static function, used to create a global singleton -// used for the OVR::System default argument initialization. -// -// End users implementing custom Allocator interface don't need to make use of this base -// class; they can just create an instance of their own class on stack and pass it to System. - -template<class D> -class Allocator_SingletonSupport : public Allocator -{ - struct AllocContainer - { - size_t Data[(sizeof(D) + sizeof(size_t)-1) / sizeof(size_t)]; - bool Initialized; - AllocContainer() : Initialized(0) { } - }; - - AllocContainer* pContainer; - -public: - Allocator_SingletonSupport() : pContainer(0) { } - - // Creates a singleton instance of this Allocator class used - // on OVR_DEFAULT_ALLOCATOR during System initialization. - static D* InitSystemSingleton() - { - static AllocContainer Container; - OVR_ASSERT(Container.Initialized == false); - - Allocator_SingletonSupport<D> *presult = Construct<D>((void*)Container.Data); - presult->pContainer = &Container; - Container.Initialized = true; - return (D*)presult; - } - -protected: - virtual void onSystemShutdown() - { - Allocator::onSystemShutdown(); - if (pContainer) - { - pContainer->Initialized = false; - Destruct((D*)this); - pContainer = 0; - } - } -}; - -//------------------------------------------------------------------------ -// ***** Default Allocator - -// This allocator is created and used if no other allocator is installed. -// Default allocator delegates to system malloc. - -class DefaultAllocator : public Allocator_SingletonSupport<DefaultAllocator> -{ -public: - virtual void* Alloc(size_t size); - virtual void* AllocDebug(size_t size, const char* file, unsigned line); - virtual void* Realloc(void* p, size_t newSize); - virtual void Free(void *p); -}; - - -//------------------------------------------------------------------------ -// ***** Memory Allocation Macros - -// These macros should be used for global allocation. In the future, these -// macros will allows allocation to be extended with debug file/line information -// if necessary. - -#define OVR_REALLOC(p,s) OVR::Allocator::GetInstance()->Realloc((p),(s)) -#define OVR_FREE(p) OVR::Allocator::GetInstance()->Free((p)) -#define OVR_ALLOC_ALIGNED(s,a) OVR::Allocator::GetInstance()->AllocAligned((s),(a)) -#define OVR_FREE_ALIGNED(p) OVR::Allocator::GetInstance()->FreeAligned((p)) - -#ifdef OVR_BUILD_DEBUG -#define OVR_ALLOC(s) OVR::Allocator::GetInstance()->AllocDebug((s), __FILE__, __LINE__) -#define OVR_ALLOC_DEBUG(s,f,l) OVR::Allocator::GetInstance()->AllocDebug((s), f, l) -#else -#define OVR_ALLOC(s) OVR::Allocator::GetInstance()->Alloc((s)) -#define OVR_ALLOC_DEBUG(s,f,l) OVR::Allocator::GetInstance()->Alloc((s)) -#endif - -//------------------------------------------------------------------------ - -// Base class that overrides the new and delete operators. -// Deriving from this class, even as a multiple base, incurs no space overhead. -class NewOverrideBase -{ -public: - - // Redefine all new & delete operators. - OVR_MEMORY_REDEFINE_NEW(NewOverrideBase) -}; - - -//------------------------------------------------------------------------ -// ***** Mapped memory allocation -// -// Equates to VirtualAlloc/VirtualFree on Windows, mmap/munmap on Unix. -// These are useful for when you need system-supplied memory pages. -// These are also useful for when you need to allocate memory in a way -// that doesn't affect the application heap. - -void* MMapAlloc(size_t size); -void MMapFree(void* memory, size_t size); - - -} // OVR - - -// Redefine operator 'new' if necessary. -#if defined(OVR_DEFINE_NEW) -#define new OVR_DEFINE_NEW -#endif - - -#endif // OVR_Memory diff --git a/LibOVR/Src/Kernel/OVR_Array.h b/LibOVR/Src/Kernel/OVR_Array.h deleted file mode 100644 index 7855a5b..0000000 --- a/LibOVR/Src/Kernel/OVR_Array.h +++ /dev/null @@ -1,837 +0,0 @@ -/************************************************************************************ - -PublicHeader: OVR_Kernel.h -Filename : OVR_Array.h -Content : Template implementation for Array -Created : September 19, 2012 -Notes : - -Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); -you may not use the Oculus VR Rift SDK except in compliance with the License, -which is provided at the time of installation or download, or which -otherwise accompanies this software in either electronic or hard copy form. - -You may obtain a copy of the License at - -http://www.oculusvr.com/licenses/LICENSE-3.2 - -Unless required by applicable law or agreed to in writing, the Oculus VR SDK -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -************************************************************************************/ - -#ifndef OVR_Array_h -#define OVR_Array_h - -#include "OVR_ContainerAllocator.h" - -namespace OVR { - -//----------------------------------------------------------------------------------- -// ***** ArrayDefaultPolicy -// -// Default resize behavior. No minimal capacity, Granularity=4, -// Shrinking as needed. ArrayConstPolicy actually is the same as -// ArrayDefaultPolicy, but parametrized with constants. -// This struct is used only in order to reduce the template "matroska". -struct ArrayDefaultPolicy -{ - ArrayDefaultPolicy() : Capacity(0) {} - ArrayDefaultPolicy(const ArrayDefaultPolicy&) : Capacity(0) {} - - size_t GetMinCapacity() const { return 0; } - size_t GetGranularity() const { return 4; } - bool NeverShrinking() const { return 0; } - - size_t GetCapacity() const { return Capacity; } - void SetCapacity(size_t capacity) { Capacity = capacity; } -private: - size_t Capacity; -}; - - -//----------------------------------------------------------------------------------- -// ***** ArrayConstPolicy -// -// Statically parametrized resizing behavior: -// MinCapacity, Granularity, and Shrinking flag. -template<int MinCapacity=0, int Granularity=4, bool NeverShrink=false> -struct ArrayConstPolicy -{ - typedef ArrayConstPolicy<MinCapacity, Granularity, NeverShrink> SelfType; - - ArrayConstPolicy() : Capacity(0) {} - ArrayConstPolicy(const SelfType&) : Capacity(0) {} - - size_t GetMinCapacity() const { return MinCapacity; } - size_t GetGranularity() const { return Granularity; } - bool NeverShrinking() const { return NeverShrink; } - - size_t GetCapacity() const { return Capacity; } - void SetCapacity(size_t capacity) { Capacity = capacity; } -private: - size_t Capacity; -}; - -//----------------------------------------------------------------------------------- -// ***** ArrayDataBase -// -// Basic operations with array data: Reserve, Resize, Free, ArrayPolicy. -// For internal use only: ArrayData,ArrayDataCC and others. -template<class T, class Allocator, class SizePolicy> -struct ArrayDataBase -{ - typedef T ValueType; - typedef Allocator AllocatorType; - typedef SizePolicy SizePolicyType; - typedef ArrayDataBase<T, Allocator, SizePolicy> SelfType; - - ArrayDataBase() - : Data(0), Size(0), Policy() {} - - ArrayDataBase(const SizePolicy& p) - : Data(0), Size(0), Policy(p) {} - - ~ArrayDataBase() - { - Allocator::DestructArray(Data, Size); - Allocator::Free(Data); - } - - size_t GetCapacity() const - { - return Policy.GetCapacity(); - } - - void ClearAndRelease() - { - Allocator::DestructArray(Data, Size); - Allocator::Free(Data); - Data = 0; - Size = 0; - Policy.SetCapacity(0); - } - - void Reserve(size_t newCapacity) - { - if (Policy.NeverShrinking() && newCapacity < GetCapacity()) - return; - - if (newCapacity < Policy.GetMinCapacity()) - newCapacity = Policy.GetMinCapacity(); - - // Resize the buffer. - if (newCapacity == 0) - { - if (Data) - { - Allocator::Free(Data); - Data = 0; - } - Policy.SetCapacity(0); - } - else - { - size_t gran = Policy.GetGranularity(); - newCapacity = (newCapacity + gran - 1) / gran * gran; - if (Data) - { - if (Allocator::IsMovable()) - { - Data = (T*)Allocator::Realloc(Data, sizeof(T) * newCapacity); - } - else - { - T* newData = (T*)Allocator::Alloc(sizeof(T) * newCapacity); - size_t i, s; - s = (Size < newCapacity) ? Size : newCapacity; - for (i = 0; i < s; ++i) - { - Allocator::Construct(&newData[i], Data[i]); - Allocator::Destruct(&Data[i]); - } - for (i = s; i < Size; ++i) - { - Allocator::Destruct(&Data[i]); - } - Allocator::Free(Data); - Data = newData; - } - } - else - { - Data = (T*)Allocator::Alloc(sizeof(T) * newCapacity); - //memset(Buffer, 0, (sizeof(ValueType) * newSize)); // Do we need this? - } - Policy.SetCapacity(newCapacity); - // OVR_ASSERT(Data); // need to throw (or something) on alloc failure! - } - } - - // This version of Resize DOES NOT construct the elements. - // It's done to optimize PushBack, which uses a copy constructor - // instead of the default constructor and assignment - void ResizeNoConstruct(size_t newSize) - { - size_t oldSize = Size; - - if (newSize < oldSize) - { - Allocator::DestructArray(Data + newSize, oldSize - newSize); - if (newSize < (Policy.GetCapacity() >> 1)) - { - Reserve(newSize); - } - } - else if(newSize >= Policy.GetCapacity()) - { - Reserve(newSize + (newSize >> 2)); - } - //! IMPORTANT to modify Size only after Reserve completes, because garbage collectable - // array may use this array and may traverse it during Reserve (in the case, if - // collection occurs because of heap limit exceeded). - Size = newSize; - } - - ValueType* Data; - size_t Size; - SizePolicy Policy; -}; - - - -//----------------------------------------------------------------------------------- -// ***** ArrayData -// -// General purpose array data. -// For internal use only in Array, ArrayLH, ArrayPOD and so on. -template<class T, class Allocator, class SizePolicy> -struct ArrayData : ArrayDataBase<T, Allocator, SizePolicy> -{ - typedef T ValueType; - typedef Allocator AllocatorType; - typedef SizePolicy SizePolicyType; - typedef ArrayDataBase<T, Allocator, SizePolicy> BaseType; - typedef ArrayData <T, Allocator, SizePolicy> SelfType; - - ArrayData() - : BaseType() { } - - ArrayData(size_t size) - : BaseType() { Resize(size); } - - ArrayData(const SelfType& a) - : BaseType(a.Policy) { Append(a.Data, a.Size); } - - - void Resize(size_t newSize) - { - size_t oldSize = this->Size; - BaseType::ResizeNoConstruct(newSize); - if(newSize > oldSize) - Allocator::ConstructArray(this->Data + oldSize, newSize - oldSize); - } - - void PushBack(const ValueType& val) - { - BaseType::ResizeNoConstruct(this->Size + 1); - OVR_ASSERT(this->Data != NULL); - Allocator::Construct(this->Data + this->Size - 1, val); - } - - template<class S> - void PushBackAlt(const S& val) - { - BaseType::ResizeNoConstruct(this->Size + 1); - Allocator::ConstructAlt(this->Data + this->Size - 1, val); - } - - // Append the given data to the array. - void Append(const ValueType other[], size_t count) - { - if (count) - { - size_t oldSize = this->Size; - BaseType::ResizeNoConstruct(this->Size + count); - Allocator::ConstructArray(this->Data + oldSize, count, other); - } - } -}; - - - -//----------------------------------------------------------------------------------- -// ***** ArrayDataCC -// -// A modification of ArrayData that always copy-constructs new elements -// using a specified DefaultValue. For internal use only in ArrayCC. -template<class T, class Allocator, class SizePolicy> -struct ArrayDataCC : ArrayDataBase<T, Allocator, SizePolicy> -{ - typedef T ValueType; - typedef Allocator AllocatorType; - typedef SizePolicy SizePolicyType; - typedef ArrayDataBase<T, Allocator, SizePolicy> BaseType; - typedef ArrayDataCC <T, Allocator, SizePolicy> SelfType; - - ArrayDataCC(const ValueType& defval) - : BaseType(), DefaultValue(defval) { } - - ArrayDataCC(const ValueType& defval, size_t size) - : BaseType(), DefaultValue(defval) { Resize(size); } - - ArrayDataCC(const SelfType& a) - : BaseType(a.Policy), DefaultValue(a.DefaultValue) { Append(a.Data, a.Size); } - - - void Resize(size_t newSize) - { - size_t oldSize = this->Size; - BaseType::ResizeNoConstruct(newSize); - if(newSize > oldSize) - Allocator::ConstructArray(this->Data + oldSize, newSize - oldSize, DefaultValue); - } - - void PushBack(const ValueType& val) - { - BaseType::ResizeNoConstruct(this->Size + 1); - Allocator::Construct(this->Data + this->Size - 1, val); - } - - template<class S> - void PushBackAlt(const S& val) - { - BaseType::ResizeNoConstruct(this->Size + 1); - Allocator::ConstructAlt(this->Data + this->Size - 1, val); - } - - // Append the given data to the array. - void Append(const ValueType other[], size_t count) - { - if (count) - { - size_t oldSize = this->Size; - BaseType::ResizeNoConstruct(this->Size + count); - Allocator::ConstructArray(this->Data + oldSize, count, other); - } - } - - ValueType DefaultValue; -}; - - - - - -//----------------------------------------------------------------------------------- -// ***** ArrayBase -// -// Resizable array. The behavior can be POD (suffix _POD) and -// Movable (no suffix) depending on the allocator policy. -// In case of _POD the constructors and destructors are not called. -// -// Arrays can't handle non-movable objects! Don't put anything in here -// that can't be moved around by bitwise copy. -// -// The addresses of elements are not persistent! Don't keep the address -// of an element; the array contents will move around as it gets resized. -template<class ArrayData> -class ArrayBase -{ -public: - typedef typename ArrayData::ValueType ValueType; - typedef typename ArrayData::AllocatorType AllocatorType; - typedef typename ArrayData::SizePolicyType SizePolicyType; - typedef ArrayBase<ArrayData> SelfType; - - -#undef new - OVR_MEMORY_REDEFINE_NEW(ArrayBase) -// Redefine operator 'new' if necessary. -#if defined(OVR_DEFINE_NEW) -#define new OVR_DEFINE_NEW -#endif - - - ArrayBase() - : Data() {} - ArrayBase(size_t size) - : Data(size) {} - ArrayBase(const SelfType& a) - : Data(a.Data) {} - - ArrayBase(const ValueType& defval) - : Data(defval) {} - ArrayBase(const ValueType& defval, size_t size) - : Data(defval, size) {} - - SizePolicyType* GetSizePolicy() const { return Data.Policy; } - void SetSizePolicy(const SizePolicyType& p) { Data.Policy = p; } - - bool NeverShrinking()const { return Data.Policy.NeverShrinking(); } - size_t GetSize() const { return Data.Size; } - int GetSizeI() const { return (int)Data.Size; } - bool IsEmpty() const { return Data.Size == 0; } - size_t GetCapacity() const { return Data.GetCapacity(); } - size_t GetNumBytes() const { return Data.GetCapacity() * sizeof(ValueType); } - - void ClearAndRelease() { Data.ClearAndRelease(); } - void Clear() { Data.Resize(0); } - void Resize(size_t newSize) { Data.Resize(newSize); } - - // Reserve can only increase the capacity - void Reserve(size_t newCapacity) - { - if (newCapacity > Data.GetCapacity()) - Data.Reserve(newCapacity); - } - - // Basic access. - ValueType& At(size_t index) - { - OVR_ASSERT((Data.Data) && (index < Data.Size)); // Asserting that Data.Data is valid helps static analysis tools. - return Data.Data[index]; - } - const ValueType& At(size_t index) const - { - OVR_ASSERT((Data.Data) && (index < Data.Size)); - return Data.Data[index]; - } - - ValueType ValueAt(size_t index) const - { - OVR_ASSERT((Data.Data) && (index < Data.Size)); - return Data.Data[index]; - } - - // Basic access. - ValueType& operator [] (size_t index) - { - OVR_ASSERT((Data.Data) && (index < Data.Size)); - return Data.Data[index]; - } - const ValueType& operator [] (size_t index) const - { - OVR_ASSERT((Data.Data) && (index < Data.Size)); - return Data.Data[index]; - } - - // Raw pointer to the data. Use with caution! - const ValueType* GetDataPtr() const { return Data.Data; } - ValueType* GetDataPtr() { return Data.Data; } - - // Insert the given element at the end of the array. - void PushBack(const ValueType& val) - { - // DO NOT pass elements of your own vector into - // push_back()! Since we're using references, - // resize() may munge the element storage! - // OVR_ASSERT(&val < &Buffer[0] || &val > &Buffer[BufferSize]); - Data.PushBack(val); - } - - template<class S> - void PushBackAlt(const S& val) - { - Data.PushBackAlt(val); - } - - // Remove the last element. - void PopBack(size_t count = 1) - { - OVR_ASSERT(Data.Size >= count); - Data.Resize(Data.Size - count); - } - - ValueType& PushDefault() - { - Data.PushBack(ValueType()); - return Back(); - } - - ValueType Pop() - { - OVR_ASSERT((Data.Data) && (Data.Size > 0)); - ValueType t = Back(); - PopBack(); - return t; - } - - - // Access the first element. - ValueType& Front() { return At(0); } - const ValueType& Front() const { return At(0); } - - // Access the last element. - ValueType& Back() { return At(Data.Size - 1); } - const ValueType& Back() const { return At(Data.Size - 1); } - - // Array copy. Copies the contents of a into this array. - const SelfType& operator = (const SelfType& a) - { - Resize(a.GetSize()); - OVR_ASSERT((Data.Data != NULL) || (Data.Size == 0)); - for (size_t i = 0; i < Data.Size; i++) { - *(Data.Data + i) = a[i]; - } - return *this; - } - - // Removing multiple elements from the array. - void RemoveMultipleAt(size_t index, size_t num) - { - OVR_ASSERT(index + num <= Data.Size); - if (Data.Size == num) - { - Clear(); - } - else - { - AllocatorType::DestructArray(Data.Data + index, num); - AllocatorType::CopyArrayForward( - Data.Data + index, - Data.Data + index + num, - Data.Size - num - index); - Data.Size -= num; - } - } - - // Removing an element from the array is an expensive operation! - // It compacts only after removing the last element. - // If order of elements in the array is not important then use - // RemoveAtUnordered, that could be much faster than the regular - // RemoveAt. - void RemoveAt(size_t index) - { - OVR_ASSERT((Data.Data) && (index < Data.Size)); - if (Data.Size == 1) - { - Clear(); - } - else - { - AllocatorType::Destruct(Data.Data + index); - AllocatorType::CopyArrayForward( - Data.Data + index, - Data.Data + index + 1, - Data.Size - 1 - index); - --Data.Size; - } - } - - // Removes an element from the array without respecting of original order of - // elements for better performance. Do not use on array where order of elements - // is important, otherwise use it instead of regular RemoveAt(). - void RemoveAtUnordered(size_t index) - { - OVR_ASSERT((Data.Data) && (index < Data.Size)); - if (Data.Size == 1) - { - Clear(); - } - else - { - // copy the last element into the 'index' position - // and decrement the size (instead of moving all elements - // in [index + 1 .. size - 1] range). - const size_t lastElemIndex = Data.Size - 1; - if (index < lastElemIndex) - { - AllocatorType::Destruct(Data.Data + index); - AllocatorType::Construct(Data.Data + index, Data.Data[lastElemIndex]); - } - AllocatorType::Destruct(Data.Data + lastElemIndex); - --Data.Size; - } - } - - // Insert the given object at the given index shifting all the elements up. - void InsertAt(size_t index, const ValueType& val = ValueType()) - { - OVR_ASSERT(index <= Data.Size); - - Data.Resize(Data.Size + 1); - if (index < Data.Size - 1) - { - AllocatorType::CopyArrayBackward( - Data.Data + index + 1, - Data.Data + index, - Data.Size - 1 - index); - } - AllocatorType::Construct(Data.Data + index, val); - } - - // Insert the given object at the given index shifting all the elements up. - void InsertMultipleAt(size_t index, size_t num, const ValueType& val = ValueType()) - { - OVR_ASSERT(index <= Data.Size); - - Data.Resize(Data.Size + num); - if (index < Data.Size - num) - { - AllocatorType::CopyArrayBackward( - Data.Data + index + num, - Data.Data + index, - Data.Size - num - index); - } - for (size_t i = 0; i < num; ++i) - AllocatorType::Construct(Data.Data + index + i, val); - } - - // Append the given data to the array. - void Append(const SelfType& other) - { - Append(other.Data.Data, other.GetSize()); - } - - // Append the given data to the array. - void Append(const ValueType other[], size_t count) - { - Data.Append(other, count); - } - - class Iterator - { - SelfType* pArray; - intptr_t CurIndex; - - public: - Iterator() : pArray(0), CurIndex(-1) {} - Iterator(SelfType* parr, intptr_t idx = 0) : pArray(parr), CurIndex(idx) {} - - bool operator==(const Iterator& it) const { return pArray == it.pArray && CurIndex == it.CurIndex; } - bool operator!=(const Iterator& it) const { return pArray != it.pArray || CurIndex != it.CurIndex; } - - Iterator& operator++() - { - if (pArray) - { - if (CurIndex < (intptr_t)pArray->GetSize()) - ++CurIndex; - } - return *this; - } - Iterator operator++(int) - { - Iterator it(*this); - operator++(); - return it; - } - Iterator& operator--() - { - if (pArray) - { - if (CurIndex >= 0) - --CurIndex; - } - return *this; - } - Iterator operator--(int) - { - Iterator it(*this); - operator--(); - return it; - } - Iterator operator+(int delta) const - { - return Iterator(pArray, CurIndex + delta); - } - Iterator operator-(int delta) const - { - return Iterator(pArray, CurIndex - delta); - } - intptr_t operator-(const Iterator& right) const - { - OVR_ASSERT(pArray == right.pArray); - return CurIndex - right.CurIndex; - } - ValueType& operator*() const { OVR_ASSERT(pArray); return (*pArray)[CurIndex]; } - ValueType* operator->() const { OVR_ASSERT(pArray); return &(*pArray)[CurIndex]; } - ValueType* GetPtr() const { OVR_ASSERT(pArray); return &(*pArray)[CurIndex]; } - - bool IsFinished() const { return !pArray || CurIndex < 0 || CurIndex >= (int)pArray->GetSize(); } - - void Remove() - { - if (!IsFinished()) - pArray->RemoveAt(CurIndex); - } - - intptr_t GetIndex() const { return CurIndex; } - }; - - Iterator Begin() { return Iterator(this); } - Iterator End() { return Iterator(this, (intptr_t)GetSize()); } - Iterator Last() { return Iterator(this, (intptr_t)GetSize() - 1); } - - class ConstIterator - { - const SelfType* pArray; - intptr_t CurIndex; - - public: - ConstIterator() : pArray(0), CurIndex(-1) {} - ConstIterator(const SelfType* parr, intptr_t idx = 0) : pArray(parr), CurIndex(idx) {} - - bool operator==(const ConstIterator& it) const { return pArray == it.pArray && CurIndex == it.CurIndex; } - bool operator!=(const ConstIterator& it) const { return pArray != it.pArray || CurIndex != it.CurIndex; } - - ConstIterator& operator++() - { - if (pArray) - { - if (CurIndex < (int)pArray->GetSize()) - ++CurIndex; - } - return *this; - } - ConstIterator operator++(int) - { - ConstIterator it(*this); - operator++(); - return it; - } - ConstIterator& operator--() - { - if (pArray) - { - if (CurIndex >= 0) - --CurIndex; - } - return *this; - } - ConstIterator operator--(int) - { - ConstIterator it(*this); - operator--(); - return it; - } - ConstIterator operator+(int delta) const - { - return ConstIterator(pArray, CurIndex + delta); - } - ConstIterator operator-(int delta) const - { - return ConstIterator(pArray, CurIndex - delta); - } - intptr_t operator-(const ConstIterator& right) const - { - OVR_ASSERT(pArray == right.pArray); - return CurIndex - right.CurIndex; - } - const ValueType& operator*() const { OVR_ASSERT(pArray); return (*pArray)[CurIndex]; } - const ValueType* operator->() const { OVR_ASSERT(pArray); return &(*pArray)[CurIndex]; } - const ValueType* GetPtr() const { OVR_ASSERT(pArray); return &(*pArray)[CurIndex]; } - - bool IsFinished() const { return !pArray || CurIndex < 0 || CurIndex >= (int)pArray->GetSize(); } - - intptr_t GetIndex() const { return CurIndex; } - }; - ConstIterator Begin() const { return ConstIterator(this); } - ConstIterator End() const { return ConstIterator(this, (intptr_t)GetSize()); } - ConstIterator Last() const { return ConstIterator(this, (intptr_t)GetSize() - 1); } - -protected: - ArrayData Data; -}; - - - -//----------------------------------------------------------------------------------- -// ***** Array -// -// General purpose array for movable objects that require explicit -// construction/destruction. -template<class T, class SizePolicy=ArrayDefaultPolicy> -class Array : public ArrayBase<ArrayData<T, ContainerAllocator<T>, SizePolicy> > -{ -public: - typedef T ValueType; - typedef ContainerAllocator<T> AllocatorType; - typedef SizePolicy SizePolicyType; - typedef Array<T, SizePolicy> SelfType; - typedef ArrayBase<ArrayData<T, ContainerAllocator<T>, SizePolicy> > BaseType; - - Array() : BaseType() {} - Array(size_t size) : BaseType(size) {} - Array(const SizePolicyType& p) : BaseType() { SetSizePolicy(p); } - Array(const SelfType& a) : BaseType(a) {} - const SelfType& operator=(const SelfType& a) { BaseType::operator=(a); return *this; } -}; - -// ***** ArrayPOD -// -// General purpose array for movable objects that DOES NOT require -// construction/destruction. Constructors and destructors are not called! -// Global heap is in use. -template<class T, class SizePolicy=ArrayDefaultPolicy> -class ArrayPOD : public ArrayBase<ArrayData<T, ContainerAllocator_POD<T>, SizePolicy> > -{ -public: - typedef T ValueType; - typedef ContainerAllocator_POD<T> AllocatorType; - typedef SizePolicy SizePolicyType; - typedef ArrayPOD<T, SizePolicy> SelfType; - typedef ArrayBase<ArrayData<T, ContainerAllocator_POD<T>, SizePolicy> > BaseType; - - ArrayPOD() : BaseType() {} - ArrayPOD(size_t size) : BaseType(size) {} - ArrayPOD(const SizePolicyType& p) : BaseType() { SetSizePolicy(p); } - ArrayPOD(const SelfType& a) : BaseType(a) {} - const SelfType& operator=(const SelfType& a) { BaseType::operator=(a); return *this; } -}; - - -// ***** ArrayCPP -// -// General purpose, fully C++ compliant array. Can be used with non-movable data. -// Global heap is in use. -template<class T, class SizePolicy=ArrayDefaultPolicy> -class ArrayCPP : public ArrayBase<ArrayData<T, ContainerAllocator_CPP<T>, SizePolicy> > -{ -public: - typedef T ValueType; - typedef ContainerAllocator_CPP<T> AllocatorType; - typedef SizePolicy SizePolicyType; - typedef ArrayCPP<T, SizePolicy> SelfType; - typedef ArrayBase<ArrayData<T, ContainerAllocator_CPP<T>, SizePolicy> > BaseType; - - ArrayCPP() : BaseType() {} - ArrayCPP(size_t size) : BaseType(size) {} - ArrayCPP(const SizePolicyType& p) : BaseType() { SetSizePolicy(p); } - ArrayCPP(const SelfType& a) : BaseType(a) {} - const SelfType& operator=(const SelfType& a) { BaseType::operator=(a); return *this; } -}; - - -// ***** ArrayCC -// -// A modification of the array that uses the given default value to -// construct the elements. The constructors and destructors are -// properly called, the objects must be movable. - -template<class T, class SizePolicy=ArrayDefaultPolicy> -class ArrayCC : public ArrayBase<ArrayDataCC<T, ContainerAllocator<T>, SizePolicy> > -{ -public: - typedef T ValueType; - typedef ContainerAllocator<T> AllocatorType; - typedef SizePolicy SizePolicyType; - typedef ArrayCC<T, SizePolicy> SelfType; - typedef ArrayBase<ArrayDataCC<T, ContainerAllocator<T>, SizePolicy> > BaseType; - - ArrayCC(const ValueType& defval) : BaseType(defval) {} - ArrayCC(const ValueType& defval, size_t size) : BaseType(defval, size) {} - ArrayCC(const ValueType& defval, const SizePolicyType& p) : BaseType(defval) { SetSizePolicy(p); } - ArrayCC(const SelfType& a) : BaseType(a) {} - const SelfType& operator=(const SelfType& a) { BaseType::operator=(a); return *this; } -}; - -} // OVR - -#endif diff --git a/LibOVR/Src/Kernel/OVR_Atomic.cpp b/LibOVR/Src/Kernel/OVR_Atomic.cpp deleted file mode 100644 index f7cf9a6..0000000 --- a/LibOVR/Src/Kernel/OVR_Atomic.cpp +++ /dev/null @@ -1,139 +0,0 @@ -/************************************************************************************ - -Filename : OVR_Atomic.cpp -Content : Contains atomic operations and inline fastest locking - functionality. Will contain #ifdefs for OS efficiency. - Have non-thread-safe implementation if not available. -Created : September 19, 2012 -Notes : - -Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); -you may not use the Oculus VR Rift SDK except in compliance with the License, -which is provided at the time of installation or download, or which -otherwise accompanies this software in either electronic or hard copy form. - -You may obtain a copy of the License at - -http://www.oculusvr.com/licenses/LICENSE-3.2 - -Unless required by applicable law or agreed to in writing, the Oculus VR SDK -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -************************************************************************************/ - -#include "OVR_Atomic.h" -#include "OVR_Allocator.h" - -#ifdef OVR_ENABLE_THREADS - -// Include Windows 8-Metro compatible Synchronization API -#if defined(OVR_OS_MS) && defined(NTDDI_WIN8) && (NTDDI_VERSION >= NTDDI_WIN8) -#include <synchapi.h> -#endif - - -namespace OVR { - -// ***** Windows Lock implementation - -#if defined(OVR_OS_MS) - -// ***** Standard Win32 Lock implementation - -// Constructors -Lock::Lock(unsigned spinCount) -{ - #if defined(NTDDI_WIN8) && (NTDDI_VERSION >= NTDDI_WIN8) - // On Windows 8 we use InitializeCriticalSectionEx due to Metro-Compatibility - InitializeCriticalSectionEx(&cs, (DWORD)spinCount, - OVR_DEBUG_SELECT(NULL, CRITICAL_SECTION_NO_DEBUG_INFO)); - #else - ::InitializeCriticalSectionAndSpinCount(&cs, (DWORD)spinCount); // This is available with WindowsXP+. - #endif -} - - -Lock::~Lock() -{ - DeleteCriticalSection(&cs); -} - - -#endif - - -//------------------------------------------------------------------------------------- -// ***** SharedLock - -// This is a general purpose globally shared Lock implementation that should probably be -// moved to Kernel. -// May in theory busy spin-wait if we hit contention on first lock creation, -// but this shouldn't matter in practice since Lock* should be cached. - - -enum { LockInitMarker = 0xFFFFFFFF }; - -Lock* SharedLock::GetLockAddRef() -{ - int oldUseCount; - - do { - oldUseCount = UseCount; - if (oldUseCount == (int)LockInitMarker) - continue; - - if (oldUseCount == 0) - { - // Initialize marker - if (AtomicOps<int>::CompareAndSet_Sync(&UseCount, 0, LockInitMarker)) - { - Construct<Lock>(Buffer); - do { } - while (!AtomicOps<int>::CompareAndSet_Sync(&UseCount, LockInitMarker, 1)); - return toLock(); - } - continue; - } - - } while (!AtomicOps<int>::CompareAndSet_NoSync(&UseCount, oldUseCount, oldUseCount + 1)); - - return toLock(); -} - -void SharedLock::ReleaseLock(Lock* plock) -{ - OVR_UNUSED(plock); - OVR_ASSERT(plock == toLock()); - - int oldUseCount; - - do { - oldUseCount = UseCount; - OVR_ASSERT(oldUseCount != (int)LockInitMarker); - - if (oldUseCount == 1) - { - // Initialize marker - if (AtomicOps<int>::CompareAndSet_Sync(&UseCount, 1, LockInitMarker)) - { - Destruct<Lock>(toLock()); - - do { } - while (!AtomicOps<int>::CompareAndSet_Sync(&UseCount, LockInitMarker, 0)); - - return; - } - continue; - } - - } while (!AtomicOps<int>::CompareAndSet_NoSync(&UseCount, oldUseCount, oldUseCount - 1)); -} - -} // OVR - -#endif // OVR_ENABLE_THREADS diff --git a/LibOVR/Src/Kernel/OVR_Atomic.h b/LibOVR/Src/Kernel/OVR_Atomic.h deleted file mode 100644 index 478077b..0000000 --- a/LibOVR/Src/Kernel/OVR_Atomic.h +++ /dev/null @@ -1,915 +0,0 @@ -/************************************************************************************ - -PublicHeader: OVR_Kernel.h -Filename : OVR_Atomic.h -Content : Contains atomic operations and inline fastest locking - functionality. Will contain #ifdefs for OS efficiency. - Have non-thread-safe implementaion if not available. -Created : September 19, 2012 -Notes : - -Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); -you may not use the Oculus VR Rift SDK except in compliance with the License, -which is provided at the time of installation or download, or which -otherwise accompanies this software in either electronic or hard copy form. - -You may obtain a copy of the License at - -http://www.oculusvr.com/licenses/LICENSE-3.2 - -Unless required by applicable law or agreed to in writing, the Oculus VR SDK -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -************************************************************************************/ - -#ifndef OVR_Atomic_h -#define OVR_Atomic_h - -#include "OVR_Types.h" - -// Include System thread functionality. -#if defined(OVR_OS_MS) && !defined(OVR_OS_MS_MOBILE) -#ifndef WIN32_LEAN_AND_MEAN -#define WIN32_LEAN_AND_MEAN -#endif -#include <Windows.h> -#else -#include <pthread.h> -#endif - -#ifdef OVR_CC_MSVC -#include <intrin.h> -#pragma intrinsic(_ReadBarrier, _WriteBarrier, _ReadWriteBarrier) -#endif - -namespace OVR { - - -// ****** Declared classes - -// If there is NO thread support we implement AtomicOps and -// Lock objects as no-ops. The other classes are not defined. -template<class C> class AtomicOps; -template<class T> class AtomicInt; -template<class T> class AtomicPtr; - -class Lock; - - -//----------------------------------------------------------------------------------- -// ***** AtomicOps - -// Atomic operations are provided by the AtomicOps templates class, -// implemented through system-specific AtomicOpsRaw specializations. -// It provides several fundamental operations such as Exchange, ExchangeAdd -// CompareAndSet, and Store_Release. Each function includes several memory -// synchronization versions, important for multiprocessing CPUs with weak -// memory consistency. The following memory fencing strategies are supported: -// -// - NoSync. No memory synchronization is done for atomic op. -// - Release. All other memory writes are completed before atomic op -// writes its results. -// - Acquire. Further memory reads are forced to wait until atomic op -// executes, guaranteeing that the right values will be seen. -// - Sync. A combination of Release and Acquire. - - -// *** AtomicOpsRaw - -// AtomicOpsRaw is a specialized template that provides atomic operations -// used by AtomicOps. This class has two fundamental qualities: (1) it -// defines a type T of correct size, and (2) provides operations that work -// atomically, such as Exchange_Sync and CompareAndSet_Release. - -// AtomicOpsRawBase class contains shared constants/classes for AtomicOpsRaw. -// The primary thing is does is define sync class objects, whose destructor and -// constructor provide places to insert appropriate synchronization calls, on -// systems where such calls are necessary. So far, the breakdown is as follows: -// -// - X86 systems don't need custom syncs, since their exchange/atomic -// instructions are implicitly synchronized. -// - PowerPC requires lwsync/isync instructions that can use this mechanism. -// - If some other systems require a mechanism where syncing type is associated -// with a particular instruction, the default implementation (which implements -// all Sync, Acquire, and Release modes in terms of NoSync and fence) may not -// work. Ii that case it will need to be #ifdef-ed conditionally. - -struct AtomicOpsRawBase -{ -#if !defined(OVR_ENABLE_THREADS) || defined(OVR_CPU_X86) || defined(OVR_CPU_X86_64) - // Need to have empty constructor to avoid class 'unused' variable warning. - struct FullSync { inline FullSync() { } }; - struct AcquireSync { inline AcquireSync() { } }; - struct ReleaseSync { inline ReleaseSync() { } }; - -#elif defined(OVR_CPU_PPC64) || defined(OVR_CPU_PPC) - struct FullSync { inline FullSync() { asm volatile("sync\n"); } ~FullSync() { asm volatile("isync\n"); } }; - struct AcquireSync { inline AcquireSync() { } ~AcquireSync() { asm volatile("isync\n"); } }; - struct ReleaseSync { inline ReleaseSync() { asm volatile("sync\n"); } }; - -#elif defined(OVR_CPU_MIPS) - struct FullSync { inline FullSync() { asm volatile("sync\n"); } ~FullSync() { asm volatile("sync\n"); } }; - struct AcquireSync { inline AcquireSync() { } ~AcquireSync() { asm volatile("sync\n"); } }; - struct ReleaseSync { inline ReleaseSync() { asm volatile("sync\n"); } }; - -#elif defined(OVR_CPU_ARM) // Includes Android and iOS. - struct FullSync { inline FullSync() { asm volatile("dmb\n"); } ~FullSync() { asm volatile("dmb\n"); } }; - struct AcquireSync { inline AcquireSync() { } ~AcquireSync() { asm volatile("dmb\n"); } }; - struct ReleaseSync { inline ReleaseSync() { asm volatile("dmb\n"); } }; - -#elif defined(OVR_CC_GNU) && (__GNUC__ >= 4) - // __sync functions are already full sync - struct FullSync { inline FullSync() { } }; - struct AcquireSync { inline AcquireSync() { } }; - struct ReleaseSync { inline ReleaseSync() { } }; -#endif -}; - - -// 4-Byte raw data atomic op implementation class. -struct AtomicOpsRaw_4ByteImpl : public AtomicOpsRawBase -{ -#if !defined(OVR_ENABLE_THREADS) - - // Provide a type for no-thread-support cases. Used by AtomicOpsRaw_DefImpl. - typedef uint32_t T; - - // *** Thread - Safe Atomic Versions. - -#elif defined(OVR_OS_MS) - - // Use special defined for VC6, where volatile is not used and - // InterlockedCompareExchange is declared incorrectly. - typedef LONG T; -#if defined(OVR_CC_MSVC) && (OVR_CC_MSVC < 1300) - typedef T* InterlockTPtr; - typedef LPVOID ET; - typedef ET* InterlockETPtr; -#else - typedef volatile T* InterlockTPtr; - typedef T ET; - typedef InterlockTPtr InterlockETPtr; -#endif - inline static T Exchange_NoSync(volatile T* p, T val) { return InterlockedExchange((InterlockTPtr)p, val); } - inline static T ExchangeAdd_NoSync(volatile T* p, T val) { return InterlockedExchangeAdd((InterlockTPtr)p, val); } - inline static bool CompareAndSet_NoSync(volatile T* p, T c, T val) { return InterlockedCompareExchange((InterlockETPtr)p, (ET)val, (ET)c) == (ET)c; } - -#elif defined(OVR_CPU_PPC64) || defined(OVR_CPU_PPC) - typedef uint32_t T; - static inline uint32_t Exchange_NoSync(volatile uint32_t *i, uint32_t j) - { - uint32_t ret; - - asm volatile("1:\n\t" - "lwarx %[r],0,%[i]\n\t" - "stwcx. %[j],0,%[i]\n\t" - "bne- 1b\n" - : "+m" (*i), [r] "=&b" (ret) : [i] "b" (i), [j] "b" (j) : "cc", "memory"); - - return ret; - } - - static inline uint32_t ExchangeAdd_NoSync(volatile uint32_t *i, uint32_t j) - { - uint32_t dummy, ret; - - asm volatile("1:\n\t" - "lwarx %[r],0,%[i]\n\t" - "add %[o],%[r],%[j]\n\t" - "stwcx. %[o],0,%[i]\n\t" - "bne- 1b\n" - : "+m" (*i), [r] "=&b" (ret), [o] "=&r" (dummy) : [i] "b" (i), [j] "b" (j) : "cc", "memory"); - - return ret; - } - - static inline bool CompareAndSet_NoSync(volatile uint32_t *i, uint32_t c, uint32_t value) - { - uint32_t ret; - - asm volatile("1:\n\t" - "lwarx %[r],0,%[i]\n\t" - "cmpw 0,%[r],%[cmp]\n\t" - "mfcr %[r]\n\t" - "bne- 2f\n\t" - "stwcx. %[val],0,%[i]\n\t" - "bne- 1b\n\t" - "2:\n" - : "+m" (*i), [r] "=&b" (ret) : [i] "b" (i), [cmp] "b" (c), [val] "b" (value) : "cc", "memory"); - - return (ret & 0x20000000) ? 1 : 0; - } - -#elif defined(OVR_CPU_MIPS) - typedef uint32_t T; - - static inline uint32_t Exchange_NoSync(volatile uint32_t *i, uint32_t j) - { - uint32_t ret; - - asm volatile("1:\n\t" - "ll %[r],0(%[i])\n\t" - "sc %[j],0(%[i])\n\t" - "beq %[j],$0,1b\n\t" - "nop \n" - : "+m" (*i), [r] "=&d" (ret) : [i] "d" (i), [j] "d" (j) : "cc", "memory"); - - return ret; - } - - static inline uint32_t ExchangeAdd_NoSync(volatile uint32_t *i, uint32_t j) - { - uint32_t ret; - - asm volatile("1:\n\t" - "ll %[r],0(%[i])\n\t" - "addu %[j],%[r],%[j]\n\t" - "sc %[j],0(%[i])\n\t" - "beq %[j],$0,1b\n\t" - "nop \n" - : "+m" (*i), [r] "=&d" (ret) : [i] "d" (i), [j] "d" (j) : "cc", "memory"); - - return ret; - } - - static inline bool CompareAndSet_NoSync(volatile uint32_t *i, uint32_t c, uint32_t value) - { - uint32_t ret, dummy; - - asm volatile("1:\n\t" - "move %[r],$0\n\t" - "ll %[o],0(%[i])\n\t" - "bne %[o],%[c],2f\n\t" - "move %[r],%[v]\n\t" - "sc %[r],0(%[i])\n\t" - "beq %[r],$0,1b\n\t" - "nop \n\t" - "2:\n" - : "+m" (*i),[r] "=&d" (ret), [o] "=&d" (dummy) : [i] "d" (i), [c] "d" (c), [v] "d" (value) - : "cc", "memory"); - - return ret; - } - -#elif defined(OVR_CPU_ARM) && defined(OVR_CC_ARM) - typedef uint32_t T; - - static inline uint32_t Exchange_NoSync(volatile uint32_t *i, uint32_t j) - { - for(;;) - { - T r = __ldrex(i); - if (__strex(j, i) == 0) - return r; - } - } - static inline uint32_t ExchangeAdd_NoSync(volatile uint32_t *i, uint32_t j) - { - for(;;) - { - T r = __ldrex(i); - if (__strex(r + j, i) == 0) - return r; - } - } - - static inline bool CompareAndSet_NoSync(volatile uint32_t *i, uint32_t c, uint32_t value) - { - for(;;) - { - T r = __ldrex(i); - if (r != c) - return 0; - if (__strex(value, i) == 0) - return 1; - } - } - -#elif defined(OVR_CPU_ARM) - typedef uint32_t T; - - static inline uint32_t Exchange_NoSync(volatile uint32_t *i, uint32_t j) - { - uint32_t ret, dummy; - - asm volatile("1:\n\t" - "ldrex %[r],[%[i]]\n\t" - "strex %[t],%[j],[%[i]]\n\t" - "cmp %[t],#0\n\t" - "bne 1b\n\t" - : "+m" (*i), [r] "=&r" (ret), [t] "=&r" (dummy) : [i] "r" (i), [j] "r" (j) : "cc", "memory"); - - return ret; - } - - static inline uint32_t ExchangeAdd_NoSync(volatile uint32_t *i, uint32_t j) - { - uint32_t ret, dummy, test; - - asm volatile("1:\n\t" - "ldrex %[r],[%[i]]\n\t" - "add %[o],%[r],%[j]\n\t" - "strex %[t],%[o],[%[i]]\n\t" - "cmp %[t],#0\n\t" - "bne 1b\n\t" - : "+m" (*i), [r] "=&r" (ret), [o] "=&r" (dummy), [t] "=&r" (test) : [i] "r" (i), [j] "r" (j) : "cc", "memory"); - - return ret; - } - - static inline bool CompareAndSet_NoSync(volatile uint32_t *i, uint32_t c, uint32_t value) - { - uint32_t ret = 1, dummy, test; - - asm volatile("1:\n\t" - "ldrex %[o],[%[i]]\n\t" - "cmp %[o],%[c]\n\t" - "bne 2f\n\t" - "strex %[r],%[v],[%[i]]\n\t" - "cmp %[r],#0\n\t" - "bne 1b\n\t" - "2:\n" - : "+m" (*i),[r] "=&r" (ret), [o] "=&r" (dummy), [t] "=&r" (test) : [i] "r" (i), [c] "r" (c), [v] "r" (value) - : "cc", "memory"); - - return !ret; - } - -#elif defined(OVR_CPU_X86) - typedef uint32_t T; - - static inline uint32_t Exchange_NoSync(volatile uint32_t *i, uint32_t j) - { - asm volatile("xchgl %1,%[i]\n" - : "+m" (*i), "=q" (j) : [i] "m" (*i), "1" (j) : "cc", "memory"); - - return j; - } - - static inline uint32_t ExchangeAdd_NoSync(volatile uint32_t *i, uint32_t j) - { - asm volatile("lock; xaddl %1,%[i]\n" - : "+m" (*i), "+q" (j) : [i] "m" (*i) : "cc", "memory"); - - return j; - } - - static inline bool CompareAndSet_NoSync(volatile uint32_t *i, uint32_t c, uint32_t value) - { - uint32_t ret; - - asm volatile("lock; cmpxchgl %[v],%[i]\n" - : "+m" (*i), "=a" (ret) : [i] "m" (*i), "1" (c), [v] "q" (value) : "cc", "memory"); - - return (ret == c); - } - -#elif defined(OVR_CC_GNU) && (__GNUC__ >= 4 && __GNUC_MINOR__ >= 1) - - typedef uint32_t T; - - static inline T Exchange_NoSync(volatile T *i, T j) - { - T v; - do { - v = *i; - } while (!__sync_bool_compare_and_swap(i, v, j)); - return v; - } - - static inline T ExchangeAdd_NoSync(volatile T *i, T j) - { - return __sync_fetch_and_add(i, j); - } - - static inline bool CompareAndSet_NoSync(volatile T *i, T c, T value) - { - return __sync_bool_compare_and_swap(i, c, value); - } - -#endif // OS -}; - - -// 8-Byte raw data data atomic op implementation class. -// Currently implementation is provided only on systems with 64-bit pointers. -struct AtomicOpsRaw_8ByteImpl : public AtomicOpsRawBase -{ -#if !defined(OVR_64BIT_POINTERS) || !defined(OVR_ENABLE_THREADS) - - // Provide a type for no-thread-support cases. Used by AtomicOpsRaw_DefImpl. - typedef uint64_t T; - - // *** Thread - Safe OS specific versions. -#elif defined(OVR_OS_MS) - - // This is only for 64-bit systems. - typedef LONG64 T; - typedef volatile T* InterlockTPtr; - inline static T Exchange_NoSync(volatile T* p, T val) { return InterlockedExchange64((InterlockTPtr)p, val); } - inline static T ExchangeAdd_NoSync(volatile T* p, T val) { return InterlockedExchangeAdd64((InterlockTPtr)p, val); } - inline static bool CompareAndSet_NoSync(volatile T* p, T c, T val) { return InterlockedCompareExchange64((InterlockTPtr)p, val, c) == c; } - -#elif defined(OVR_CPU_PPC64) - - typedef uint64_t T; - - static inline uint64_t Exchange_NoSync(volatile uint64_t *i, uint64_t j) - { - uint64_t dummy, ret; - - asm volatile("1:\n\t" - "ldarx %[r],0,%[i]\n\t" - "mr %[o],%[j]\n\t" - "stdcx. %[o],0,%[i]\n\t" - "bne- 1b\n" - : "+m" (*i), [r] "=&b" (ret), [o] "=&r" (dummy) : [i] "b" (i), [j] "b" (j) : "cc"); - - return ret; - } - - static inline uint64_t ExchangeAdd_NoSync(volatile uint64_t *i, uint64_t j) - { - uint64_t dummy, ret; - - asm volatile("1:\n\t" - "ldarx %[r],0,%[i]\n\t" - "add %[o],%[r],%[j]\n\t" - "stdcx. %[o],0,%[i]\n\t" - "bne- 1b\n" - : "+m" (*i), [r] "=&b" (ret), [o] "=&r" (dummy) : [i] "b" (i), [j] "b" (j) : "cc"); - - return ret; - } - - static inline bool CompareAndSet_NoSync(volatile uint64_t *i, uint64_t c, uint64_t value) - { - uint64_t ret, dummy; - - asm volatile("1:\n\t" - "ldarx %[r],0,%[i]\n\t" - "cmpw 0,%[r],%[cmp]\n\t" - "mfcr %[r]\n\t" - "bne- 2f\n\t" - "stdcx. %[val],0,%[i]\n\t" - "bne- 1b\n\t" - "2:\n" - : "+m" (*i), [r] "=&b" (ret), [o] "=&r" (dummy) : [i] "b" (i), [cmp] "b" (c), [val] "b" (value) : "cc"); - - return (ret & 0x20000000) ? 1 : 0; - } - -#elif defined(OVR_CC_GNU) && (__GNUC__ >= 4 && __GNUC_MINOR__ >= 1) - - typedef uint64_t T; - - static inline T Exchange_NoSync(volatile T *i, T j) - { - T v; - do { - v = *i; - } while (!__sync_bool_compare_and_swap(i, v, j)); - return v; - } - - static inline T ExchangeAdd_NoSync(volatile T *i, T j) - { - return __sync_fetch_and_add(i, j); - } - - static inline bool CompareAndSet_NoSync(volatile T *i, T c, T value) - { - return __sync_bool_compare_and_swap(i, c, value); - } - -#endif // OS -}; - - -// Default implementation for AtomicOpsRaw; provides implementation of mem-fenced -// atomic operations where fencing is done with a sync object wrapped around a NoSync -// operation implemented in the base class. If such implementation is not possible -// on a given platform, #ifdefs can be used to disable it and then op functions can be -// implemented individually in the appropriate AtomicOpsRaw<size> class. - -template<class O> -struct AtomicOpsRaw_DefImpl : public O -{ - typedef typename O::T O_T; - typedef typename O::FullSync O_FullSync; - typedef typename O::AcquireSync O_AcquireSync; - typedef typename O::ReleaseSync O_ReleaseSync; - - // If there is no thread support, provide the default implementation. In this case, - // the base class (0) must still provide the T declaration. -#ifndef OVR_ENABLE_THREADS - - // Atomic exchange of val with argument. Returns old val. - inline static O_T Exchange_NoSync(volatile O_T* p, O_T val) { O_T old = *p; *p = val; return old; } - // Adds a new val to argument; returns its old val. - inline static O_T ExchangeAdd_NoSync(volatile O_T* p, O_T val) { O_T old = *p; *p += val; return old; } - // Compares the argument data with 'c' val. - // If succeeded, stores val int '*p' and returns true; otherwise returns false. - inline static bool CompareAndSet_NoSync(volatile O_T* p, O_T c, O_T val) { if (*p==c) { *p = val; return 1; } return 0; } - -#endif - - // If NoSync wrapped implementation may not be possible, it this block should be - // replaced with per-function implementation in O. - // "AtomicOpsRaw_DefImpl<O>::" prefix in calls below. - inline static O_T Exchange_Sync(volatile O_T* p, O_T val) { O_FullSync sync; OVR_UNUSED(sync); return AtomicOpsRaw_DefImpl<O>::Exchange_NoSync(p, val); } - inline static O_T Exchange_Release(volatile O_T* p, O_T val) { O_ReleaseSync sync; OVR_UNUSED(sync); return AtomicOpsRaw_DefImpl<O>::Exchange_NoSync(p, val); } - inline static O_T Exchange_Acquire(volatile O_T* p, O_T val) { O_AcquireSync sync; OVR_UNUSED(sync); return AtomicOpsRaw_DefImpl<O>::Exchange_NoSync(p, val); } - inline static O_T ExchangeAdd_Sync(volatile O_T* p, O_T val) { O_FullSync sync; OVR_UNUSED(sync); return AtomicOpsRaw_DefImpl<O>::ExchangeAdd_NoSync(p, val); } - inline static O_T ExchangeAdd_Release(volatile O_T* p, O_T val) { O_ReleaseSync sync; OVR_UNUSED(sync); return AtomicOpsRaw_DefImpl<O>::ExchangeAdd_NoSync(p, val); } - inline static O_T ExchangeAdd_Acquire(volatile O_T* p, O_T val) { O_AcquireSync sync; OVR_UNUSED(sync); return AtomicOpsRaw_DefImpl<O>::ExchangeAdd_NoSync(p, val); } - inline static bool CompareAndSet_Sync(volatile O_T* p, O_T c, O_T val) { O_FullSync sync; OVR_UNUSED(sync); return AtomicOpsRaw_DefImpl<O>::CompareAndSet_NoSync(p,c,val); } - inline static bool CompareAndSet_Release(volatile O_T* p, O_T c, O_T val) { O_ReleaseSync sync; OVR_UNUSED(sync); return AtomicOpsRaw_DefImpl<O>::CompareAndSet_NoSync(p,c,val); } - inline static bool CompareAndSet_Acquire(volatile O_T* p, O_T c, O_T val) { O_AcquireSync sync; OVR_UNUSED(sync); return AtomicOpsRaw_DefImpl<O>::CompareAndSet_NoSync(p,c,val); } - - // Loads and stores with memory fence. These have only the relevant versions. -#ifdef OVR_CPU_X86 - // On X86, Store_Release is implemented as exchange. Note that we can also - // consider 'sfence' in the future, although it is not as compatible with older CPUs. - inline static void Store_Release(volatile O_T* p, O_T val) { Exchange_Release(p, val); } -#else - inline static void Store_Release(volatile O_T* p, O_T val) { O_ReleaseSync sync; OVR_UNUSED(sync); *p = val; } -#endif - inline static O_T Load_Acquire(const volatile O_T* p) - { - O_AcquireSync sync; - OVR_UNUSED(sync); - -#if defined(OVR_CC_MSVC) - _ReadBarrier(); // Compiler fence and load barrier -#elif defined(OVR_CC_INTEL) - __memory_barrier(); // Compiler fence -#else - // GCC-compatible: - asm volatile ("" : : : "memory"); // Compiler fence -#endif - - return *p; - } -}; - - -template<int size> -struct AtomicOpsRaw : public AtomicOpsRawBase { }; - -template<> -struct AtomicOpsRaw<4> : public AtomicOpsRaw_DefImpl<AtomicOpsRaw_4ByteImpl> -{ - // Ensure that assigned type size is correct. - AtomicOpsRaw() - { OVR_COMPILER_ASSERT(sizeof(AtomicOpsRaw_DefImpl<AtomicOpsRaw_4ByteImpl>::T) == 4); } -}; -template<> -struct AtomicOpsRaw<8> : public AtomicOpsRaw_DefImpl<AtomicOpsRaw_8ByteImpl> -{ - AtomicOpsRaw() - { OVR_COMPILER_ASSERT(sizeof(AtomicOpsRaw_DefImpl<AtomicOpsRaw_8ByteImpl>::T) == 8); } -}; - - -// *** AtomicOps - implementation of atomic Ops for specified class - -// Implements atomic ops on a class, provided that the object is either -// 4 or 8 bytes in size (depending on the AtomicOpsRaw specializations -// available). Relies on AtomicOpsRaw for much of implementation. - -template<class C> -class AtomicOps -{ - typedef AtomicOpsRaw<sizeof(C)> Ops; - typedef typename Ops::T T; - typedef volatile typename Ops::T* PT; - // We cast through unions to (1) avoid pointer size compiler warnings - // and (2) ensure that there are no problems with strict pointer aliasing. - union C2T_union { C c; T t; }; - -public: - // General purpose implementation for standard syncs. - inline static C Exchange_Sync(volatile C* p, C val) { C2T_union u; u.c = val; u.t = Ops::Exchange_Sync((PT)p, u.t); return u.c; } - inline static C Exchange_Release(volatile C* p, C val) { C2T_union u; u.c = val; u.t = Ops::Exchange_Release((PT)p, u.t); return u.c; } - inline static C Exchange_Acquire(volatile C* p, C val) { C2T_union u; u.c = val; u.t = Ops::Exchange_Acquire((PT)p, u.t); return u.c; } - inline static C Exchange_NoSync(volatile C* p, C val) { C2T_union u; u.c = val; u.t = Ops::Exchange_NoSync((PT)p, u.t); return u.c; } - inline static C ExchangeAdd_Sync(volatile C* p, C val) { C2T_union u; u.c = val; u.t = Ops::ExchangeAdd_Sync((PT)p, u.t); return u.c; } - inline static C ExchangeAdd_Release(volatile C* p, C val) { C2T_union u; u.c = val; u.t = Ops::ExchangeAdd_Release((PT)p, u.t); return u.c; } - inline static C ExchangeAdd_Acquire(volatile C* p, C val) { C2T_union u; u.c = val; u.t = Ops::ExchangeAdd_Acquire((PT)p, u.t); return u.c; } - inline static C ExchangeAdd_NoSync(volatile C* p, C val) { C2T_union u; u.c = val; u.t = Ops::ExchangeAdd_NoSync((PT)p, u.t); return u.c; } - inline static bool CompareAndSet_Sync(volatile C* p, C c, C val) { C2T_union u,cu; u.c = val; cu.c = c; return Ops::CompareAndSet_Sync((PT)p, cu.t, u.t); } - inline static bool CompareAndSet_Release(volatile C* p, C c, C val){ C2T_union u,cu; u.c = val; cu.c = c; return Ops::CompareAndSet_Release((PT)p, cu.t, u.t); } - inline static bool CompareAndSet_Acquire(volatile C* p, C c, C val){ C2T_union u,cu; u.c = val; cu.c = c; return Ops::CompareAndSet_Acquire((PT)p, cu.t, u.t); } - inline static bool CompareAndSet_NoSync(volatile C* p, C c, C val) { C2T_union u,cu; u.c = val; cu.c = c; return Ops::CompareAndSet_NoSync((PT)p, cu.t, u.t); } - - // Loads and stores with memory fence. These have only the relevant versions. - inline static void Store_Release(volatile C* p, C val) { C2T_union u; u.c = val; Ops::Store_Release((PT)p, u.t); } - inline static C Load_Acquire(const volatile C* p) { C2T_union u; u.t = Ops::Load_Acquire((PT)p); return u.c; } - - // Deprecated typo error: - inline static bool CompareAndSet_Relse(volatile C* p, C c, C val){ C2T_union u,cu; u.c = val; cu.c = c; return Ops::CompareAndSet_Acquire((PT)p, cu.t, u.t); } -}; - - - -// Atomic value base class - implements operations shared for integers and pointers. -template<class T> -class AtomicValueBase -{ -protected: - typedef AtomicOps<T> Ops; -public: - - volatile T Value; - - inline AtomicValueBase() { } - explicit inline AtomicValueBase(T val) { Ops::Store_Release(&Value, val); } - - // Most libraries (TBB and Joshua Scholar's) library do not do Load_Acquire - // here, since most algorithms do not require atomic loads. Needs some research. - inline operator T() const { return Value; } - - // *** Standard Atomic inlines - inline T Exchange_Sync(T val) { return Ops::Exchange_Sync(&Value, val); } - inline T Exchange_Release(T val) { return Ops::Exchange_Release(&Value, val); } - inline T Exchange_Acquire(T val) { return Ops::Exchange_Acquire(&Value, val); } - inline T Exchange_NoSync(T val) { return Ops::Exchange_NoSync(&Value, val); } - inline bool CompareAndSet_Sync(T c, T val) { return Ops::CompareAndSet_Sync(&Value, c, val); } - inline bool CompareAndSet_Release(T c, T val) { return Ops::CompareAndSet_Release(&Value, c, val); } - inline bool CompareAndSet_Acquire(T c, T val) { return Ops::CompareAndSet_Acquire(&Value, c, val); } - inline bool CompareAndSet_NoSync(T c, T val) { return Ops::CompareAndSet_NoSync(&Value, c, val); } - // Load & Store. - inline void Store_Release(T val) { Ops::Store_Release(&Value, val); } - inline T Load_Acquire() const { return Ops::Load_Acquire(&Value); } -}; - - -// ***** AtomicPtr - Atomic pointer template - -// This pointer class supports atomic assignments with release, -// increment / decrement operations, and conditional compare + set. - -template<class T> -class AtomicPtr : public AtomicValueBase<T*> -{ - typedef typename AtomicValueBase<T*>::Ops Ops; - -public: - // Initialize pointer value to 0 by default; use Store_Release only with explicit constructor. - inline AtomicPtr() : AtomicValueBase<T*>() { this->Value = 0; } - explicit inline AtomicPtr(T* val) : AtomicValueBase<T*>(val) { } - - // Pointer access. - inline T* operator -> () const { return this->Load_Acquire(); } - - // It looks like it is convenient to have Load_Acquire characteristics - // for this, since that is convenient for algorithms such as linked - // list traversals that can be added to bu another thread. - inline operator T* () const { return this->Load_Acquire(); } - - - // *** Standard Atomic inlines (applicable to pointers) - - // ExhangeAdd considers pointer size for pointers. - template<class I> - inline T* ExchangeAdd_Sync(I incr) { return Ops::ExchangeAdd_Sync(&this->Value, ((T*)0) + incr); } - template<class I> - inline T* ExchangeAdd_Release(I incr) { return Ops::ExchangeAdd_Release(&this->Value, ((T*)0) + incr); } - template<class I> - inline T* ExchangeAdd_Acquire(I incr) { return Ops::ExchangeAdd_Acquire(&this->Value, ((T*)0) + incr); } - template<class I> - inline T* ExchangeAdd_NoSync(I incr) { return Ops::ExchangeAdd_NoSync(&this->Value, ((T*)0) + incr); } - - // *** Atomic Operators - - inline T* operator = (T* val) { this->Store_Release(val); return val; } - - template<class I> - inline T* operator += (I val) { return ExchangeAdd_Sync(val) + val; } - template<class I> - inline T* operator -= (I val) { return operator += (-val); } - - inline T* operator ++ () { return ExchangeAdd_Sync(1) + 1; } - inline T* operator -- () { return ExchangeAdd_Sync(-1) - 1; } - inline T* operator ++ (int) { return ExchangeAdd_Sync(1); } - inline T* operator -- (int) { return ExchangeAdd_Sync(-1); } -}; - - -// ***** AtomicInt - Atomic integer template - -// Implements an atomic integer type; the exact type to use is provided -// as an argument. Supports atomic Acquire / Release semantics, atomic -// arithmetic operations, and atomic conditional compare + set. - -template<class T> -class AtomicInt : public AtomicValueBase<T> -{ - typedef typename AtomicValueBase<T>::Ops Ops; - -public: - inline AtomicInt() : AtomicValueBase<T>() { } - explicit inline AtomicInt(T val) : AtomicValueBase<T>(val) { } - - - // *** Standard Atomic inlines (applicable to int) - inline T ExchangeAdd_Sync(T val) { return Ops::ExchangeAdd_Sync(&this->Value, val); } - inline T ExchangeAdd_Release(T val) { return Ops::ExchangeAdd_Release(&this->Value, val); } - inline T ExchangeAdd_Acquire(T val) { return Ops::ExchangeAdd_Acquire(&this->Value, val); } - inline T ExchangeAdd_NoSync(T val) { return Ops::ExchangeAdd_NoSync(&this->Value, val); } - // These increments could be more efficient because they don't return a value. - inline void Increment_Sync() { ExchangeAdd_Sync((T)1); } - inline void Increment_Release() { ExchangeAdd_Release((T)1); } - inline void Increment_Acquire() { ExchangeAdd_Acquire((T)1); } - inline void Increment_NoSync() { ExchangeAdd_NoSync((T)1); } - - // *** Atomic Operators - - inline T operator = (T val) { this->Store_Release(val); return val; } - inline T operator += (T val) { return ExchangeAdd_Sync(val) + val; } - inline T operator -= (T val) { return ExchangeAdd_Sync(0 - val) - val; } - - inline T operator ++ () { return ExchangeAdd_Sync((T)1) + 1; } - inline T operator -- () { return ExchangeAdd_Sync(((T)0)-1) - 1; } - inline T operator ++ (int) { return ExchangeAdd_Sync((T)1); } - inline T operator -- (int) { return ExchangeAdd_Sync(((T)0)-1); } - - // More complex atomic operations. Leave it to compiler whether to optimize them or not. - T operator &= (T arg) - { - T comp, newVal; - do { - comp = this->Value; - newVal = comp & arg; - } while(!this->CompareAndSet_Sync(comp, newVal)); - return newVal; - } - - T operator |= (T arg) - { - T comp, newVal; - do { - comp = this->Value; - newVal = comp | arg; - } while(!this->CompareAndSet_Sync(comp, newVal)); - return newVal; - } - - T operator ^= (T arg) - { - T comp, newVal; - do { - comp = this->Value; - newVal = comp ^ arg; - } while(!this->CompareAndSet_Sync(comp, newVal)); - return newVal; - } - - T operator *= (T arg) - { - T comp, newVal; - do { - comp = this->Value; - newVal = comp * arg; - } while(!this->CompareAndSet_Sync(comp, newVal)); - return newVal; - } - - T operator /= (T arg) - { - T comp, newVal; - do { - comp = this->Value; - newVal = comp / arg; - } while(!CompareAndSet_Sync(comp, newVal)); - return newVal; - } - - T operator >>= (unsigned bits) - { - T comp, newVal; - do { - comp = this->Value; - newVal = comp >> bits; - } while(!CompareAndSet_Sync(comp, newVal)); - return newVal; - } - - T operator <<= (unsigned bits) - { - T comp, newVal; - do { - comp = this->Value; - newVal = comp << bits; - } while(!this->CompareAndSet_Sync(comp, newVal)); - return newVal; - } -}; - - -//----------------------------------------------------------------------------------- -// ***** Lock - -// Lock is a simplest and most efficient mutual-exclusion lock class. -// Unlike Mutex, it cannot be waited on. - -class Lock -{ - // NOTE: Locks are not allocatable and they themselves should not allocate - // memory by standard means. This is the case because StandardAllocator - // relies on this class. - // Make 'delete' private. Don't do this for 'new' since it can be redefined. - void operator delete(void*) {} - - - // *** Lock implementation for various platforms. - -#if !defined(OVR_ENABLE_THREADS) - -public: - // With no thread support, lock does nothing. - inline Lock() { } - inline Lock(unsigned) { } - inline ~Lock() { } - inline void DoLock() { } - inline void Unlock() { } - - // Windows. -#elif defined(OVR_OS_MS) - - CRITICAL_SECTION cs; -public: - Lock(unsigned spinCount = 10000); // Mutexes with non-zero spin counts usually result in better performance. - ~Lock(); - // Locking functions. - inline void DoLock() { ::EnterCriticalSection(&cs); } - inline void Unlock() { ::LeaveCriticalSection(&cs); } - -#else - pthread_mutex_t mutex; - -public: - static pthread_mutexattr_t RecursiveAttr; - static bool RecursiveAttrInit; - - Lock (unsigned spinCount = 0) // To do: Support spin count, probably via a custom lock implementation. - { - OVR_UNUSED(spinCount); - if (!RecursiveAttrInit) - { - pthread_mutexattr_init(&RecursiveAttr); - pthread_mutexattr_settype(&RecursiveAttr, PTHREAD_MUTEX_RECURSIVE); - RecursiveAttrInit = 1; - } - pthread_mutex_init(&mutex,&RecursiveAttr); - } - ~Lock () { pthread_mutex_destroy(&mutex); } - inline void DoLock() { pthread_mutex_lock(&mutex); } - inline void Unlock() { pthread_mutex_unlock(&mutex); } - -#endif // OVR_ENABLE_THREDS - - -public: - // Locker class, used for automatic locking - class Locker - { - public: - Lock *pLock; - inline Locker(Lock *plock) - { pLock = plock; pLock->DoLock(); } - inline ~Locker() - { pLock->Unlock(); } - }; -}; - - -//------------------------------------------------------------------------------------- -// Globally shared Lock implementation used for MessageHandlers, etc. - -class SharedLock -{ -public: - SharedLock() : UseCount(0) {} - - Lock* GetLockAddRef(); - void ReleaseLock(Lock* plock); - -private: - Lock* toLock() { return (Lock*)Buffer; } - - // UseCount and max alignment. - volatile int UseCount; - uint64_t Buffer[(sizeof(Lock)+sizeof(uint64_t)-1)/sizeof(uint64_t)]; -}; - - -} // OVR - -#endif diff --git a/LibOVR/Src/Kernel/OVR_CRC32.cpp b/LibOVR/Src/Kernel/OVR_CRC32.cpp deleted file mode 100644 index 82cbe7f..0000000 --- a/LibOVR/Src/Kernel/OVR_CRC32.cpp +++ /dev/null @@ -1,85 +0,0 @@ -/************************************************************************************ - -Filename : OVR_CRC32.cpp -Content : CRC-32 with polynomial used for sensor devices -Created : June 20, 2014 -Author : Chris Taylor - -Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); -you may not use the Oculus VR Rift SDK except in compliance with the License, -which is provided at the time of installation or download, or which -otherwise accompanies this software in either electronic or hard copy form. - -You may obtain a copy of the License at - -http://www.oculusvr.com/licenses/LICENSE-3.2 - -Unless required by applicable law or agreed to in writing, the Oculus VR SDK -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -************************************************************************************/ - -#include "OVR_CRC32.h" - -namespace OVR { - - -static const uint32_t CRC_Table[256] = { - 0x00000000, 0x04c11db7, 0x09823b6e, 0x0d4326d9, 0x130476dc, 0x17c56b6b, 0x1a864db2, 0x1e475005, - 0x2608edb8, 0x22c9f00f, 0x2f8ad6d6, 0x2b4bcb61, 0x350c9b64, 0x31cd86d3, 0x3c8ea00a, 0x384fbdbd, - 0x4c11db70, 0x48d0c6c7, 0x4593e01e, 0x4152fda9, 0x5f15adac, 0x5bd4b01b, 0x569796c2, 0x52568b75, - 0x6a1936c8, 0x6ed82b7f, 0x639b0da6, 0x675a1011, 0x791d4014, 0x7ddc5da3, 0x709f7b7a, 0x745e66cd, - 0x9823b6e0, 0x9ce2ab57, 0x91a18d8e, 0x95609039, 0x8b27c03c, 0x8fe6dd8b, 0x82a5fb52, 0x8664e6e5, - 0xbe2b5b58, 0xbaea46ef, 0xb7a96036, 0xb3687d81, 0xad2f2d84, 0xa9ee3033, 0xa4ad16ea, 0xa06c0b5d, - 0xd4326d90, 0xd0f37027, 0xddb056fe, 0xd9714b49, 0xc7361b4c, 0xc3f706fb, 0xceb42022, 0xca753d95, - 0xf23a8028, 0xf6fb9d9f, 0xfbb8bb46, 0xff79a6f1, 0xe13ef6f4, 0xe5ffeb43, 0xe8bccd9a, 0xec7dd02d, - 0x34867077, 0x30476dc0, 0x3d044b19, 0x39c556ae, 0x278206ab, 0x23431b1c, 0x2e003dc5, 0x2ac12072, - 0x128e9dcf, 0x164f8078, 0x1b0ca6a1, 0x1fcdbb16, 0x018aeb13, 0x054bf6a4, 0x0808d07d, 0x0cc9cdca, - 0x7897ab07, 0x7c56b6b0, 0x71159069, 0x75d48dde, 0x6b93dddb, 0x6f52c06c, 0x6211e6b5, 0x66d0fb02, - 0x5e9f46bf, 0x5a5e5b08, 0x571d7dd1, 0x53dc6066, 0x4d9b3063, 0x495a2dd4, 0x44190b0d, 0x40d816ba, - 0xaca5c697, 0xa864db20, 0xa527fdf9, 0xa1e6e04e, 0xbfa1b04b, 0xbb60adfc, 0xb6238b25, 0xb2e29692, - 0x8aad2b2f, 0x8e6c3698, 0x832f1041, 0x87ee0df6, 0x99a95df3, 0x9d684044, 0x902b669d, 0x94ea7b2a, - 0xe0b41de7, 0xe4750050, 0xe9362689, 0xedf73b3e, 0xf3b06b3b, 0xf771768c, 0xfa325055, 0xfef34de2, - 0xc6bcf05f, 0xc27dede8, 0xcf3ecb31, 0xcbffd686, 0xd5b88683, 0xd1799b34, 0xdc3abded, 0xd8fba05a, - 0x690ce0ee, 0x6dcdfd59, 0x608edb80, 0x644fc637, 0x7a089632, 0x7ec98b85, 0x738aad5c, 0x774bb0eb, - 0x4f040d56, 0x4bc510e1, 0x46863638, 0x42472b8f, 0x5c007b8a, 0x58c1663d, 0x558240e4, 0x51435d53, - 0x251d3b9e, 0x21dc2629, 0x2c9f00f0, 0x285e1d47, 0x36194d42, 0x32d850f5, 0x3f9b762c, 0x3b5a6b9b, - 0x0315d626, 0x07d4cb91, 0x0a97ed48, 0x0e56f0ff, 0x1011a0fa, 0x14d0bd4d, 0x19939b94, 0x1d528623, - 0xf12f560e, 0xf5ee4bb9, 0xf8ad6d60, 0xfc6c70d7, 0xe22b20d2, 0xe6ea3d65, 0xeba91bbc, 0xef68060b, - 0xd727bbb6, 0xd3e6a601, 0xdea580d8, 0xda649d6f, 0xc423cd6a, 0xc0e2d0dd, 0xcda1f604, 0xc960ebb3, - 0xbd3e8d7e, 0xb9ff90c9, 0xb4bcb610, 0xb07daba7, 0xae3afba2, 0xaafbe615, 0xa7b8c0cc, 0xa379dd7b, - 0x9b3660c6, 0x9ff77d71, 0x92b45ba8, 0x9675461f, 0x8832161a, 0x8cf30bad, 0x81b02d74, 0x857130c3, - 0x5d8a9099, 0x594b8d2e, 0x5408abf7, 0x50c9b640, 0x4e8ee645, 0x4a4ffbf2, 0x470cdd2b, 0x43cdc09c, - 0x7b827d21, 0x7f436096, 0x7200464f, 0x76c15bf8, 0x68860bfd, 0x6c47164a, 0x61043093, 0x65c52d24, - 0x119b4be9, 0x155a565e, 0x18197087, 0x1cd86d30, 0x029f3d35, 0x065e2082, 0x0b1d065b, 0x0fdc1bec, - 0x3793a651, 0x3352bbe6, 0x3e119d3f, 0x3ad08088, 0x2497d08d, 0x2056cd3a, 0x2d15ebe3, 0x29d4f654, - 0xc5a92679, 0xc1683bce, 0xcc2b1d17, 0xc8ea00a0, 0xd6ad50a5, 0xd26c4d12, 0xdf2f6bcb, 0xdbee767c, - 0xe3a1cbc1, 0xe760d676, 0xea23f0af, 0xeee2ed18, 0xf0a5bd1d, 0xf464a0aa, 0xf9278673, 0xfde69bc4, - 0x89b8fd09, 0x8d79e0be, 0x803ac667, 0x84fbdbd0, 0x9abc8bd5, 0x9e7d9662, 0x933eb0bb, 0x97ffad0c, - 0xafb010b1, 0xab710d06, 0xa6322bdf, 0xa2f33668, 0xbcb4666d, 0xb8757bda, 0xb5365d03, 0xb1f740b4 -}; - - -//// CRC-32 - -uint32_t CRC32_Calculate(const void* data, int bytes, uint32_t accumulator) -{ - const uint8_t* inputBytes = reinterpret_cast<const uint8_t*>( data ); - - for (int j = 0; j < bytes; ++j) - { - int i = ((uint32_t)(accumulator >> 24) ^ *inputBytes++) & 0xFF; - - accumulator = (accumulator << 8) ^ CRC_Table[i]; - } - - return ~accumulator; -} - - -} // OVR diff --git a/LibOVR/Src/Kernel/OVR_CRC32.h b/LibOVR/Src/Kernel/OVR_CRC32.h deleted file mode 100644 index e4edd65..0000000 --- a/LibOVR/Src/Kernel/OVR_CRC32.h +++ /dev/null @@ -1,45 +0,0 @@ -/************************************************************************************ - -PublicHeader: OVR -Filename : OVR_CRC32.h -Content : CRC-32 with polynomial used for sensor devices -Created : June 20, 2014 -Author : Chris Taylor - -Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); -you may not use the Oculus VR Rift SDK except in compliance with the License, -which is provided at the time of installation or download, or which -otherwise accompanies this software in either electronic or hard copy form. - -You may obtain a copy of the License at - -http://www.oculusvr.com/licenses/LICENSE-3.2 - -Unless required by applicable law or agreed to in writing, the Oculus VR SDK -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -************************************************************************************/ - -#ifndef OVR_CRC32_h -#define OVR_CRC32_h - -#include "OVR_Types.h" - -namespace OVR { - - -//----------------------------------------------------------------------------------- -// ***** CRC-32 - -// Polynomial used and algorithm details are proprietary to our sensor board -uint32_t CRC32_Calculate(const void* data, int bytes, uint32_t prevCRC = 0); - - -} // namespace OVR - -#endif diff --git a/LibOVR/Src/Kernel/OVR_Color.h b/LibOVR/Src/Kernel/OVR_Color.h deleted file mode 100644 index 7b5e966..0000000 --- a/LibOVR/Src/Kernel/OVR_Color.h +++ /dev/null @@ -1,73 +0,0 @@ -/************************************************************************************ - -PublicHeader: OVR_Kernel.h -Filename : OVR_Color.h -Content : Contains color struct. -Created : February 7, 2013 -Notes : - -Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); -you may not use the Oculus VR Rift SDK except in compliance with the License, -which is provided at the time of installation or download, or which -otherwise accompanies this software in either electronic or hard copy form. - -You may obtain a copy of the License at - -http://www.oculusvr.com/licenses/LICENSE-3.2 - -Unless required by applicable law or agreed to in writing, the Oculus VR SDK -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -************************************************************************************/ -#ifndef OVR_Color_h -#define OVR_Color_h - -#include "OVR_Types.h" - -namespace OVR { - - -struct Color -{ - uint8_t R,G,B,A; - - Color() - { - #if defined(OVR_BUILD_DEBUG) - R = G = B = A = 0; - #endif - } - - // Constructs color by channel. Alpha is set to 0xFF (fully visible) - // if not specified. - Color(unsigned char r,unsigned char g,unsigned char b, unsigned char a = 0xFF) - : R(r), G(g), B(b), A(a) { } - - // 0xAARRGGBB - Common HTML color Hex layout - Color(unsigned c) - : R((unsigned char)(c>>16)), G((unsigned char)(c>>8)), - B((unsigned char)c), A((unsigned char)(c>>24)) { } - - bool operator==(const Color& b) const - { - return R == b.R && G == b.G && B == b.B && A == b.A; - } - - void GetRGBA(float *r, float *g, float *b, float* a) const - { - *r = R / 255.0f; - *g = G / 255.0f; - *b = B / 255.0f; - *a = A / 255.0f; - } -}; - - -} // namespace OVR - -#endif diff --git a/LibOVR/Src/Kernel/OVR_Compiler.h b/LibOVR/Src/Kernel/OVR_Compiler.h deleted file mode 100644 index 93a4181..0000000 --- a/LibOVR/Src/Kernel/OVR_Compiler.h +++ /dev/null @@ -1,1524 +0,0 @@ -/************************************************************************************ - -PublicHeader: OVR.h -Filename : OVR_Compiler.h -Content : Compiler-specific feature identification and utilities -Created : June 19, 2014 -Notes : - -Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); -you may not use the Oculus VR Rift SDK except in compliance with the License, -which is provided at the time of installation or download, or which -otherwise accompanies this software in either electronic or hard copy form. - -You may obtain a copy of the License at - -http://www.oculusvr.com/licenses/LICENSE-3.2 - -Unless required by applicable law or agreed to in writing, the Oculus VR SDK -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -************************************************************************************/ - - -#ifndef OVR_Compiler_h -#define OVR_Compiler_h - -#pragma once - - -// References -// https://gcc.gnu.org/projects/cxx0x.html -// https://gcc.gnu.org/projects/cxx1y.html -// http://clang.llvm.org/cxx_status.html -// http://msdn.microsoft.com/en-us/library/hh567368.aspx -// https://docs.google.com/spreadsheet/pub?key=0AoBblDsbooe4dHZuVTRoSTFBejk5eFBfVk1GWlE5UlE&output=html -// http://nadeausoftware.com/articles/2012/10/c_c_tip_how_detect_compiler_name_and_version_using_compiler_predefined_macros - - -//----------------------------------------------------------------------------------- -// ***** Compiler -// -// The following compilers are defined: (OVR_CC_x) -// -// MSVC - Microsoft Visual C/C++ -// INTEL - Intel C++ for Linux / Windows -// GNU - GNU C++ -// ARM - ARM C/C++ - -#if defined(__INTEL_COMPILER) -// Intel 4.0 = 400 -// Intel 5.0 = 500 -// Intel 6.0 = 600 -// Intel 8.0 = 800 -// Intel 9.0 = 900 -# define OVR_CC_INTEL __INTEL_COMPILER - -#elif defined(_MSC_VER) -// MSVC 5.0 = 1100 -// MSVC 6.0 = 1200 -// MSVC 7.0 (VC2002) = 1300 -// MSVC 7.1 (VC2003) = 1310 -// MSVC 8.0 (VC2005) = 1400 -// MSVC 9.0 (VC2008) = 1500 -// MSVC 10.0 (VC2010) = 1600 -// MSVC 11.0 (VC2012) = 1700 -// MSVC 12.0 (VC2013) = 1800 -# define OVR_CC_MSVC _MSC_VER - -#if _MSC_VER == 0x1600 -# if _MSC_FULL_VER < 160040219 -# error "Oculus does not support VS2010 without SP1 installed." -# endif -#endif - -#elif defined(__GNUC__) -# define OVR_CC_GNU - -#elif defined(__clang__) -# define OVR_CC_CLANG - -#elif defined(__CC_ARM) -# define OVR_CC_ARM - -#else -# error "Oculus does not support this Compiler" -#endif - - -//----------------------------------------------------------------------------------- -// ***** OVR_CC_VERSION -// -// M = major version -// m = minor version -// p = patch release -// b = build number -// -// Compiler Format Example -// ---------------------------- -// OVR_CC_GNU Mmm 408 means GCC 4.8 -// OVR_CC_CLANG Mmm 305 means clang 3.5 -// OVR_CC_MSVC MMMM 1700 means VS2012 -// OVR_CC_ARM Mmpbbb 401677 means 4.0, patch 1, build 677 -// OVR_CC_INTEL MMmm 1210 means 12.10 -// OVR_CC_EDG Mmm 407 means EDG 4.7 -// -#if defined(OVR_CC_GNU) - #define OVR_CC_VERSION ((__GNUC__ * 100) + __GNUC_MINOR__) -#elif defined(OVR_CC_CLANG) - #define OVR_CC_VERSION ((__clang_major__ * 100) + __clang_minor__) -#elif defined(OVR_CC_MSVC) - #define OVR_CC_VERSION _MSC_VER // Question: Should we recognize _MSC_FULL_VER? -#elif defined(OVR_CC_ARM) - #define OVR_CC_VERSION __ARMCC_VERSION -#elif defined(OVR_CC_INTEL) - #if defined(__INTEL_COMPILER) - #define OVR_CC_VERSION __INTEL_COMPILER - #elif defined(__ICL) - #define OVR_CC_VERSION __ICL - #elif defined(__ICC) - #define OVR_CC_VERSION __ICC - #elif defined(__ECC) - #define OVR_CC_VERSION __ECC - #endif -#elif defined(OVR_CC_EDG) - #define OVR_CC_VERSION __EDG_VERSION__ // This is a generic fallback for EDG-based compilers which aren't specified above (e.g. as OVR_CC_ARM) -#endif - - - -// ----------------------------------------------------------------------------------- -// ***** OVR_DISABLE_OPTIMIZATION / OVR_RESTORE_OPTIMIZATION -// -// Allows for the dynamic disabling and restoring of compiler optimizations in code. -// This is useful for helping deal with potential compiler code generation problems. -// With VC++ the usage must be outside of function bodies. This can be used only to -// temporarily disable optimization for a block of code and not to temporarily enable -// optimization for a block of code. -// -// Clang doesn't support this as of June 2014, though function __attribute__((optimize(0)) -// is supposedly supported by clang in addition to GCC. To consider: Make a wrapper for -// this attribute-based functionality. -// -// Example usage: -// OVR_DISABLE_OPTIMIZATION() -// void Test() { ... } -// OVR_RESTORE_OPTIMIZATION() -// -#if !defined(OVR_DISABLE_OPTIMIZATION) - #if defined(OVR_CC_GNU) && (OVR_CC_VERSION > 404) && (defined(OVR_CPU_X86) || defined(OVR_CPU_X86_64)) - #define OVR_DISABLE_OPTIMIZATION() \ - _Pragma("GCC push_options") \ - _Pragma("GCC optimize 0") - #elif defined(OVR_CC_MSVC) - #define OVR_DISABLE_OPTIMIZATION() __pragma(optimize("", off)) - #else - #define OVR_DISABLE_OPTIMIZATION() - #endif -#endif - -#if !defined(OVR_RESTORE_OPTIMIZATION) - #if defined(OVR_CC_GNU) && (OVR_CC_VERSION > 404) && (defined(OVR_CPU_X86) || defined(OVR_CPU_X86_64)) - #define OVR_RESTORE_OPTIMIZATION() _Pragma("GCC pop_options") - #elif defined(OVR_CC_MSVC) - #define OVR_RESTORE_OPTIMIZATION() __pragma(optimize("", on)) - #else - #define OVR_RESTORE_OPTIMIZATION() - #endif -#endif - - -// ----------------------------------------------------------------------------------- -// ***** OVR_DISABLE_GNU_WARNING / OVR_RESTORE_GNU_WARNING -// -// Portable wrapper for disabling GCC compiler warnings, one at a time. See example -// usage for usage by example. -// -// Example usage: -// OVR_DISABLE_GNU_WARNING(-Wmissing-braces) // Only one warning per usage. -// OVR_DISABLE_GNU_WARNING(-Wunused-variable) -// <code> -// OVR_RESTORE_GNU_WARNINGS() -// OVR_RESTORE_GNU_WARNINGS() // Must match each disable with a restore. -// -#if !defined(OVR_DISABLE_GNU_WARNING) - #if defined(OVR_CC_GNU) - #define ODGW1(x) #x - #define ODGW2(x) ODGW1(GCC diagnostic ignored x) - #define ODGW3(x) ODGW2(#x) - #endif - - #if defined(OVR_CC_GNU) && (OVR_CC_VERSION >= 406) - #define OVR_DISABLE_GNU_WARNING(w) \ - _Pragma("GCC diagnostic push") \ - _Pragma(ODGW3(w)) - #elif defined(OVR_CC_GNU) && (OVR_CC_VERSION >= 404) // GCC 4.4 doesn't support diagnostic push, but supports disabling warnings. - #define OVR_DISABLE_GNU_WARNING(w) \ - _Pragma(ODGW3(w)) - #else - #define OVR_DISABLE_GNU_WARNING(w) - #endif -#endif - -#if !defined(OVR_RESTORE_GNU_WARNING) - #if defined(OVR_CC_GNU) && (OVR_CC_VERSION >= 4006) - #define OVR_RESTORE_GNU_WARNINGS() \ - _Pragma("GCC diagnostic pop") - #else - #define OVR_RESTORE_GNU_WARNING() - #endif -#endif - - - -// ----------------------------------------------------------------------------------- -// ***** OVR_DISABLE_CLANG_WARNING / OVR_RESTORE_CLANG_WARNING -// -// Portable wrapper for disabling GCC compiler warnings, one at a time. See example -// usage for usage by example. -// -// Example usage: -// OVR_DISABLE_CLANG_WARNING(-Wmissing-braces) // Only one warning per usage. -// OVR_DISABLE_CLANG_WARNING(-Wunused-variable) -// <code> -// OVR_RESTORE_CLANG_WARNINGS() -// OVR_RESTORE_CLANG_WARNINGS() // Must match each disable with a restore. -// -// -#if !defined(OVR_DISABLE_CLANG_WARNING) - #if defined(OVR_CC_CLANG) - #define ODCW1(x) #x - #define ODCW2(x) ODCW1(clang diagnostic ignored x) - #define ODCW3(x) ODCW2(#x) - - #define OVR_DISABLE_CLANG_WARNING(w) \ - _Pragma("clang diagnostic push") \ - _Pragma(ODCW3(w)) - #else - #define OVR_DISABLE_CLANG_WARNING(w) - #endif -#endif - -#if !defined(OVR_RESTORE_CLANG_WARNING) - #if defined(OVR_CC_CLANG) - #define OVR_RESTORE_CLANG_WARNING() \ - _Pragma("clang diagnostic pop") - #else - #define OVR_RESTORE_CLANG_WARNING() - #endif -#endif - - -// ----------------------------------------------------------------------------------- -// ***** OVR_DISABLE_MSVC_WARNING / OVR_RESTORE_MSVC_WARNING -// -// Portable wrapper for disabling VC++ compiler warnings. See example usage for usage -// by example. -// -// Example usage: -// OVR_DISABLE_MSVC_WARNING(4556 4782 4422) -// <code> -// OVR_RESTORE_MSVC_WARNING() -// -#if !defined(OVR_DISABLE_MSVC_WARNING) - #if defined(OVR_CC_MSVC) - #define OVR_DISABLE_MSVC_WARNING(w) \ - __pragma(warning(push)) \ - __pragma(warning(disable:w)) - #else - #define OVR_DISABLE_MSVC_WARNING(w) - #endif -#endif - -#if !defined(OVR_RESTORE_MSVC_WARNING) - #if defined(OVR_CC_MSVC) - #define OVR_RESTORE_MSVC_WARNING() \ - __pragma(warning(pop)) - #else - #define OVR_RESTORE_MSVC_WARNING() - #endif -#endif - - -// ----------------------------------------------------------------------------------- -// ***** OVR_DISABLE_ALL_MSVC_WARNINGS / OVR_RESTORE_ALL_MSVC_WARNINGS -// -// Portable wrapper for disabling all VC++ compiler warnings. -// OVR_RESTORE_ALL_MSVC_WARNINGS restores warnings that were disabled by -// OVR_DISABLE_ALL_MSVC_WARNINGS. Any previously enabled warnings will still be -// enabled after OVR_RESTORE_ALL_MSVC_WARNINGS. -// -// Example usage: -// OVR_DISABLE_ALL_MSVC_WARNINGS() -// <code> -// OVR_RESTORE_ALL_MSVC_WARNINGS() - -#if !defined(OVR_DISABLE_ALL_MSVC_WARNINGS) - #if defined(OVR_CC_MSVC) - #define OVR_DISABLE_ALL_MSVC_WARNINGS() \ - __pragma(warning(push, 0)) - #else - #define OVR_DISABLE_ALL_MSVC_WARNINGS() - #endif -#endif - -#if !defined(OVR_RESTORE_ALL_MSVC_WARNINGS) - #if defined(OVR_CC_MSVC) - #define OVR_RESTORE_ALL_MSVC_WARNINGS() \ - __pragma(warning(pop)) - #else - #define OVR_RESTORE_ALL_MSVC_WARNINGS() - #endif -#endif - - -//----------------------------------------------------------------------------------- -// ***** OVR_CC_HAS_FEATURE -// -// This is a portable way to use compile-time feature identification available -// with some compilers in a clean way. Direct usage of __has_feature in preprocessing -// statements of non-supporting compilers results in a preprocessing error. -// -// Example usage: -// #if OVR_CC_HAS_FEATURE(is_pod) -// if(__is_pod(T)) // If the type is plain data then we can safely memcpy it. -// memcpy(&destObject, &srcObject, sizeof(object)); -// #endif -// -#if !defined(OVR_CC_HAS_FEATURE) - #if defined(__clang__) // http://clang.llvm.org/docs/LanguageExtensions.html#id2 - #define OVR_CC_HAS_FEATURE(x) __has_feature(x) - #else - #define OVR_CC_HAS_FEATURE(x) 0 - #endif -#endif - - -//----------------------------------------------------------------------------------- -// ***** OVR_CC_HAS_BUILTIN -// -// -// This is a portable way to use compile-time builtin identification available -// with some compilers in a clean way. Direct usage of __has_builtin in preprocessing -// statements of non-supporting compilers results in a preprocessing error. -// -// Example usage: -// #if OVR_CC_HAS_BUILTIN(__builtin_trap) -// #define DEBUG_BREAK __builtin_trap -// #endif -// -#if !defined(OVR_CC_HAS_BUILTIN) - #if defined(__clang__) - #define OVR_CC_HAS_BUILTIN(x) __has_builtin(x) // http://clang.llvm.org/docs/LanguageExtensions.html#id2 - #else - #define OVR_CC_HAS_BUILTIN(x) 0 - #endif -#endif - - -//----------------------------------------------------------------------------------- -// ***** OVR_CPP11_ENABLED / OVR_CPP_CPP14_ENABLED -// -// Defined as 1 if the compiler has its available C++11 support enabled, else undefined. -// This does not mean that all of C++11 or any particular feature of C++11 is supported -// by the compiler. It means that whatever C++11 support the compiler has is enabled. -// This also includes existing and older compilers that still identify C++11 as C++0x. -// -#if !defined(OVR_CPP11_ENABLED) && defined(__cplusplus) - #if defined(__GNUC__) && defined(__GXX_EXPERIMENTAL_CXX0X__) - #define OVR_CPP11_ENABLED 1 - #elif defined(_MSC_VER) && (_MSC_VER >= 1500) // VS2010+, the first version with any significant C++11 support. - #define OVR_CPP11_ENABLED 1 - #elif (__cplusplus >= 201103L) // 201103 is the first C++11 version. - #define OVR_CPP11_ENABLED 1 - #else - // Leave undefined - #endif -#endif - -#if !defined(OVR_CPP_CPP14_ENABLED) && defined(__cplusplus) - #if defined(_MSC_VER) && (_MSC_VER >= 1800) // VS2013+, the first version with any significant C++14 support. - #define OVR_CPP_CPP14_ENABLED 1 - #elif (__cplusplus > 201103L) - #define OVR_CPP_CPP14_ENABLED 1 - #else - // Leave undefined - #endif -#endif - - -//----------------------------------------------------------------------------------- -// ***** OVR_CPP_NO_EXCEPTIONS / OVR_CPP_NO_UNWIND -// -// OVR_CPP_NO_EXCEPTIONS is defined as 1 if the compiler doesn't support C++ -// exceptions or is configured to disable support for them. Else not defined. -// If OVR_CPP_NO_EXCEPTIONS is defined then attempts to use try/catch -// related C++ statements result in a compilation error with many -// compilers. -// -// OVR_CPP_NO_UNWIND is defined as 1 if the compiler supports exceptions but -// doesn't support stack unwinding in the presence of an exception. Else not defined. -// For the Microsoft compiler, disabling exceptions means disabling stack unwinding -// and not disabling exceptions themselves. -// -// Example usage: -// void Test() { -// #if !defined(OVR_CPP_NO_EXCEPTIONS) -// try { -// #endif -// void* ptr = new Object; -// #if !defined(OVR_CPP_NO_EXCEPTIONS) -// catch(...) { ... } -// #endif - -#if !defined(OVR_CPP_NO_EXCEPTIONS) - #if defined(OVR_CPP_GNUC) && defined(_NO_EX) - #define OVR_CPP_NO_EXCEPTIONS 1 - #elif (defined(OVR_CC_GNU) || defined(OVR_CC_CLANG) || defined(OVR_CC_INTEL) || defined(OVR_CC_ARM)) && !defined(__EXCEPTIONS) - #define OVR_CPP_NO_EXCEPTIONS 1 - #elif defined(OVR_CC_MSVC) && !defined(_CPPUNWIND) - #define OVR_CPP_NO_UNWIND 1 - #endif -#endif - - -//----------------------------------------------------------------------------------- -// ***** OVR_CPP_NO_RTTI -// -// Defined as 1 if C++ run-time type information support is unavailable or disabled -// by the compiler. Else undefined. Allows you to write portable code in the face -// of the possibility that RTTI is disabled. -// -// Example usage: -// #if !OVR_CPP_NO_RTTI -// #include <typeinfo> -// int x = std::dynamic_cast<int>(3.4f); -// #endif - -#if defined(__clang__) && !OVR_CC_HAS_FEATURE(cxx_rtti) - #define OVR_CPP_NO_RTTI 1 -#elif defined(__GNUC__) && !defined(__GXX_RTTI) - #define OVR_CPP_NO_RTTI 1 -#elif defined(_MSC_VER) && !defined(_CPPRTTI) - #define OVR_CPP_NO_RTTI 1 -#elif defined(__CC_ARM) && defined(__TARGET_CPU_MPCORE) && !defined(__RTTI) - #define OVR_CPP_NO_RTTI 1 -#endif - - -//----------------------------------------------------------------------------------- -// ***** OVR_CPP_NO_STATIC_ASSERT -// -// Defined as 1 if C++ run-time type information support is available and enabled -// by the compiler. Else undefined. -// -// Example usage: -// #if OVR_CPP_NO_STATIC_ASSERT -// #define MY_ASSERT(x) { int zero = 0; switch(zero) {case 0: case (x):;} } -// #else -// #define MY_ASSERT(x) static_assert((x), #x) -// #endif - -#if !defined(OVR_CPP_NO_STATIC_ASSERT) - #if !(defined(__GNUC__) && (defined(__GXX_EXPERIMENTAL_CXX0X__) || (defined(__cplusplus) && (__cplusplus >= 201103L)))) && \ - !(defined(__clang__) && defined(__cplusplus) && OVR_CC_HAS_FEATURE(cxx_static_assert)) && \ - !(defined(_MSC_VER) && (_MSC_VER >= 1600) && defined(__cplusplus)) && /* VS2010+ */ \ - !(defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 401) && defined(OVR_CPP11_ENABLED)) /* EDG 4.1+ */ - #define OVR_CPP_NO_STATIC_ASSERT 1 - #endif -#endif - - -//----------------------------------------------------------------------------------- -// ***** OVR_CPP_NO_NULLPTR -// -// Defined as 1 if the compiler doesn't support C++11 nullptr built in type. -// Otherwise undefined. Does not identify if the standard library defines -// std::nullptr_t, as some standard libraries are further behind in standardization -// than the compilers using them (e.g. Apple clang with the supplied libstdc++). -// -// OVR_Nullptr.h provides a portable nullptr and std::nullptr_t for when the -// compiler or standard library do not. - -#if !defined(OVR_CPP_NO_NULLPTR) - #if !defined(OVR_CPP11_ENABLED) || \ - (!(defined(__clang__) && OVR_CC_HAS_FEATURE(cxx_nullptr)) /* clang */ && \ - !(defined(__GNUC__) && (OVR_CC_VERSION >= 406)) /* GCC 4.6+ */ && \ - !(defined(_MSC_VER) && (_MSC_VER >= 1600)) /* VS2010+ */ && \ - !(defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 403))) /* EDG 4.3+ */ - #define OVR_CPP_NO_NULLPTR 1 - #endif -#endif - - -//----------------------------------------------------------------------------------- -// ***** OVR_CPP_NO_RVALUE_REFERENCES -// -// Defined as 1 if the compiler doesn't support C++11 rvalue references and move semantics. -// Otherwise undefined. - -#if !defined(OVR_CPP_NO_RVALUE_REFERENCES) - #if !defined(OVR_CPP11_ENABLED) || \ - (!(defined(__clang__) && OVR_CC_HAS_FEATURE(cxx_rvalue_references)) /* clang */ && \ - !(defined(__GNUC__) && (OVR_CC_VERSION >= 405)) /* GCC 4.5+ */ && \ - !(defined(_MSC_VER) && (_MSC_VER >= 1600)) /* VS2010+ */ && \ - !(defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 403))) /* EDG 4.3+ */ - #define OVR_CPP_NO_RVALUE_REFERENCES 1 - #endif -#endif - - -//----------------------------------------------------------------------------------- -// ***** OVR_CPP_NO_AUTO -// -// Defined as 1 if the compiler doesn't support C++11 auto keyword. Otherwise undefined. - -#if !defined(OVR_CPP_NO_AUTO) - #if !defined(OVR_CPP11_ENABLED) || \ - (!(defined(__clang__) && OVR_CC_HAS_FEATURE(cxx_auto_type)) /* clang */ && \ - !(defined(__GNUC__) && (OVR_CC_VERSION >= 404)) /* GCC 4.4+ */ && \ - !(defined(_MSC_VER) && (_MSC_VER >= 1600)) /* VS2010+ */ && \ - !(defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 309))) /* EDG 3.9+ */ - #define OVR_CPP_NO_AUTO 1 - #endif -#endif - - -//----------------------------------------------------------------------------------- -// ***** OVR_CPP_NO_RANGE_BASED_FOR_LOOP -// -// Defined as 1 if the compiler doesn't support C++11 range-based for loops. -// Otherwise undefined. - -#if !defined(OVR_CPP_NO_RANGE_BASED_FOR_LOOP) - #if !defined(OVR_CPP11_ENABLED) || \ - (!(defined(__clang__) && OVR_CC_HAS_FEATURE(cxx_range_for)) /* clang */ && \ - !(defined(__GNUC__) && (OVR_CC_VERSION >= 406)) /* GCC 4.6+ */ && \ - !(defined(_MSC_VER) && (_MSC_VER >= 1700)) /* VS2012+ */ && \ - !(defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 405))) /* EDG 4.5+ */ - #define OVR_CPP_NO_RANGE_BASED_FOR_LOOP 1 - #endif -#endif - - -//----------------------------------------------------------------------------------- -// ***** OVR_CPP_NO_CONSTEXPR / OVR_CPP_NO_RELAXED_CONSTEXPR -// -// OVR_CPP_NO_CONSTEXPR is defined as 1 if the compiler doesn't support C++11 constexpr. -// OVR_CPP_NO_RELAXED_CONSTEXPR is defined as 1 if the compiler doesn't support C++14 constexpr. -// Otherwise undefined. -// See the OVR_CONSTEXPR / OVR_CONSTEXPR_OR_CONST macros for portable wrappers of this functionality. - -#if !defined(OVR_CPP_NO_CONSTEXPR) - #if !defined(OVR_CPP11_ENABLED) || \ - (!(defined(__clang__) && OVR_CC_HAS_FEATURE(cxx_constexpr)) /* clang */ && \ - !(defined(__GNUC__) && (OVR_CC_VERSION >= 406)) /* GCC 4.6+ */ && \ - !(defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 406))) /* EDG 4.6+ */ - // Not supported by VC++ through at least VS2013. - #define OVR_CPP_NO_CONSTEXPR 1 - #endif -#endif - -#if !defined(OVR_CPP_NO_RELAXED_CONSTEXPR) - #if !defined(OVR_CPP14_ENABLED) || \ - !(defined(__clang__) && OVR_CC_HAS_FEATURE(cxx_relaxed_constexpr)) /* clang */ - // Supported only by clang as of this writing. - #define OVR_CPP_NO_RELAXED_CONSTEXPR 1 - #endif -#endif - - -//----------------------------------------------------------------------------------- -// ***** OVR_CPP_NO_LAMBDA_EXPRESSIONS -// -// Defined as 1 if the compiler doesn't support C++11 lambda expressions. Otherwise undefined. -// Some compilers have slightly crippled versions of this. - -#if !defined(OVR_CPP_NO_LAMBDA_EXPRESSIONS) - #if !defined(OVR_CPP11_ENABLED) || \ - (!(defined(__clang__) && OVR_CC_HAS_FEATURE(cxx_lambdas)) /* clang */ && \ - !(defined(__GNUC__) && (OVR_CC_VERSION >= 404)) /* GCC 4.4+ */ && \ - !(defined(_MSC_VER) && (_MSC_VER >= 1600)) /* VS2010+ */ && \ - !(defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 401))) /* EDG 4.1+ */ - // Conversion of lambdas to function pointers is not supported until EDG 4.5. - #define OVR_CPP_NO_LAMBDA_EXPRESSIONS 1 - #endif -#endif - - -//----------------------------------------------------------------------------------- -// ***** OVR_CPP_NO_ALIGNOF -// -// Defined as 1 if the compiler supports C++11 alignof. Otherwise undefined. -// Some compilers support __alignof__ instead of alignof, so for portability you -// should use OVR_ALIGNOF instead of directly using C++11 alignof. - -#if !defined(OVR_CPP_NO_ALIGNOF) - #if !defined(OVR_CPP11_ENABLED) || \ - (!(defined(__clang__) && !defined(__APPLE__) && (__clang__ >= 209)) /* clang 2.9+ */ && \ - !(defined(__clang__) && defined(__APPLE__) && (__clang__ >= 300)) /* Apple clang 3.0+ */ && \ - !(defined(__GNUC__) && (OVR_CC_VERSION >= 401)) /* GCC 4.1+ */ && \ - !(defined(_MSC_VER) && (_MSC_VER >= 1900)) /* VS2014+ */ && \ - !(defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 400))) /* EDG 4.0+ */ - #define OVR_CPP_NO_ALIGNOF 1 - #endif -#endif - - -//----------------------------------------------------------------------------------- -// ***** OVR_CPP_NO_ALIGNAS -// -// Defined as 1 if the compiler supports C++11 alignas. Otherwise undefined. -// See the OVR_ALIGNAS for a portable wrapper for alignas functionality. - -#if !defined(OVR_CPP_NO_ALIGNAS) - #if !defined(OVR_CPP11_ENABLED) || \ - (!(defined(__clang__) && !defined(__APPLE__) && (__clang__ >= 300)) /* clang 3.0+ */ && \ - !(defined(__clang__) && defined(__APPLE__) && (__clang__ >= 401)) /* Apple clang 4.1+ */ && \ - !(defined(__GNUC__) && (OVR_CC_VERSION >= 408)) /* GCC 4.8+ */ && \ - !(defined(_MSC_VER) && (_MSC_VER >= 1900)) /* VS2014+ */ && \ - !(defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 408))) /* EDG 4.8+ */ - #define OVR_CPP_NO_ALIGNAS 1 - #endif -#endif - - -//----------------------------------------------------------------------------------- -// ***** OVR_CPP_NO_OVERRIDE -// -// Defined as 1 if the compiler doesn't support C++11 override. Otherwise undefined. -// See the OVR_OVERRIDE and OVR_FINALOVERRIDE macros for a portable wrapper. - -#if !defined(OOVR_CPP_NO_OVERRIDE) - #if !defined(OVR_CPP11_ENABLED) || \ - (!(defined(__clang__) && !defined(__APPLE__) && (__clang__ >= 209)) /* clang 2.9+ */ && \ - !(defined(__clang__) && defined(__APPLE__) && (__clang__ >= 400)) /* Apple clang 4.0+ */ && \ - !(defined(__GNUC__) && (OVR_CC_VERSION >= 407)) /* GCC 4.7+ */ && \ - !(defined(_MSC_VER) && (_MSC_VER >= 1500)) /* VS2008+ */ && \ - !(defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 408))) /* EDG 4.8+ */ - #define OVR_CPP_NO_OVERRIDE 1 - #endif -#endif - - -//----------------------------------------------------------------------------------- -// ***** OVR_CPP_NO_FINAL -// -// Defined as 1 if the compiler doesn't support C++11 final attribute. Otherwise undefined. -// See the OVR_FINAL and OVR_FINALOVERRIDE macros for a portable wrapper. - -#if !defined(OOVR_CPP_NO_FINAL) - #if !defined(OVR_CPP11_ENABLED) || \ - (!(defined(__clang__) && !defined(__APPLE__) && (__clang__ >= 209)) /* clang 2.9+ */ && \ - !(defined(__clang__) && defined(__APPLE__) && (__clang__ >= 400)) /* Apple clang 4.0+ */ && \ - !(defined(__GNUC__) && (OVR_CC_VERSION >= 407)) /* GCC 4.7+ */ && \ - !(defined(_MSC_VER) && (_MSC_VER >= 1500)) /* VS2008+ */ && \ - !(defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 408))) /* EDG 4.8+ */ - #define OVR_CPP_NO_FINAL 1 - #endif -#endif - - -//----------------------------------------------------------------------------------- -// ***** OVR_CPP_NO_EXTERN_TEMPLATE -// -// Defined as 1 if the compiler doesn't support C++11 extern template. -// Otherwise undefined. See OVR_EXTERN_TEMPLATE for wrapper macro. - -#if !defined(OVR_CPP_NO_EXTERN_TEMPLATE) - #if !defined(OVR_CPP11_ENABLED) || \ - (!(defined(__clang__) && !defined(__APPLE__) && (__clang__ >= 209)) /* clang 2.9+ */ && \ - !(defined(__clang__) && defined(__APPLE__) && (__clang__ >= 401)) /* Apple clang 4.1+ */ && \ - !(defined(__GNUC__) && (OVR_CC_VERSION >= 406)) /* GCC 4.6+ */ && \ - !(defined(_MSC_VER) && (_MSC_VER >= 1700)) /* VS2012+ */ && \ - !(defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 401))) /* EDG 4.1+ */ - #define OVR_CPP_NO_EXTERN_TEMPLATE 1 - #endif -#endif - - -//----------------------------------------------------------------------------------- -// ***** OVR_CPP_NO_VARIADIC_TEMPLATES -// -// Defined as 1 if the compiler doesn't support C++11 variadic templates. Otherwise undefined. - -#if !defined(OVR_CPP_NO_VARIADIC_TEMPLATES) - #if !defined(OVR_CPP11_ENABLED) || \ - (!(defined(__clang__) && OVR_CC_HAS_FEATURE(cxx_variadic_templates)) /* clang */ && \ - !(defined(__GNUC__) && (OVR_CC_VERSION >= 404)) /* GCC 4.4+ */ && \ - !(defined(_MSC_VER) && (_MSC_VER >= 1800)) /* VS2013+ */ && \ - !(defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 403))) /* EDG 4.3+ */ - #define OVR_CPP_NO_VARIADIC_TEMPLATES 1 - #endif -#endif - - -//----------------------------------------------------------------------------------- -// ***** OVR_CPP_NO_NOEXCEPT -// -// Defined as 1 if the compiler supports C++11 noexcept. Otherwise undefined. -// http://en.cppreference.com/w/cpp/language/noexcept -// See OVR_NOEXCEPT / OVR_NOEXCEPT_IF / OVR_NOEXCEPT_EXPR for a portable wrapper -// for noexcept functionality. - -#if !defined(OVR_CPP_NO_NOEXCEPT) - #if !defined(OVR_CPP11_ENABLED) || \ - (!(defined(__clang__) && OVR_CC_HAS_FEATURE(cxx_noexcept)) /* clang */ && \ - !(defined(__GNUC__) && (OVR_CC_VERSION >= 406)) /* GCC 4.6+ */ && \ - !(defined(_MSC_VER) && (_MSC_VER >= 1900)) /* VS2014+ */ && \ - !(defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 405))) /* EDG 4.5+ */ - #define OVR_CPP_NO_NOEXCEPT 1 - #endif -#endif - - -//----------------------------------------------------------------------------------- -// ***** OVR_CPP_NO_DECLTYPE -// -// Defined as 1 if the compiler doesn't support C++11 decltype. Otherwise undefined. -// Some compilers (e.g. VS2012) support most uses of decltype but don't support -// decltype with incomplete types (which is an uncommon usage seen usually in -// template metaprogramming). We don't include this support as a requirement for -// our definition of decltype support here. - -#if !defined(OVR_CPP_NO_DECLTYPE) - #if !defined(OVR_CPP11_ENABLED) || \ - (!(defined(__clang__) && OVR_CC_HAS_FEATURE(cxx_decltype)) /* clang */ && \ - !(defined(__GNUC__) && (OVR_CC_VERSION >= 403)) /* GCC 4.3+ */ && \ - !(defined(_MSC_VER) && (_MSC_VER >= 1600)) /* VS2010+ */ && \ - !(defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 402))) /* EDG 4.2+ */ - // VC++ fails to support decltype for incomplete types until VS2013. - // EDG fails to support decltype for incomplete types until v4.8. - #define OVR_CPP_NO_DECLTYPE 1 - #endif -#endif - - -//----------------------------------------------------------------------------------- -// ***** OVR_CPP_NO_DEFAULTED_FUNCTIONS -// -// Defined as 1 if the compiler doesn't support C++11 defaulted functions. Otherwise undefined. -// Some compilers have slightly crippled versions of this. - -#if !defined(OVR_CPP_NO_DEFAULTED_FUNCTIONS) - #if !defined(OVR_CPP11_ENABLED) || \ - (!(defined(__clang__) && OVR_CC_HAS_FEATURE(cxx_defaulted_functions))/* clang */ && \ - !(defined(__GNUC__) && (OVR_CC_VERSION >= 404)) /* GCC 4.4+ */ && \ - !(defined(_MSC_VER) && (_MSC_VER >= 1800)) /* VS2013+ */ && \ - !(defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 401))) /* EDG 4.1+ */ - // Up through at least VS2013 it's unsupported for defaulted move constructors and move assignment operators. - // Until EDG 4.8 it's unsupported for defaulted move constructors and move assigment operators. - #define OVR_CPP_NO_DEFAULTED_FUNCTIONS 1 - #endif -#endif - - -//----------------------------------------------------------------------------------- -// ***** OVR_CPP_NO_DELETED_FUNCTIONS -// -// Defined as 1 if the compiler doesn't support C++11 deleted functions. Otherwise undefined. -// Some compilers have slightly crippled versions of this. - -#if !defined(OVR_CPP_NO_DELETED_FUNCTIONS) - #if !defined(OVR_CPP11_ENABLED) || \ - (!(defined(__clang__) && OVR_CC_HAS_FEATURE(cxx_defaulted_functions)) /* clang */ && \ - !(defined(__GNUC__) && (OVR_CC_VERSION >= 404)) /* GCC 4.4+ */ && \ - !(defined(_MSC_VER) && (_MSC_VER >= 1800)) /* VS2013+ */ && \ - !(defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 401))) /* EDG 4.1+ */ - // Up through at least VS2013 it's unsupported for defaulted move constructors and move assignment operators. - // Until EDG 4.8 it's unsupported for defaulted move constructors and move assigment operators. - #define OVR_CPP_NO_DELETED_FUNCTIONS 1 - #endif -#endif - - -//----------------------------------------------------------------------------------- -// ***** OVR_CPP_NO_STANDARD_LAYOUT_TYPES -// -// Defined as 1 if the compiler doesn't support C++11 standard layout (relaxed POD). Otherwise undefined. -// http://en.cppreference.com/w/cpp/types/is_standard_layout - -#if !defined(OVR_CPP_NO_STANDARD_LAYOUT_TYPES) - #if !defined(OVR_CPP11_ENABLED) || \ - (!(defined(__clang__) && !defined(__APPLE__) && (__clang__ >= 300)) /* clang 3.0+ */ && \ - !(defined(__clang__) && defined(__APPLE__) && (__clang__ >= 401)) /* Apple clang 4.1+ */ && \ - !(defined(__GNUC__) && (OVR_CC_VERSION >= 405)) /* GCC 4.5+ */ && \ - !(defined(_MSC_VER) && (_MSC_VER >= 1700)) /* VS2013+ */ && \ - !(defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 406))) /* EDG 4.6+ */ - #define OVR_CPP_NO_STANDARD_LAYOUT_TYPES 1 - #endif -#endif - - -//----------------------------------------------------------------------------------- -// ***** OVR_CPP_NO_FORWARD_DECLARED_ENUMS -// -// Defined as 1 if the compiler doesn't support C++11 forward declared enums. Otherwise undefined. - -#if !defined(OVR_CPP_NO_FORWARD_DECLARED_ENUMS) - #if !defined(OVR_CPP11_ENABLED) || \ - (!(defined(__clang__) && !defined(__APPLE__) && (__clang__ >= 301)) /* clang 3.1+ */ && \ - !(defined(__clang__) && defined(__APPLE__) && (__clang__ >= 401)) /* Apple clang 4.1+ */ && \ - !(defined(__GNUC__) && (OVR_CC_VERSION >= 406)) /* GCC 4.6+ */ && \ - !(defined(_MSC_VER) && (_MSC_VER >= 1700)) /* VS2012+ */ && \ - !(defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 405))) /* EDG 4.5+ */ - #define OVR_CPP_NO_FORWARD_DECLARED_ENUMS 1 - #endif -#endif - - -//----------------------------------------------------------------------------------- -// ***** OVR_CPP_NO_STRONGLY_TYPED_ENUMS -// -// Defined as 1 if the compiler doesn't support C++11 strongly typed enums. Otherwise undefined. - -#if !defined(OVR_CPP_NO_STRONGLY_TYPED_ENUMS) - #if !defined(OVR_CPP11_ENABLED) || \ - (!(defined(__clang__) && OVR_CC_HAS_FEATURE(cxx_strong_enums)) /* clang */ && \ - !(defined(__GNUC__) && (OVR_CC_VERSION >= 404)) /* GCC 4.4+ */ && \ - !(defined(_MSC_VER) && (_MSC_VER >= 1700)) /* VS2012+ */ && \ - !(defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 400))) /* EDG 4.0+ */ - #define OVR_CPP_NO_STRONGLY_TYPED_ENUMS 1 - #endif -#endif - - -//----------------------------------------------------------------------------------- -// ***** OVR_CPP_NO_TRAILING_RETURN_TYPES -// -// Defined as 1 if the compiler doesn't support C++11 trailing return types. Otherwise undefined. -// http://en.wikipedia.org/wiki/C%2B%2B11#Alternative_function_syntax - -#if !defined(OVR_CPP_NO_TRAILING_RETURN_TYPES) - #if !defined(OVR_CPP11_ENABLED) || \ - (!(defined(__clang__) && OVR_CC_HAS_FEATURE(cxx_trailing_return)) /* clang */ && \ - !(defined(__GNUC__) && (OVR_CC_VERSION >= 404)) /* GCC 4.4+ */ && \ - !(defined(_MSC_VER) && (_MSC_VER >= 1600)) /* VS2010+ */ && \ - !(defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 401))) /* EDG 4.1+ */ - #define OVR_CPP_NO_TRAILING_RETURN_TYPES 1 - #endif -#endif - - -//----------------------------------------------------------------------------------- -// ***** OVR_CPP_NO_TEMPLATE_ALIASES -// -// Defined as 1 if the compiler doesn't support C++11 template aliases. Otherwise undefined. - -#if !defined(OVR_CPP_NO_TEMPLATE_ALIASES) - #if !defined(OVR_CPP11_ENABLED) || \ - (!(defined(__clang__) && OVR_CC_HAS_FEATURE(cxx_alias_templates)) /* clang */ && \ - !(defined(__GNUC__) && (OVR_CC_VERSION >= 407)) /* GCC 4.7+ */ && \ - !(defined(_MSC_VER) && (_MSC_VER >= 1800)) /* VS2013+ */ && \ - !(defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 402))) /* EDG 4.2+ */ - #define OVR_CPP_NO_TEMPLATE_ALIASES 1 - #endif -#endif - - -//----------------------------------------------------------------------------------- -// ***** OVR_CPP_NO_INITIALIZER_LISTS -// -// Defined as 1 if the compiler doesn't support C++11 initializer lists. Otherwise undefined. -// This refers to the compiler support for this and not the Standard Library support for std::initializer_list, -// as a new compiler with an old standard library (e.g. Apple clang with libstdc++) may not support std::initializer_list. - -#if !defined(OVR_CPP_NO_INITIALIZER_LISTS) - #if !defined(OVR_CPP11_ENABLED) || \ - (!(defined(__clang__) && OVR_CC_HAS_FEATURE(cxx_generalized_initializers)) /* clang */ && \ - !(defined(__GNUC__) && (OVR_CC_VERSION >= 404)) /* GCC 4.4+ */ && \ - !(defined(_MSC_VER) && (_MSC_VER >= 1800)) /* VS2013+ */ && \ - !(defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 405))) /* EDG 4.5+ */ - #define OVR_CPP_NO_INITIALIZER_LISTS 1 - #endif -#endif - - -//----------------------------------------------------------------------------------- -// ***** OVR_CPP_NO_NORETURN -// -// Defined as 1 if the compiler doesn't support the C++11 noreturn attribute. Otherwise undefined. -// http://en.cppreference.com/w/cpp/language/attributes -// -#if !defined(OVR_CPP_NO_NORETURN) - #if !defined(OVR_CPP11_ENABLED) || \ - (!(defined(__clang__) && !defined(__APPLE__) && (__clang__ >= 301)) /* clang 3.1+ */ && \ - !(defined(__clang__) && defined(__APPLE__) && (__clang__ >= 401)) /* Apple clang 4.1+ */ && \ - !(defined(__GNUC__) && (OVR_CC_VERSION >= 408)) /* GCC 4.8+ */ && \ - !(defined(_MSC_VER) && (_MSC_VER >= 1500)) /* VS2008+ */ && \ - !(defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 402))) /* EDG 4.2+ */ - // Supported with VC++ only via __declspec(noreturn) (see OVR_NORETURN). - #define OVR_CPP_NO_NORETURN 1 - #endif -#endif - - -//----------------------------------------------------------------------------------- -// ***** OVR_CPP_NO_NONSTATIC_MEMBER_INITIALIZERS -// -// Defined as 1 if the compiler doesn't support C++11 in-class non-static member initializers. Otherwise undefined. -// http://en.cppreference.com/w/cpp/language/data_members - -#if !defined(OVR_CPP_NO_NONSTATIC_MEMBER_INITIALIZERS) - #if !defined(OVR_CPP11_ENABLED) || \ - (!(defined(__clang__) && !defined(__APPLE__) && (__clang__ >= 301)) /* clang 3.1+ */ && \ - !(defined(__clang__) && defined(__APPLE__) && (__clang__ >= 401)) /* Apple clang 4.1+ */ && \ - !(defined(__GNUC__) && (OVR_CC_VERSION >= 407)) /* GCC 4.7+ */ && \ - !(defined(_MSC_VER) && (_MSC_VER >= 1800)) /* VS2013+ */ && \ - !(defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 406))) /* EDG 4.6+ */ - #define OVR_CPP_NO_NONSTATIC_MEMBER_INITIALIZERS 1 - #endif -#endif - - -//----------------------------------------------------------------------------------- -// ***** OVR_CPP_NO_DOUBLE_TEMPLATE_BRACKETS -// -// Defined as 1 if the compiler supports nested template declarations with >>, -// as supported by C++11. Otherwise undefined. - -#if !defined(OVR_CPP_NO_DOUBLE_TEMPLATE_ANGLE_BRACKETS) - #if !defined(OVR_CPP11_ENABLED) || \ - (!(defined(__clang__) && !defined(__APPLE__) && (__clang__ >= 209)) /* clang 2.9+ */ && \ - !(defined(__clang__) && defined(__APPLE__) && (__clang__ >= 400)) /* Apple clang 4.0+ */ && \ - !(defined(__GNUC__) && (OVR_CC_VERSION >= 403)) /* GCC 4.3+ */ && \ - !(defined(_MSC_VER) && (_MSC_VER >= 1600)) /* VS2010+ */ && \ - !(defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 401))) /* EDG 4.1+ */ - #define OVR_CPP_NO_DOUBLE_TEMPLATE_BRACKETS 1 - #endif -#endif - - - -//----------------------------------------------------------------------------------- -// ***** OVR_CPP_NO_INHERITING_CONSTRUCTORS -// -// Defined as 1 if the compiler supports C++11 inheriting constructors. Otherwise undefined. -// Example usage: -// struct A { explicit A(int x){} }; -// struct B : public A { using A::A; }; // As if B redeclared A::A(int). - -#if !defined(OVR_CPP_NO_INHERITING_CONSTRUCTORS) - #if !defined(OVR_CPP11_ENABLED) || \ - (!(defined(__clang__) && OVR_CC_HAS_FEATURE(cxx_inheriting_constructors)) /* clang */ && \ - !(defined(__GNUC__) && (OVR_CC_VERSION >= 408)) /* GCC 4.8+ */ && \ - !(defined(_MSC_VER) && (_MSC_VER >= 1900)) /* VS2014+ */ && \ - !(defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 408))) /* EDG 4.8+ */ - #define OVR_CPP_NO_INHERITING_CONSTRUCTORS 1 - #endif -#endif - - -//----------------------------------------------------------------------------------- -// ***** OVR_CPP_NO_DELEGATING_CONSTRUCTORS -// -// Defined as 1 if the compiler supports C++11 delegating constructors. Otherwise undefined. - -#if !defined(OVR_CPP_NO_DELEGATING_CONSTRUCTORS) - #if !defined(OVR_CPP11_ENABLED) || \ - (!(defined(__clang__) && !defined(__APPLE__) && (__clang__ >= 300)) /* clang 3.0+ */ && \ - !(defined(__clang__) && defined(__APPLE__) && (__clang__ >= 401)) /* Apple clang 4.1+ */ && \ - !(defined(__GNUC__) && (OVR_CC_VERSION >= 407)) /* GCC 4.7+ */ && \ - !(defined(_MSC_VER) && (_MSC_VER >= 1800)) /* VS2013+ */ && \ - !(defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 407))) /* EDG 4.7+ */ - #define OVR_CPP_NO_DELEGATING_CONSTRUCTORS 1 - #endif -#endif - - -//----------------------------------------------------------------------------------- -// ***** OVR_CPP_NO_FUNCTION_TEMPLATE_DEFAULT_ARGS -// -// Defined as 1 if the compiler supports C++11 function template default arguments. Otherwise undefined. - -#if !defined(OVR_CPP_NO_FUNCTION_TEMPLATE_DEFAULT_ARGS) - #if !defined(OVR_CPP11_ENABLED) || \ - (!(defined(__clang__) && !defined(__APPLE__) && (__clang__ >= 209)) /* clang 2.9+ */ && \ - !(defined(__clang__) && defined(__APPLE__) && (__clang__ >= 401)) /* Apple clang 4.0+ */ && \ - !(defined(__GNUC__) && (OVR_CC_VERSION >= 403)) /* GCC 4.3+ */ && \ - !(defined(_MSC_VER) && (_MSC_VER >= 1800)) /* VS2013+ */ && \ - !(defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 403))) /* EDG 4.3+ */ - #define OVR_CPP_NO_FUNCTION_TEMPLATE_DEFAULT_ARGS 1 - #endif -#endif - - -//----------------------------------------------------------------------------------- -// ***** OVR_CPP_NO_UNRESTRICTED_UNIONS -// -// Defined as 1 if the compiler supports C++11 unrestricted unions. Otherwise undefined. - -#if !defined(OVR_CPP_NO_UNRESTRICTED_UNIONS) - #if !defined(OVR_CPP11_ENABLED) || \ - (!(defined(__clang__) && !defined(__APPLE__) && (__clang__ >= 301)) /* clang 3.1+ */ && \ - !(defined(__clang__) && defined(__APPLE__) && (__clang__ >= 401)) /* Apple clang 4.1+ */ && \ - !(defined(__GNUC__) && (OVR_CC_VERSION >= 406)) /* GCC 4.6+ */ && \ - !(defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 406))) /* EDG 4.6+ */ - // Not supported by VC++ as of VS2013. - #define OVR_CPP_NO_UNRESTRICTED_UNIONS 1 - #endif -#endif - - - -//----------------------------------------------------------------------------------- -// ***** OVR_CPP_NO_EXTENDED_SIZEOF -// -// Defined as 1 if the compiler supports C++11 class sizeof extensions (e.g. sizeof SomeClass::someMember). -// Otherwise undefined. - -#if !defined(OVR_CPP_NO_EXTENDED_SIZEOF) - #if !defined(OVR_CPP11_ENABLED) || \ - (!(defined(__clang__) && !defined(__APPLE__) && (__clang__ >= 301)) /* clang 3.1+ */ && \ - !(defined(__clang__) && defined(__APPLE__) && (__clang__ >= 401)) /* Apple clang 4.1+ */ && \ - !(defined(__GNUC__) && (OVR_CC_VERSION >= 405)) /* GCC 4.5+ */ && \ - !(defined(_MSC_VER) && (_MSC_VER >= 1900)) /* VS2014+ */ && \ - !(defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 405))) /* EDG 4.5+ */ - #define OVR_CPP_NO_EXTENDED_SIZEOF 1 - #endif -#endif - - -//----------------------------------------------------------------------------------- -// ***** OVR_CPP_NO_INLINE_NAMESPACES -// -// Defined as 1 if the compiler supports C++11 inlined namespaces. Otherwise undefined. -// http://en.cppreference.com/w/cpp/language/namespace#Inline_namespaces - -#if !defined(OVR_CPP_NO_INLINE_NAMESPACES) - #if !defined(OVR_CPP11_ENABLED) || \ - (!(defined(__clang__) && !defined(__APPLE__) && (__clang__ >= 209)) /* clang 2.9+ */ && \ - !(defined(__clang__) && defined(__APPLE__) && (__clang__ >= 400)) /* Apple clang 4.0+ */ && \ - !(defined(__GNUC__) && (OVR_CC_VERSION >= 404)) /* GCC 4.4+ */ && \ - !(defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 405))) /* EDG 4.5+ */ - // Not supported by VC++ as of VS2013. - #define OVR_CPP_NO_INLINE_NAMESPACES 1 - #endif -#endif - - -//----------------------------------------------------------------------------------- -// ***** OVR_CPP_NO_EXPLICIT_CONVERSION_OPERATORS -// -// Defined as 1 if the compiler supports C++11 explicit conversion operators. Otherwise undefined. -// http://en.cppreference.com/w/cpp/language/explicit - -#if !defined(OVR_CPP_NO_EXPLICIT_CONVERSION_OPERATORS) - #if !defined(OVR_CPP11_ENABLED) || \ - (!(defined(__clang__) && OVR_CC_HAS_FEATURE(cxx_explicit_conversions)) /* clang */ && \ - !(defined(__GNUC__) && (OVR_CC_VERSION >= 405)) /* GCC 4.5+ */ && \ - !(defined(_MSC_VER) && (_MSC_VER >= 1800)) /* VS2013+ */ && \ - !(defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 404))) /* EDG 4.4+ */ - #define OVR_CPP_NO_EXPLICIT_CONVERSION_OPERATORS 1 - #endif -#endif - - -//----------------------------------------------------------------------------------- -// ***** OVR_CPP_NO_LOCAL_CLASS_TEMPLATE_PARAMETERS -// -// Defined as 1 if the compiler supports C++11 local class template parameters. Otherwise undefined. -// Example: -// void Test() { -// struct LocalClass{ }; -// SomeTemplateClass<LocalClass> t; // Allowed only in C++11 -// } - -#if !defined(OVR_CPP_NO_LOCAL_CLASS_TEMPLATE_PARAMETERS) - #if !defined(OVR_CPP11_ENABLED) || \ - (!(defined(__clang__) && OVR_CC_HAS_FEATURE(cxx_local_type_template_args)) /* clang */ && \ - !(defined(__GNUC__) && (OVR_CC_VERSION >= 405)) /* GCC 4.5+ */ && \ - !(defined(_MSC_VER) && (_MSC_VER >= 1600)) /* VS2010+ */ && \ - !(defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 402))) /* EDG 4.2+ */ - #define OVR_CPP_NO_LOCAL_CLASS_TEMPLATE_PARAMETERS 1 - #endif -#endif - - -//----------------------------------------------------------------------------------- -// ***** OVR_CPP_NO_NEW_CHARACTER_TYPES -// -// Defined as 1 if the compiler natively supports C++11 char16_t and char32_t. Otherwise undefined. -// VC++ through at least VS2013 defines char16_t as unsigned short in its standard library, -// but it is not a native type or unique type, nor can you for a string literal with it. - -#if !defined(OVR_CPP_NO_NEW_CHARACTER_TYPES) - #if !defined(OVR_CPP11_ENABLED) || \ - (!(defined(__clang__) && OVR_CC_HAS_FEATURE(cxx_unicode_literals)) /* clang */ && \ - !(defined(__GNUC__) && (OVR_CC_VERSION >= 404)) /* GCC 4.4+ */ && \ - !(defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 407))) /* EDG 4.7+ */ - // Not supported by VC++ as of VS2013. - #define OVR_CPP_NO_NEW_CHARACTER_TYPES 1 - #endif -#endif - - -//----------------------------------------------------------------------------------- -// ***** OVR_CPP_NO_UNICODE_CHAR_NAME_LITERALS -// -// Defined as 1 if the compiler supports C++11 \u and \U character literals for -// native char16_t and char32_t types. -// -#if !defined(OVR_CPP_NO_UNICODE_CHAR_NAME_LITERALS) - #if !defined(OVR_CPP11_ENABLED) || \ - (!(defined(__clang__) && !defined(__APPLE__) && (__clang__ >= 301)) /* clang 3.1+ */ && \ - !(defined(__clang__) && defined(__APPLE__) && (__clang__ >= 401)) /* Apple clang 4.1+ */ && \ - !(defined(__GNUC__) && (OVR_CC_VERSION >= 405)) /* GCC 4.5+ */ && \ - !(defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 408))) /* EDG 4.8+ */ - // Not supported by VC++ as of VS2013. VC++'s existing \U and \u are non-conforming. - #define OVR_CPP_NO_UNICODE_CHAR_NAME_LITERALS 1 - #endif -#endif - - -//----------------------------------------------------------------------------------- -// ***** OVR_CPP_NO_USER_DEFINED_LITERALS -// -// Defined as 1 if the compiler supports C++11 user-defined literals. Otherwise undefined. - -#if !defined(OVR_CPP_NO_USER_DEFINED_LITERALS) - #if !defined(OVR_CPP11_ENABLED) || \ - (!(defined(__clang__) && !defined(__APPLE__) && (__clang__ >= 301)) /* clang 3.1+ */ && \ - !(defined(__clang__) && defined(__APPLE__) && (__clang__ >= 401)) /* Apple clang 4.1+ */ && \ - !(defined(__GNUC__) && (OVR_CC_VERSION >= 407)) /* GCC 4.7+ */ && \ - !(defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 408))) /* EDG 4.8+ */ - // Not supported by VC++ as of VS2013. - #define OVR_CPP_NO_USER_DEFINED_LITERALS 1 - #endif -#endif - - -//----------------------------------------------------------------------------------- -// ***** OVR_CPP_NO_UNICODE_STRING_LITERALS -// -// Defined as 1 if the compiler supports C++11 Unicode string literals. Otherwise undefined. -// http://en.wikipedia.org/wiki/C%2B%2B11#New_string_literals - -#if !defined(OVR_CPP_NO_UNICODE_STRING_LITERALS) - #if !defined(OVR_CPP11_ENABLED) || \ - (!(defined(__clang__) && OVR_CC_HAS_FEATURE(cxx_unicode_literals)) /* clang */ && \ - !(defined(__GNUC__) && (OVR_CC_VERSION >= 404)) /* GCC 4.4+ */ && \ - !(defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 407))) /* EDG 4.7+ */ - // Not supported by VC++ as of VS2013. - #define OVR_CPP_NO_UNICODE_STRING_LITERALS 1 - #endif -#endif - - -//----------------------------------------------------------------------------------- -// ***** OVR_CPP_NO_RAW_STRING_LITERALS -// -// Defined as 1 if the compiler supports C++11 raw literals. Otherwise undefined. -// http://en.wikipedia.org/wiki/C%2B%2B11#New_string_literals - -#if !defined(OVR_CPP_NO_RAW_STRING_LITERALS) - #if !defined(OVR_CPP11_ENABLED) || \ - (!(defined(__clang__) && OVR_CC_HAS_FEATURE(cxx_raw_string_literals)) /* clang */ && \ - !(defined(__GNUC__) && (OVR_CC_VERSION >= 405)) /* GCC 4.5+ */ && \ - !(defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 407))) /* EDG 4.7+ */ - // Not supported by VC++ as of VS2013. - #define OVR_CPP_NO_RAW_STRING_LITERALS 1 - #endif -#endif - - -//----------------------------------------------------------------------------------- -// ***** OVR_CPP_NO_UNIFIED_INITIALIZATION_SYNTAX -// -// Defined as 1 if the compiler supports C++11 unified initialization. -// http://en.wikipedia.org/wiki/C%2B%2B11#Uniform_initialization - -#if !defined(OVR_CPP_NO_UNIFIED_INITIALIZATION_SYNTAX) - #if !defined(OVR_CPP11_ENABLED) || \ - (!(defined(__clang__) && OVR_CC_HAS_FEATURE(cxx_generalized_initializers)) /* clang */ && \ - !(defined(__GNUC__) && (OVR_CC_VERSION >= 404)) /* GCC 4.4+ */ && \ - !(defined(_MSC_VER) && (_MSC_VER >= 1800)) /* VS2013+ */ && \ - !(defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 406))) /* EDG 4.6+ */ - #define OVR_CPP_NO_UNIFIED_INITIALIZATION_SYNTAX 1 - #endif -#endif - - -//----------------------------------------------------------------------------------- -// ***** OVR_CPP_NO_EXTENDED_FRIEND_DECLARATIONS -// -// Defined as 1 if the compiler supports C++11 extended friends. - -#if !defined(OVR_CPP_NO_EXTENDED_FRIEND_DECLARATIONS) - #if !defined(OVR_CPP11_ENABLED) || \ - (!(defined(__clang__) && !defined(__APPLE__) && (__clang__ >= 209)) /* clang 2.9+ */ && \ - !(defined(__clang__) && defined(__APPLE__) && (__clang__ >= 400)) /* Apple clang 4.0+ */ && \ - !(defined(__GNUC__) && (OVR_CC_VERSION >= 407)) /* GCC 4.7+ */ && \ - !(defined(_MSC_VER) && (_MSC_VER >= 1600)) /* VS2010+ */ && \ - !(defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 401))) /* EDG 4.1+ */ - #define OVR_CPP_NO_EXTENDED_FRIEND_DECLARATIONS 1 - #endif -#endif - - -//----------------------------------------------------------------------------------- -// ***** OVR_CPP_NO_THREAD_LOCAL -// -// Defined as 1 if the compiler supports C++11 thread_local. Else undefined. Does not -// indicate if the compiler supports C thread-local compiler extensions such as __thread -// and declspec(thread). Use OVR_THREAD_LOCAL if you want to declare a thread-local -// variable that supports C++11 thread_local when available but the C extension when -// it's available. The primary difference between C++11 thread_local and C extensions is -// that C++11 thread_local supports non-PODs and calls their constructors and destructors. -// -// Note that thread_local requires both compiler and linker support, and so it's possible -// that the compiler may support thread_local but the linker does not. - -#if !defined(OVR_CPP_NO_THREAD_LOCAL) - #if !defined(OVR_CPP11_ENABLED) || \ - (!(defined(__clang__) && OVR_CC_HAS_FEATURE(cxx_thread_local)) /* clang */ && \ - !(defined(__GNUC__) && (OVR_CC_VERSION >= 408)) /* GCC 4.8+ */ && \ - !(defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 408))) /* EDG 4.8+ */ - #define OVR_CPP_NO_THREAD_LOCAL 1 - #endif -#endif - - -// ----------------------------------------------------------------------------------- -// ***** OVR_ALIGNAS / OVR_ALIGNOF -// -// OVR_ALIGNAS(n) // Specifies a size_t power of two alignment for a type or instance. -// OVR_ALIGNOF(type) // Returns the size_t alignment of a type or instance. -// -// Example usage: -// OVR_ALIGNAS(8) char c = 'c'; // Specifies that the instance c be aligned to an 8 byte boundary. -// typedef OVR_ALIGNAS(8) char C; // Specifies that the type C be aligned to an 8 byte boundary. -// struct OVR_ALIGNAS(64) S{ char array[16]; }; // Specfies that the struct S have a natural alignment of 64. -// OVR_ALIGNAS(32) S s; // Specifies that the instance s of struct S be aligned to an 32 byte boundary. -// OVR_ALIGNAS(32) struct T{ char array[16]; } t; // Specfies that the instance t of struct T have a natural alignment of 32. -// struct OVR_ALIGNAS(T) U{}; // Specifes that U be aligned the same as T. Supported only by C++11 compilers (see OVR_CPP_NO_ALIGNAS). -// -// size_t a = OVR_ALIGNOF(double); // Returns the natural alignment of the double type. -// size_t a = OVR_ALIGNOF(S); // Returns the natural alignment of the struct S type. -// -// Note: If C++11 alignas is supported, then alignas/OVR_ALIGNAS may take a const expression in addition to a constant. -// Note: The C11 Standard species the _Alignas keyword and alignas as a macro for it in <stdalign.h> - -#if !defined(OVR_ALIGNAS) - #if defined(OVR_CC_GNU) && !defined(OVR_CPP_NO_ALIGNAS) // If C++11 alignas is supported... - #define OVR_ALIGNAS(n) alignas(n) - #elif defined(__clang__) && !defined(OVR_CPP_NO_ALIGNAS) - #define OVR_ALIGNAS(n) alignas(n) - #elif defined(OVR_CC_GNU) || defined(__clang__) - #define OVR_ALIGNAS(n) __attribute__((aligned(n))) - #elif defined(OVR_CC_MSVC) || defined(OVR_CC_INTEL) - #define OVR_ALIGNAS(n) __declspec(align(n)) // For Microsoft the alignment must be a literal integer. - #elif defined(OVR_CC_ARM) - #define OVR_ALIGNAS(n) __align(n) - #else - #error Need to define OVR_ALIGNAS - #endif -#endif - -#if !defined(OVR_ALIGNOF) - #if defined(OVR_CC_GNU) && !defined(OVR_CPP_NO_ALIGNOF) // If C++11 alignof is supported... - #define OVR_ALIGNOF(type) alignof(type) - #elif defined(__clang__) && !defined(OVR_CPP_NO_ALIGNOF) - #define OVR_ALIGNOF(type) alignof(type) - #elif defined(OVR_CC_GNU) || defined(__clang__) - #define OVR_ALIGNOF(type) ((size_t)__alignof__(type)) - #elif defined(OVR_CC_MSVC) || defined(OVR_CC_INTEL) - #define OVR_ALIGNOF(type) ((size_t)__alignof(type)) - #elif defined(OVR_CC_ARM) - #define OVR_ALIGNOF(type) ((size_t)__ALIGNOF__(type)) - #else - #error Need to define OVR_ALIGNOF - #endif -#endif - - -// ----------------------------------------------------------------------------------- -// ***** OVR_ASSUME / OVR_ANALYSIS_ASSUME -// -// This is a portable wrapper for VC++'s __assume and __analysis_assume. -// __analysis_assume is typically used to quell VC++ static analysis warnings. -// -// Example usage: -// void Test(char c){ -// switch(c){ -// case 'a': -// case 'b': -// case 'c': -// case 'd': -// break; -// default: -// OVR_ASSUME(0); // Unreachable code. -// } -// } -// -// size_t Test(char* str){ -// OVR_ANALYSIS_ASSUME(str != nullptr); -// return strlen(str); -// } - -#if !defined(OVR_ASSUME) - #if defined(OVR_CC_MSVC) - #define OVR_ASSUME(x) __assume(x) - #define OVR_ANALYSIS_ASSUME(x) __analysis_assume(!!(x)) - #else - #define OVR_ASSUME(x) - #define OVR_ANALYSIS_ASSUME(x) - #endif -#endif - - -// ----------------------------------------------------------------------------------- -// ***** OVR_RESTRICT -// -// Wraps the C99 restrict keyword in a portable way. -// C++11 and C++14 don't have restrict but this functionality is supported by -// all C++ compilers. -// -// Example usage: -// void* memcpy(void* OVR_RESTRICT s1, const void* OVR_RESTRICT s2, size_t n); - -#if !defined(OVR_RESTRICT) - #define OVR_RESTRICT __restrict // Currently supported by all compilers of significance to us. -#endif - - -// ----------------------------------------------------------------------------------- -// ***** OVR_NOEXCEPT / OVR_NOEXCEPT_IF(predicate) / OVR_NOEXCEPT_EXPR(expression) -// -// Implements a portable wrapper for C++11 noexcept. -// http://en.cppreference.com/w/cpp/language/noexcept -// -// Example usage: -// void Test() OVR_NOEXCEPT {} // This function doesn't throw. -// -// template <typename T> -// void DoNothing() OVR_NOEXCEPT_IF(OVR_NOEXCEPT_EXPR(T())) // Throws an if and only if T::T(int) throws. -// { T t(3); } -// -#if !defined(OVR_NOEXCEPT) - #if defined(OVR_CPP_NOEXCEPT) - #define OVR_NOEXCEPT - #define OVR_NOEXCEPT_IF(predicate) - #define OVR_NOEXCEPT_EXPR(expression) false - #else - #define OVR_NOEXCEPT noexcept - #define OVR_NOEXCEPT_IF(predicate) noexcept((predicate)) - #define OVR_NOEXCEPT_EXPR(expression) noexcept((expression)) - #endif -#endif - - -// ----------------------------------------------------------------------------------- -// ***** OVR_FINAL -// -// Wraps the C++11 final keyword in a portable way. -// http://en.cppreference.com/w/cpp/language/final -// -// Example usage: -// struct Test { virtual int GetValue() OVR_FINAL; }; - -#if !defined(OVR_FINAL) - #if defined(OVR_CC_MSVC) && (OVR_CC_VERSION < 1700) // VC++ 2012 and earlier - #define OVR_FINAL sealed - #elif defined(OVR_CPP_INHERITANCE_FINAL) - #define OVR_FINAL - #else - #define OVR_FINAL final - #endif -#endif - - -// ----------------------------------------------------------------------------------- -// ***** OVR_OVERRIDE -// -// Wraps the C++11 override keyword in a portable way. -// http://en.cppreference.com/w/cpp/language/override -// -// Example usage: -// struct Parent { virtual void Func(int); }; -// struct Child : public Parent { void Func(int) OVR_OVERRIDE; }; - -#if !defined(OVR_CPP11_ENABLED) -#define OVR_OVERRIDE -#elif !defined(OVR_OVERRIDE) - #if defined(OVR_CPP_OVERRIDE) - #define OVR_OVERRIDE - #else - #if (defined(_MSC_VER) && (_MSC_VER <= 1600)) - #pragma warning(disable : 4481) - #endif - #define OVR_OVERRIDE override - #endif -#endif - - -// ----------------------------------------------------------------------------------- -// ***** OVR_FINAL_OVERRIDE -// -// Wraps the C++11 final+override keywords (a common combination) in a portable way. -// -// Example usage: -// struct Parent { virtual void Func(); }; -// struct Child : public Parent { virtual void Func() OVR_FINAL_OVERRIDE; }; - -#if !defined(OVR_FINAL_OVERRIDE) - #define OVR_FINAL_OVERRIDE OVR_FINAL OVR_OVERRIDE -#endif - - -// ----------------------------------------------------------------------------------- -// ***** OVR_EXTERN_TEMPLATE -// -// Portable wrapper for C++11 extern template. This tells the compiler to not instantiate -// the template in the current translation unit, which can significantly speed up -// compilation and avoid problems due to two translation units compiling code with -// different settings. -// -// Example usage: -// OVR_EXTERN_TEMPLATE(class basic_string<char>); // Nothing to do for non-C++11 compilers. - -#if !defined(OVR_EXTERN_TEMPLATE) - #if defined(OVR_CPP_EXTERN_TEMPLATE) - #define OVR_EXTERN_TEMPLATE(decl) - #else - #define OVR_EXTERN_TEMPLATE(decl) extern template decl - #endif -#endif - - -// ----------------------------------------------------------------------------------- -// ***** OVR_CONSTEXPR / OVR_CONSTEXPR_OR_CONST -// -// Portable wrapper for C++11 constexpr. Doesn't include C++14 relaxed constexpr, -// for which a different wrapper name is reserved. -// -// Example usage: -// OVR_CONSTEXPR int Test() { return 15; } // This can be optimized better by a C++11 compiler that supports constexpr. -// OVR_CONSTEXPR_OR_CONST float x = 3.14159f; // This can be optimized better by a C++11 compiler, but if not then at least make it const. - -#if !defined(OVR_CONSTEXPR) - #if defined(OVR_CPP_NO_CONSTEXPR) - #define OVR_CONSTEXPR - #else - #define OVR_CONSTEXPR constexpr - #endif -#endif - -#if !defined(OVR_CONSTEXPR_OR_CONST) - #if defined(OVR_CPP_NO_CONSTEXPR) - #define OVR_CONSTEXPR_OR_CONST const - #else - #define OVR_CONSTEXPR_OR_CONST constexpr - #endif -#endif - - - -// ----------------------------------------------------------------------------------- -// ***** OVR_FUNCTION_DELETE / OVR_FUNCTION_DEFAULT -// -// Wraps the C++11 delete and default keywords in a way that allows for cleaner code -// while making for a better version of uncallable or default functions. -// -// Example usage: -// struct Test{ -// Test() OVR_FUNCTION_DEFAULT; // Non-C++11 compilers will require a separate definition for Test(). -// private: // Users should put OVR_FUNCTION_DELETE usage in a private -// void Uncallable() OVR_FUNCTION_DELETE; // area for compatibility with pre-C++11 compilers. -// }; - -#if defined(OVR_CPP_NO_DELETED_FUNCTIONS) - #define OVR_FUNCTION_DELETE -#else - #define OVR_FUNCTION_DELETE = delete -#endif - -#if defined(OVR_CPP_NO_DEFAULTED_FUNCTIONS) - #define OVR_FUNCTION_DEFAULT -#else - #define OVR_FUNCTION_DEFAULT = default -#endif - - - -// ----------------------------------------------------------------------------------- -// ***** OVR_NON_COPYABLE -// -// Allows you to specify a class as being neither copy-constructible nor assignable, -// which is a commonly needed pattern in C++ programming. Classes with this declaration -// are required to be default constructible (as are most classes). For pre-C++11 -// compilers this macro declares a private section for the class, which will be -// inherited by whatever code is directly below the macro invocation by default. -// -// Example usage: -// struct Test { -// Test(); -// ... -// OVR_NON_COPYABLE(Test) -// }; - -#if !defined(OVR_NON_COPYABLE) - #if defined(OVR_CPP_NO_DELETED_FUNCTIONS) - #define OVR_NON_COPYABLE(Type) \ - private: \ - Type(const Type&); \ - void operator=(const Type&); - #else - #define OVR_NON_COPYABLE(Type) \ - Type(const Type&) = delete; \ - void operator=(const Type&) = delete; - #endif -#endif - - - -#endif // header include guard - - - - diff --git a/LibOVR/Src/Kernel/OVR_ContainerAllocator.h b/LibOVR/Src/Kernel/OVR_ContainerAllocator.h deleted file mode 100644 index 46bea2e..0000000 --- a/LibOVR/Src/Kernel/OVR_ContainerAllocator.h +++ /dev/null @@ -1,267 +0,0 @@ -/************************************************************************************ - -PublicHeader: OVR_Kernel.h -Filename : OVR_ContainerAllocator.h -Content : Template allocators and constructors for containers. -Created : September 19, 2012 -Notes : - -Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); -you may not use the Oculus VR Rift SDK except in compliance with the License, -which is provided at the time of installation or download, or which -otherwise accompanies this software in either electronic or hard copy form. - -You may obtain a copy of the License at - -http://www.oculusvr.com/licenses/LICENSE-3.2 - -Unless required by applicable law or agreed to in writing, the Oculus VR SDK -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -************************************************************************************/ - -#ifndef OVR_ContainerAllocator_h -#define OVR_ContainerAllocator_h - -#include "OVR_Allocator.h" -#include <string.h> - - -namespace OVR { - - -//----------------------------------------------------------------------------------- -// ***** Container Allocator - -// ContainerAllocator serves as a template argument for allocations done by -// containers, such as Array and Hash; replacing it could allow allocator -// substitution in containers. - -class ContainerAllocatorBase -{ -public: - static void* Alloc(size_t size) { return OVR_ALLOC(size); } - static void* Realloc(void* p, size_t newSize) { return OVR_REALLOC(p, newSize); } - static void Free(void *p) { OVR_FREE(p); } -}; - - - -//----------------------------------------------------------------------------------- -// ***** Constructors, Destructors, Copiers - -// Plain Old Data - movable, no special constructors/destructor. -template<class T> -class ConstructorPOD -{ -public: - static void Construct(void *) {} - static void Construct(void *p, const T& source) - { - *(T*)p = source; - } - - // Same as above, but allows for a different type of constructor. - template <class S> - static void ConstructAlt(void *p, const S& source) - { - *(T*)p = source; - } - - static void ConstructArray(void*, size_t) {} - - static void ConstructArray(void* p, size_t count, const T& source) - { - uint8_t *pdata = (uint8_t*)p; - for (size_t i=0; i< count; ++i, pdata += sizeof(T)) - *(T*)pdata = source; - } - - static void ConstructArray(void* p, size_t count, const T* psource) - { - memcpy(p, psource, sizeof(T) * count); - } - - static void Destruct(T*) {} - static void DestructArray(T*, size_t) {} - - static void CopyArrayForward(T* dst, const T* src, size_t count) - { - memmove(dst, src, count * sizeof(T)); - } - - static void CopyArrayBackward(T* dst, const T* src, size_t count) - { - memmove(dst, src, count * sizeof(T)); - } - - static bool IsMovable() { return true; } -}; - - -//----------------------------------------------------------------------------------- -// ***** ConstructorMov -// -// Correct C++ construction and destruction for movable objects -template<class T> -class ConstructorMov -{ -public: - static void Construct(void* p) - { - OVR::Construct<T>(p); - } - - static void Construct(void* p, const T& source) - { - OVR::Construct<T>(p, source); - } - - // Same as above, but allows for a different type of constructor. - template <class S> - static void ConstructAlt(void* p, const S& source) - { - OVR::ConstructAlt<T,S>(p, source); - } - - static void ConstructArray(void* p, size_t count) - { - uint8_t* pdata = (uint8_t*)p; - for (size_t i=0; i< count; ++i, pdata += sizeof(T)) - Construct(pdata); - } - - static void ConstructArray(void* p, size_t count, const T& source) - { - uint8_t* pdata = (uint8_t*)p; - for (size_t i=0; i< count; ++i, pdata += sizeof(T)) - Construct(pdata, source); - } - - static void ConstructArray(void* p, size_t count, const T* psource) - { - uint8_t* pdata = (uint8_t*)p; - for (size_t i=0; i< count; ++i, pdata += sizeof(T)) - Construct(pdata, *psource++); - } - - static void Destruct(T* p) - { - p->~T(); - OVR_UNUSED(p); // Suppress silly MSVC warning - } - - static void DestructArray(T* p, size_t count) - { - p += count - 1; - for (size_t i=0; i<count; ++i, --p) - p->~T(); - } - - static void CopyArrayForward(T* dst, const T* src, size_t count) - { - memmove(dst, src, count * sizeof(T)); - } - - static void CopyArrayBackward(T* dst, const T* src, size_t count) - { - memmove(dst, src, count * sizeof(T)); - } - - static bool IsMovable() { return true; } -}; - - -//----------------------------------------------------------------------------------- -// ***** ConstructorCPP -// -// Correct C++ construction and destruction for movable objects -template<class T> -class ConstructorCPP -{ -public: - static void Construct(void* p) - { - OVR::Construct<T>(p); - } - - static void Construct(void* p, const T& source) - { - OVR::Construct<T>(p, source); - } - - // Same as above, but allows for a different type of constructor. - template <class S> - static void ConstructAlt(void* p, const S& source) - { - OVR::ConstructAlt<T,S>(p, source); - } - - static void ConstructArray(void* p, size_t count) - { - uint8_t* pdata = (uint8_t*)p; - for (size_t i=0; i< count; ++i, pdata += sizeof(T)) - Construct(pdata); - } - - static void ConstructArray(void* p, size_t count, const T& source) - { - uint8_t* pdata = (uint8_t*)p; - for (size_t i=0; i< count; ++i, pdata += sizeof(T)) - Construct(pdata, source); - } - - static void ConstructArray(void* p, size_t count, const T* psource) - { - uint8_t* pdata = (uint8_t*)p; - for (size_t i=0; i< count; ++i, pdata += sizeof(T)) - Construct(pdata, *psource++); - } - - static void Destruct(T* p) - { - p->~T(); - OVR_UNUSED(p); // Suppress silly MSVC warning - } - - static void DestructArray(T* p, size_t count) - { - p += count - 1; - for (size_t i=0; i<count; ++i, --p) - p->~T(); - } - - static void CopyArrayForward(T* dst, const T* src, size_t count) - { - for(size_t i = 0; i < count; ++i) - dst[i] = src[i]; - } - - static void CopyArrayBackward(T* dst, const T* src, size_t count) - { - for(size_t i = count; i; --i) - dst[i-1] = src[i-1]; - } - - static bool IsMovable() { return false; } -}; - - -//----------------------------------------------------------------------------------- -// ***** Container Allocator with movement policy -// -// Simple wraps as specialized allocators -template<class T> struct ContainerAllocator_POD : ContainerAllocatorBase, ConstructorPOD<T> {}; -template<class T> struct ContainerAllocator : ContainerAllocatorBase, ConstructorMov<T> {}; -template<class T> struct ContainerAllocator_CPP : ContainerAllocatorBase, ConstructorCPP<T> {}; - - -} // OVR - - -#endif diff --git a/LibOVR/Src/Kernel/OVR_DebugHelp.cpp b/LibOVR/Src/Kernel/OVR_DebugHelp.cpp deleted file mode 100644 index fe7b54f..0000000 --- a/LibOVR/Src/Kernel/OVR_DebugHelp.cpp +++ /dev/null @@ -1,3926 +0,0 @@ -/************************************************************************************ - -Filename : ExceptionHandler.cpp -Content : Platform-independent exception handling interface -Created : October 6, 2014 - -Copyright : Copyright 2014 Oculus VR, LLC. All Rights reserved. - -Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -************************************************************************************/ - - -#include "OVR_DebugHelp.h" -#include "OVR_Types.h" -#include "OVR_UTF8Util.h" -#include "../OVR_CAPI.h" -#include "../OVR_CAPI_Keys.h" -#include "../CAPI/CAPI_HMDState.h" -#include <stdlib.h> - -#if defined(OVR_OS_WIN32) || defined(OVR_OS_WIN64) - #pragma warning(push, 0) - #include <Windows.h> - #include <WinNT.h> - #include <DbgHelp.h> - #include <WinVer.h> - #include <share.h> - #include <Psapi.h> - #include <TlHelp32.h> - #include <comutil.h> - #include <Wbemcli.h> - #include <Wbemidl.h> - #include <ShlObj.h> - #include <ObjBase.h> - #pragma warning(pop) - - #pragma comment(lib, "Psapi.lib") // To consider: It may be a problem to statically link to these libraries if the application at runtime intends to dynamically - #pragma comment(lib, "ole32.lib") // link to a different version of the same library, and we are statically linked into that application instead of being a DLL. - #pragma comment(lib, "shell32.lib") - - // NtQueryInformation and THREAD_BASIC_INFORMATION are undocumented but frequently needed for digging into thread information. - typedef LONG (WINAPI *NtQueryInformationThreadFunc)(HANDLE, int, PVOID, ULONG, PULONG); - - struct THREAD_BASIC_INFORMATION - { - LONG ExitStatus; - PVOID TebBaseAddress; - PVOID UniqueProcessId; - PVOID UniqueThreadId; - PVOID Priority; - PVOID BasePriority; - }; - - #ifndef UNW_FLAG_NHANDLER // Older Windows SDKs don't support this. - #define UNW_FLAG_NHANDLER 0 - #endif - -#elif defined(OVR_OS_MAC) - #include <unistd.h> - #include <sys/sysctl.h> - #include <sys/utsname.h> - #include <sys/types.h> - #include <sys/mman.h> - #include <stdlib.h> - #include <stdio.h> - #include <pthread.h> - #include <mach/mach.h> - #include <mach/mach_error.h> - #include <mach/thread_status.h> - #include <mach/exception.h> - #include <mach/task.h> - #include <mach/thread_act.h> - #include <mach-o/dyld.h> - #include <mach-o/dyld_images.h> - #include <libproc.h> - #include <libgen.h> - #include <execinfo.h> - #include <cxxabi.h> - #include "OVR_mach_exc_OSX.h" - - #if defined(__LP64__) - typedef struct mach_header_64 MachHeader; - typedef struct segment_command_64 SegmentCommand; - typedef struct section_64 Section; - #define kLCSegment LC_SEGMENT_64 - #else - typedef struct mach_header MachHeader; - typedef struct segment_command SegmentCommand; - typedef struct section Section; - #define kLCSegment LC_SEGMENT - #endif - - extern "C" const struct dyld_all_image_infos* _dyld_get_all_image_infos(); // From libdyld.dylib - -#elif defined(OVR_OS_UNIX) - #include <unistd.h> - #include <sys/sysctl.h> - #include <sys/utsname.h> - #include <sys/types.h> - #include <sys/ptrace.h> - #include <sys/wait.h> - #include <sys/mman.h> - #include <stdlib.h> - #include <stdio.h> - #include <pthread.h> - #include <libgen.h> - #include <execinfo.h> - #include <cxxabi.h> - //#include <libunwind.h> // Can't use this until we can ensure that we have an installed version of it. -#endif - -#if !defined(MIN) - #define MIN(X,Y) ((X) < (Y) ? (X) : (Y)) - #define MAX(X,Y) ((X) > (Y) ? (X) : (Y)) -#endif - - -OVR_DISABLE_MSVC_WARNING(4351) // new behavior: elements of array will be default initialized -OVR_DISABLE_MSVC_WARNING(4996) // This function or variable may be unsafe - - - - -#if defined(OVR_OS_APPLE) - static OVR::ExceptionHandler* sExceptionHandler = nullptr; - const uint32_t sMachCancelMessageType = 0x0ca9ce11; // This is a made-up value of our own choice. - - extern "C" - { - kern_return_t catch_mach_exception_raise_OVR(mach_port_t /*exceptionPort*/, mach_port_t /*threadSysId*/, - mach_port_t /*machTask*/, exception_type_t /*machExceptionType*/, - mach_exception_data_t /*machExceptionData*/, mach_msg_type_number_t /*machExceptionDataCount*/) - { - return KERN_FAILURE; - } - - kern_return_t catch_mach_exception_raise_state_OVR(mach_port_t /*exceptionPort*/, exception_type_t /*exceptionType*/, - const mach_exception_data_t /*machExceptionData*/, mach_msg_type_number_t /*machExceptionDataCount*/, - int* /*pMachExceptionFlavor*/, const thread_state_t /*threadStatePrev*/, mach_msg_type_number_t /*threaStatePrevCount*/, - thread_state_t /*threadStateNew*/, mach_msg_type_number_t* /*pThreadStateNewCount*/) - { - return KERN_FAILURE; - } - - kern_return_t catch_mach_exception_raise_state_identity_OVR(mach_port_t exceptionPort, mach_port_t threadSysId, mach_port_t machTask, - exception_type_t exceptionType, mach_exception_data_type_t* machExceptionData, - mach_msg_type_number_t machExceptionDataCount, int* pMachExceptionFlavor, - thread_state_t threadStatePrev, mach_msg_type_number_t threadStatePrevCount, - thread_state_t threadStateNew, mach_msg_type_number_t* pThreadStateNewCount) - { - return sExceptionHandler->HandleMachException(exceptionPort, threadSysId, machTask, exceptionType, machExceptionData, - machExceptionDataCount, pMachExceptionFlavor, threadStatePrev, threadStatePrevCount, - threadStateNew, pThreadStateNewCount); - } - - void* MachHandlerThreadFunctionStatic(void* pExceptionHandlerVoid) - { - return static_cast<OVR::ExceptionHandler*>(pExceptionHandlerVoid)->MachHandlerThreadFunction(); - } - - } // extern "C" -#endif - - - - -namespace OVR { - - -void GetInstructionPointer(void*& pInstruction) -{ - #if defined(OVR_CC_MSVC) - pInstruction = _ReturnAddress(); - #else // GCC, clang - pInstruction = __builtin_return_address(0); - #endif -} - - -static size_t SprintfAddress(char* threadHandleStr, size_t threadHandleStrCapacity, const void* pAddress) -{ - #if defined(OVR_CC_MSVC) - #if (OVR_PTR_SIZE >= 8) - return OVR_snprintf(threadHandleStr, threadHandleStrCapacity, "0x%016I64x", pAddress); // e.g. 0x0123456789abcdef - #else - return OVR_snprintf(threadHandleStr, threadHandleStrCapacity, "0x%08x", pAddress); // e.g. 0x89abcdef - #endif - #else - #if (OVR_PTR_SIZE >= 8) - return OVR_snprintf(threadHandleStr, threadHandleStrCapacity, "%016llx", pAddress); // e.g. 0x0123456789abcdef - #else - return OVR_snprintf(threadHandleStr, threadHandleStrCapacity, "%08x", pAddress); // e.g. 0x89abcdef - #endif - #endif -} - - -static size_t SprintfThreadHandle(char* threadHandleStr, size_t threadHandleStrCapacity, const ThreadHandle& threadHandle) -{ - return SprintfAddress(threadHandleStr, threadHandleStrCapacity, threadHandle); -} - - -static size_t SprintfThreadSysId(char* threadSysIdStr, size_t threadSysIdStrCapacity, const ThreadSysId& threadSysId) -{ - #if defined(OVR_CC_MSVC) // Somebody could conceivably use VC++ with a different standard library that supports %ll. And VS2012+ also support %ll. - return OVR_snprintf(threadSysIdStr, threadSysIdStrCapacity, "%I64u", (uint64_t)threadSysId); - #else - return OVR_snprintf(threadSysIdStr, threadSysIdStrCapacity, "%llu", (uint64_t)threadSysId); - #endif -} - - - - - -void GetThreadStackBounds(void*& pStackBase, void*& pStackLimit, ThreadHandle threadHandle) -{ - #if defined(OVR_OS_WIN64) || defined(OVR_OS_WIN32) || (defined(OVR_OS_MS) && defined(OVR_OS_CONSOLE)) - ThreadSysId threadSysIdCurrent = (ThreadSysId)GetCurrentThreadId(); - ThreadSysId threadSysId; - NT_TIB* pTIB = nullptr; - - if(threadHandle == OVR_THREADHANDLE_INVALID) - threadSysId = threadSysIdCurrent; - else - threadSysId = ConvertThreadHandleToThreadSysId(threadHandle); - - if(threadSysId == threadSysIdCurrent) - { - #if (OVR_PTR_SIZE == 4) - // Need to use __asm__("movl %%fs:0x18, %0" : "=r" (pTIB) : : ); under gcc/clang. - __asm { - mov eax, fs:[18h] - mov pTIB, eax - } - #else - pTIB = (NT_TIB*)NtCurrentTeb(); - #endif - } - else - { - #if (OVR_PTR_SIZE == 4) - // It turns out we don't need to suspend the thread when getting SegFs/SegGS, as that's - // constant per thread and doesn't require the thread to be suspended. - //SuspendThread((HANDLE)threadHandle); - CONTEXT context; - memset(&context, 0, sizeof(context)); - context.ContextFlags = CONTEXT_SEGMENTS; - GetThreadContext((HANDLE)threadHandle, &context); // Requires THREAD_QUERY_INFORMATION privileges. - - LDT_ENTRY ldtEntry; - if(GetThreadSelectorEntry(threadHandle, context.SegFs, &ldtEntry)) // Requires THREAD_QUERY_INFORMATION - pTIB = (NT_TIB*)((ldtEntry.HighWord.Bits.BaseHi << 24 ) | (ldtEntry.HighWord.Bits.BaseMid << 16) | ldtEntry.BaseLow); - - //ResumeThread((HANDLE)threadHandle); - #else - // We cannot use GetThreadSelectorEntry or Wow64GetThreadSelectorEntry on Win64. - // We need to read the SegGs qword at offset 0x30. We can't use pTIB = (NT_TIB*)__readgsqword(0x30) because that reads only the current setGs offset. - // mov rax, qword ptr gs:[30h] - // mov qword ptr [pTIB],rax - // In the meantime we rely on the NtQueryInformationThread function. - - static NtQueryInformationThreadFunc spNtQueryInformationThread = nullptr; - - if(!spNtQueryInformationThread) - { - HMODULE hNTDLL = GetModuleHandleA("ntdll.dll"); - spNtQueryInformationThread = (NtQueryInformationThreadFunc)(uintptr_t)GetProcAddress(hNTDLL, "NtQueryInformationThread"); - } - - if(spNtQueryInformationThread) - { - THREAD_BASIC_INFORMATION tbi; - - memset(&tbi, 0, sizeof(tbi)); - LONG result = spNtQueryInformationThread(threadHandle, 0, &tbi, sizeof(tbi), nullptr); // Requires THREAD_QUERY_INFORMATION privileges - if(result == 0) - pTIB = (NT_TIB*)tbi.TebBaseAddress; - } - #endif - } - - if(pTIB) - { - pStackBase = (void*)pTIB->StackBase; - pStackLimit = (void*)pTIB->StackLimit; - } - else - { - pStackBase = nullptr; - pStackLimit = nullptr; - } - - #elif defined(OVR_OS_APPLE) - if(!threadHandle) - threadHandle = pthread_self(); - - pStackBase = pthread_get_stackaddr_np((pthread_t)threadHandle); - size_t stackSize = pthread_get_stacksize_np((pthread_t)threadHandle); - pStackLimit = (void*)((size_t)pStackBase - stackSize); - - #elif defined(OVR_OS_UNIX) - pStackBase = nullptr; - pStackLimit = nullptr; - - pthread_attr_t threadAttr; - pthread_attr_init(&threadAttr); - - #if defined(OVR_OS_LINUX) - int result = pthread_getattr_np((pthread_t)threadHandle, &threadAttr); - #else - int result = pthread_attr_get_np((pthread_t)threadHandle, &threadAttr); - #endif - - if(result == 0) - { - size_t stackSize = 0; - result = pthread_attr_getstack(&threadAttr, &pStackLimit, &stackSize); - - if(result == 0) - pStackBase = (void*)((uintptr_t)pStackLimit + stackSize); // We assume the stack grows downward. - } - - #endif -} - - -bool OVRIsDebuggerPresent() -{ - #if defined(OVR_OS_MS) - return ::IsDebuggerPresent() != 0; - - #elif defined(OVR_OS_APPLE) - int mib[4] = { CTL_KERN, KERN_PROC, KERN_PROC_PID, getpid() }; - struct kinfo_proc info; - size_t size = sizeof(info); - - info.kp_proc.p_flag = 0; - sysctl(mib, sizeof(mib) / sizeof(*mib), &info, &size, nullptr, 0); - - return ((info.kp_proc.p_flag & P_TRACED) != 0); - - #elif (defined(OVR_OS_LINUX) || defined(OVR_OS_BSD)) && !defined(OVR_OS_ANDROID) - // This works better than the PT_TRACE_ME approach. - // However, it presents a problem: - // http://pubs.opengroup.org/onlinepubs/009695399/functions/fork.html - // When the application calls fork() from a signal handler and any of the - // fork handlers registered by pthread_atfork() calls a function that is - // not asynch-signal-safe, the behavior is undefined. - // We may need to provide two pathways within this function, one of which - // doesn't fork and instead uses PT_TRACE_ME. - int pid = fork(); - int status; - bool present = false; - - if (pid == -1) // If fork failed... - { - // perror("fork"); - } - else if (pid == 0) // If we are the child process... - { - int ppid = getppid(); - - #if defined(OVR_OS_LINUX) - if (ptrace(PTRACE_ATTACH, ppid, nullptr, nullptr) == 0) - #else - if (ptrace(PT_ATTACH, ppid, nullptr, nullptr) == 0) - #endif - { - waitpid(ppid, nullptr, 0); - - #if defined(OVR_OS_LINUX) - ptrace(PTRACE_CONT, getppid(), nullptr, nullptr); - ptrace(PTRACE_DETACH, getppid(), nullptr, nullptr); - #else - ptrace(PT_CONTINUE, getppid(), nullptr, nullptr); - ptrace(PT_DETACH, getppid(), nullptr, nullptr); - #endif - } - else - { - // ptrace failed so the debugger is present. - present = true; - } - - exit(present ? 1 : 0); // The WEXITSTATUS call below will read this exit value. - } - else // Else we are the original process. - { - waitpid(pid, &status, 0); - present = WEXITSTATUS(status) ? true : false; // Read the exit value from the child's call to exit. - } - - return present; - - #elif defined(PT_TRACE_ME) && !defined(OVR_OS_ANDROID) - return (ptrace(PT_TRACE_ME, 0, 1, 0) < 0); - - #else - return false; - #endif -} - - -// Exits the process with the given exit code. -void ExitProcess(intptr_t processReturnValue) -{ - exit((int)processReturnValue); -} - - -void* SafeMMapAlloc(size_t size) -{ - #if defined(OVR_OS_MS) - return VirtualAlloc(nullptr, size, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE); // size is rounded up to a page. // Returned memory is 0-filled. - - #elif defined(OVR_OS_MAC) || defined(OVR_OS_UNIX) - #if !defined(MAP_FAILED) - #define MAP_FAILED ((void*)-1) - #endif - - void* result = mmap(nullptr, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0); // Returned memory is 0-filled. - if(result == MAP_FAILED) // mmap returns MAP_FAILED (-1) upon failure. - result = nullptr; - return result; - #endif -} - - -void SafeMMapFree(const void* memory, size_t size) -{ - #if defined(OVR_OS_MS) - OVR_UNUSED(size); - VirtualFree(const_cast<void*>(memory), 0, MEM_RELEASE); - - #elif defined(OVR_OS_MAC) || defined(OVR_OS_UNIX) - size_t pageSize = getpagesize(); - size = (((size + (pageSize - 1)) / pageSize) * pageSize); - munmap(const_cast<void*>(memory), size); // Must supply the size to munmap. - #endif -} - - -// Note that we can't just return sizeof(void*) == 8, as we may have the case of a -// 32 bit app running on a 64 bit operating system. -static bool Is64BitOS() -{ - #if (OVR_PTR_SIZE >= 8) - return true; - - #elif defined(OVR_OS_WIN32) || defined(OVR_OS_WIN64) - BOOL is64BitOS = FALSE; - bool IsWow64ProcessPresent = (GetProcAddress(GetModuleHandleW(L"kernel32.dll"), "IsWow64Process") != nullptr); - return (IsWow64ProcessPresent && IsWow64Process(GetCurrentProcess(), &is64BitOS) && is64BitOS); - - #elif defined(OVR_OS_MAC) || defined(OVR_OS_UNIX) - utsname utsName; - memset(&utsName, 0, sizeof(utsName)); - return (uname(&utsName) == 0) && (strcmp(utsName.machine, "x86_64") == 0); - - #else - return false; - #endif -} - - -// The output will always be 0-terminated. -// Returns the required strlen of the output. -// Returns (size_t)-1 on failure. -size_t SpawnShellCommand(const char* shellCommand, char* output, size_t outputCapacity) -{ - #if defined(OVR_OS_UNIX) || defined(OVR_OS_APPLE) - FILE* pFile = popen(shellCommand, "r"); - - if(pFile) - { - size_t requiredLength = 0; - char buffer[256]; - - while(fgets(buffer, sizeof(buffer), pFile)) // fgets 0-terminates the buffer. - { - size_t length = OVR_strlen(buffer); - requiredLength += length; - - if(outputCapacity) - { - OVR_strlcpy(output, buffer, outputCapacity); - length = MIN(outputCapacity, length); - } - - output += length; - outputCapacity -= length; - } - - pclose(pFile); - return requiredLength; - } - #else - // To do. Properly solving this on Windows requires a bit of code. - OVR_UNUSED(shellCommand); - OVR_UNUSED(output); - OVR_UNUSED(outputCapacity); - #endif - - return (size_t)-1; -} - - -// Retrieves a directory path which ends with a path separator. -// Returns the required strlen of the path. -// Guarantees the presence of the directory upon returning true. -static size_t GetUserDocumentsDirectory(char* directoryPath, size_t directoryPathCapacity) -{ - #if defined(OVR_OS_MS) - wchar_t pathW[MAX_PATH + 1]; // +1 because we append a path separator. - HRESULT hr = SHGetFolderPathW(nullptr, CSIDL_APPDATA | CSIDL_FLAG_CREATE, nullptr, SHGFP_TYPE_CURRENT, pathW); - - if(SUCCEEDED(hr)) - { - OVR_UNUSED(directoryPathCapacity); - - intptr_t requiredUTF8Length = OVR::UTF8Util::GetEncodeStringSize(pathW); // Returns required strlen. - if(requiredUTF8Length < MAX_PATH) // We need space for a trailing path separator. - { - OVR::UTF8Util::EncodeString(directoryPath, pathW, -1); - OVR::OVR_strlcat(directoryPath, "\\", directoryPathCapacity); - } - - return (requiredUTF8Length + 1); - } - - #elif defined(OVR_OS_MAC) - // This is the same location that Apple puts its OS-generated .crash files. - const char* home = getenv("HOME"); - size_t requiredStrlen = OVR::OVR_snprintf(directoryPath, directoryPathCapacity, "%s/Library/Logs/DiagnosticReports/", home ? home : "/Users/Shared/Logs/DiagnosticReports/"); - // To do: create the directory if it doesn't already exist. - return requiredStrlen; - - #elif defined(OVR_OS_UNIX) || defined(OVR_OS_MAC) - const char* home = getenv("HOME"); - size_t requiredStrlen = OVR::OVR_snprintf(directoryPath, directoryPathCapacity, "%s/Library/", home ? home : "/Users/Shared/"); - // To do: create the directory if it doesn't already exist. - return requiredStrlen; - #endif - - return 0; -} - - -// Retrieves the name of the given thread. -// To do: Move this to OVR_Threads.h -bool GetThreadName(OVR::ThreadHandle threadHandle, char* threadName, size_t threadNameCapacity) -{ - #if defined(OVR_OS_APPLE) || defined(OVR_OS_LINUX) - int result = pthread_getname_np((pthread_t)threadHandle, threadName, threadNameCapacity); - if(result == 0) - return true; - #else - // This is not currently possible on Windows, as only the debugger stores the thread name. We could potentially use a vectored - // exception handler to catch all thread name exceptions (0x406d1388) and record them in a static list at runtime. To detect - // thread exit we could use WMI Win32_ThreadStopTrace. Maintain a list of thread names between these two events. - OVR_UNUSED(threadHandle); - OVR_UNUSED(threadNameCapacity); - #endif - - if(threadNameCapacity) - threadName[0] = 0; - - return false; -} - - -OVR::ThreadSysId ConvertThreadHandleToThreadSysId(OVR::ThreadHandle threadHandle) -{ - #if defined(OVR_OS_WIN64) - return (OVR::ThreadSysId)::GetThreadId(threadHandle); // Requires THREAD_QUERY_INFORMATION privileges. - - #elif defined(OVR_OS_WIN32) - typedef DWORD (WINAPI *GetThreadIdFunc)(HANDLE); - - static volatile bool sInitialized = false; - static GetThreadIdFunc spGetThreadIdFunc = nullptr; - static NtQueryInformationThreadFunc spNtQueryInformationThread = nullptr; - - if(!sInitialized) - { - HMODULE hKernel32 = GetModuleHandleA("kernel32.dll"); - if(hKernel32) - spGetThreadIdFunc = (GetThreadIdFunc)(uintptr_t)GetProcAddress(hKernel32, "GetThreadId"); - - if(!spGetThreadIdFunc) - { - HMODULE hNTDLL = GetModuleHandleA("ntdll.dll"); - - if(hNTDLL) - spNtQueryInformationThread = (NtQueryInformationThreadFunc)(uintptr_t)GetProcAddress(hNTDLL, "NtQueryInformationThread"); - } - - sInitialized = true; - } - - if(spGetThreadIdFunc) - return (OVR::ThreadSysId)spGetThreadIdFunc(threadHandle); - - if(spNtQueryInformationThread) - { - THREAD_BASIC_INFORMATION tbi; - - if(spNtQueryInformationThread(threadHandle, 0, &tbi, sizeof(tbi), nullptr) == 0) - return (OVR::ThreadSysId)tbi.UniqueThreadId; - } - - return OVR_THREADSYSID_INVALID; - - #elif defined(OVR_OS_APPLE) - mach_port_t threadSysId = pthread_mach_thread_np((pthread_t)threadHandle); // OS 10.4 and later. - return (ThreadSysId)threadSysId; - - #elif defined(OVR_OS_LINUX) - - // I believe we can usually (though not portably) intepret the pthread_t as a pointer to a struct whose first member is a lwp id. - OVR_UNUSED(threadHandle); - return OVR_THREADSYSID_INVALID; - - #else - OVR_UNUSED(threadHandle); - return OVR_THREADSYSID_INVALID; - #endif -} - - -OVR::ThreadHandle ConvertThreadSysIdToThreadHandle(OVR::ThreadSysId threadSysId) -{ - #if defined(OVR_OS_MS) - // We currently request the given rights because that's what users of this function typically need it for. Ideally there would - // be a way to specify the requested rights in order to avoid the problem if we need only a subset of them but can't get it. - // The solution we use below to try opening with successively reduced rights will work for our uses here but isn't a good general solution to this. - OVR::ThreadHandle threadHandle = ::OpenThread(THREAD_SUSPEND_RESUME | THREAD_GET_CONTEXT | THREAD_QUERY_INFORMATION, TRUE, (DWORD)threadSysId); - - if(threadHandle == OVR_THREADHANDLE_INVALID) - { - threadHandle = ::OpenThread(THREAD_GET_CONTEXT | THREAD_QUERY_INFORMATION, TRUE, (DWORD)threadSysId); - - if(threadHandle == OVR_THREADHANDLE_INVALID) - threadHandle = ::OpenThread(THREAD_QUERY_INFORMATION, TRUE, (DWORD)threadSysId); - } - - return threadHandle; - #elif defined(OVR_OS_MAC) - return (ThreadHandle)pthread_from_mach_thread_np((mach_port_t)threadSysId); - #else - return (ThreadHandle)threadSysId; - #endif -} - - -void FreeThreadHandle(OVR::ThreadHandle threadHandle) -{ - #if defined(OVR_OS_MS) - if(threadHandle != OVR_THREADHANDLE_INVALID) - ::CloseHandle(threadHandle); - #else - OVR_UNUSED(threadHandle); - #endif -} - - -OVR::ThreadSysId GetCurrentThreadSysId() -{ - #if defined(OVR_OS_MS) - return ::GetCurrentThreadId(); - #elif defined(OVR_OS_APPLE) - return (ThreadSysId)mach_thread_self(); - #else - return (ThreadSysId)pthread_self(); - #endif -} - - - -static void GetCurrentProcessFilePath(char* appPath, size_t appPathCapacity) -{ - appPath[0] = 0; - - #if defined(OVR_OS_MS) - wchar_t pathW[MAX_PATH]; - GetModuleFileNameW(0, pathW, (DWORD)OVR_ARRAY_COUNT(pathW)); - - size_t requiredUTF8Length = (size_t)OVR::UTF8Util::GetEncodeStringSize(pathW); // Returns required strlen. - - if(requiredUTF8Length < appPathCapacity) - { - OVR::UTF8Util::EncodeString(appPath, pathW, -1); - } - else - { - appPath[0] = 0; - } - - #elif defined(OVR_OS_APPLE) - struct BunderFolder - { - // Returns true if pStr ends with pFind, case insensitively. - // To do: Move OVR_striend to OVRKernel/Std.h - static bool OVR_striend(const char* pStr, const char* pFind, size_t strLength = (size_t)-1, size_t findLength = (size_t)-1) - { - if(strLength == (size_t)-1) - strLength = OVR_strlen(pStr); - if(findLength == (size_t)-1) - findLength = OVR_strlen(pFind); - if(strLength >= findLength) - return (OVR_stricmp(pStr + strLength - findLength, pFind) == 0); - return false; - } - - static bool IsBundleFolder(const char* filePath) - { - // https://developer.apple.com/library/mac/documentation/CoreFoundation/Conceptual/CFBundles/AboutBundles/AboutBundles.html#//apple_ref/doc/uid/10000123i-CH100-SW1 - static const char* extensionArray[] = { ".app", ".bundle", ".framework", ".plugin", ".kext" }; - - for(size_t i = 0; i < OVR_ARRAY_COUNT(extensionArray); i++) - { - if(OVR_striend(filePath, extensionArray[i])) - return true; - } - - return false; - } - }; - - char appPathTemp[PATH_MAX]; - uint32_t appPathTempCapacity32 = PATH_MAX; - size_t requiredStrlen = appPathCapacity; - - if(_NSGetExecutablePath(appPathTemp, &appPathTempCapacity32) == 0) - { - char appPathTempReal[PATH_MAX]; - - if(realpath(appPathTemp, appPathTempReal)) // If the path is a symbolic link, this converts it to the real path. - { - // To consider: Enable reading the internal bundle executable path. An application on Mac may in - // fact be within a file bundle, which is an private file system within a file. With Objective C - // we could use: [[NSWorkspace sharedWorkspace] isFilePackageAtPath:fullPath]; - bool shouldReadTheBunderPath = false; - - if(shouldReadTheBunderPath) - { - // We recursively call dirname() until we find .app/.bundle/.plugin as a directory name. - OVR_strlcpy(appPathTemp, appPathTempReal, OVR_ARRAY_COUNT(appPathTemp)); - bool found = BunderFolder::IsBundleFolder(appPathTemp); - - while(!found && OVR_strcmp(appPathTemp, ".") && OVR_strcmp(appPathTemp, "/")) - { - OVR_strlcpy(appPathTemp, dirname(appPathTemp), OVR_ARRAY_COUNT(appPathTemp)); - found = BunderFolder::IsBundleFolder(appPathTemp); - } - - if(found) // If somewhere above we found a parent bundle container... - requiredStrlen = OVR_strlcpy(appPath, appPathTemp, appPathCapacity); - else - requiredStrlen = OVR_strlcpy(appPath, appPathTempReal, appPathCapacity); - } - else - { - requiredStrlen = OVR_strlcpy(appPath, appPathTempReal, appPathCapacity); - } - } - } - - if(requiredStrlen >= appPathCapacity) - appPath[0] = '\0'; - - #elif defined(OVR_OS_LINUX) - ssize_t length = readlink("/proc/self/exe", appPath, appPathCapacity); - - if((length != -1) && ((size_t)length < (appPathCapacity - 1))) - { - appPath[length] = '\0'; - } - #endif -} - - -static const char* GetFileNameFromPath(const char* filePath) -{ - #if defined(OVR_OS_MS) - const char* lastPathSeparator = max(strrchr(filePath, '\\'), strrchr(filePath, '/')); // Microsoft APIs are inconsistent with respect to allowing / as a path separator. - #else - const char* lastPathSeparator = strrchr(filePath, '/'); - #endif - - if(lastPathSeparator) - return lastPathSeparator + 1; - - return filePath; -} - - - -static void FormatDateTime(char* buffer, size_t bufferCapacity, time_t timeValue, bool getDate, bool getTime, bool localDateTime, bool fileNameSafeCharacters = false) -{ - char temp[128]; - const tm* pTime = localDateTime ? localtime(&timeValue) : gmtime(&timeValue); - - if(bufferCapacity) - buffer[0] = 0; - - if(getDate) - { - const char* format = fileNameSafeCharacters ? "%Y-%m-%d" : "%Y/%m/%d"; - strftime(temp, OVR_ARRAY_COUNT(temp), format, pTime); - OVR::OVR_strlcpy(buffer, temp, bufferCapacity); - } - - if(getTime) - { - const char* format = fileNameSafeCharacters ? " %H.%M.%S" : " %H:%M:%S"; - strftime(temp, OVR_ARRAY_COUNT(temp), (getDate ? format : format + 1), pTime); - OVR::OVR_strlcat(buffer, temp, bufferCapacity); - } -} - - -static void GetOSVersionName(char* versionName, size_t versionNameCapacity) -{ - #if defined(OVR_OS_MS) - const char* name = "unknown"; - - OSVERSIONINFOEXW vi; - memset(&vi, 0, sizeof(vi)); - vi.dwOSVersionInfoSize = sizeof(vi); - - if(GetVersionExW((LPOSVERSIONINFOW)&vi)) - { - if(vi.dwMajorVersion >= 7) - { - // Unknown recent version. - } - if(vi.dwMajorVersion >= 6) - { - if(vi.dwMinorVersion >= 4) - name = "Windows 10"; - else if(vi.dwMinorVersion >= 3) - { - if(vi.wProductType == VER_NT_WORKSTATION) - name = "Windows 8.1"; - else - name = "Windows Server 2012 R2"; - } - else if(vi.dwMinorVersion >= 2) - { - if(vi.wProductType == VER_NT_WORKSTATION) - name = "Windows 8"; - else - name = "Windows Server 2012"; - } - else if(vi.dwMinorVersion >= 1) - { - if(vi.wProductType == VER_NT_WORKSTATION) - name = "Windows 7"; - else - name = "Windows Server 2008 R2"; - } - else - { - if(vi.wProductType == VER_NT_WORKSTATION) - name = "Windows Vista"; - else - name = "Windows Server 2008"; - } - } - else if(vi.dwMajorVersion >= 5) - { - if(vi.dwMinorVersion == 0) - name = "Windows 2000"; - else if(vi.dwMinorVersion == 1) - name = "Windows XP"; - else // vi.dwMinorVersion == 2 - { - if(GetSystemMetrics(SM_SERVERR2) != 0) - name = "Windows Server 2003 R2"; - else if(vi.wSuiteMask & VER_SUITE_WH_SERVER) - name = "Windows Home Server"; - if(GetSystemMetrics(SM_SERVERR2) == 0) - name = "Windows Server 2003"; - else - name = "Windows XP Professional x64 Edition"; - } - } - else - name = "Windows 98 or earlier"; - } - - OVR_strlcpy(versionName, name, versionNameCapacity); - - #elif defined(OVR_OS_UNIX) || defined(OVR_OS_APPLE) - utsname utsName; - memset(&utsName, 0, sizeof(utsName)); - - if(uname(&utsName) == 0) - OVR_snprintf(versionName, versionNameCapacity, "%s %s %s %s", utsName.sysname, utsName.release, utsName.version, utsName.machine); - else - OVR_snprintf(versionName, versionNameCapacity, "Unix"); - #endif -} - - - - -void CreateException(CreateExceptionType exceptionType) -{ - char buffer[1024] = {}; - - switch(exceptionType) - { - case kCETAccessViolation: - { - int* pNullPtr = reinterpret_cast<int*>((rand() / 2) / RAND_MAX); - pNullPtr[0] = 0; // This line should generate an exception. - sprintf(buffer, "%p", pNullPtr); - break; - } - - case kCETDivideByZero: - { - int smallValue = 1; - int largeValue = (1000 * exceptionType); - int divByZero = (smallValue / largeValue); // This line should generate a div/0 exception. - sprintf(buffer, "%d", divByZero); - break; - } - - case kCETIllegalInstruction: - { - #if defined(OVR_CPU_X86) || (defined(OVR_CPU_X86_64) && !defined(OVR_CC_MSVC)) // (if x86) or (if x64 and any computer but VC++)... - #if defined(OVR_CC_MSVC) - __asm ud2 - #else // e.g. GCC - asm volatile("ud2"); - #endif - - #elif defined(OVR_CPU_X86_64) && (defined(OVR_OS_MS) && defined(PAGE_EXECUTE_READWRITE)) - // VC++ for x64 doesn't support inline asm. - void* pVoid = _AddressOfReturnAddress(); - void** ppVoid = reinterpret_cast<void**>(pVoid); - void* pReturnAddress = *ppVoid; - DWORD dwProtectPrev = 0; - - if(VirtualProtect(pReturnAddress, 2, PAGE_EXECUTE_READWRITE, &dwProtectPrev)) // If we can set the memory to be executable... - { - // Modify the code we return to. - uint8_t asm_ud2[] = { 0x0f, 0x0b }; - memcpy(pReturnAddress, asm_ud2, sizeof(asm_ud2)); - VirtualProtect(pReturnAddress, 2, dwProtectPrev, &dwProtectPrev); - } - else - { - // To do: Fix this. - } - - #else - // To do: Fix this. - #endif - - break; - } - - case kCETStackCorruption: - { - size_t size = (sizeof(buffer) * 16) - (rand() % 16); - char* pOutsizeStack = buffer - ((sizeof(buffer) * 16) + (rand() % 16)); - - memset(buffer, 0, size); - memset(pOutsizeStack, 0, size); // This line should generate an exception, or an exception will be generated upon return from this function. - break; - } - - case kCETStackOverflow: - { - CreateException(exceptionType); // Call ourselves recursively. This line should generate a div/0 exception. - sprintf(buffer, "%d", exceptionType); - break; - } - - case kCETAlignment: - { - // Not all platforms generate alignment exceptions. Some internally handle it. - void* pAligned = malloc(16); - char* pMisaligned = (char*)pAligned + 1; - uint64_t* pMisaligned64 = reinterpret_cast<uint64_t*>(pMisaligned); - - *pMisaligned64 = 0; // This line should generate an exception. - free(pAligned); - break; - } - - case kCETFPU: - // Platforms usually have FPU exceptions disabled. In order to test FPU exceptions we will need to at least - // temporarily disable them before executing code here to generate such exceptions. - // To do. - break; - - case kCETTrap: - // To do. This is hardware-specific. - break; - } -} - - - - -#if defined(OVR_OS_MS) - typedef BOOL (WINAPI * StackWalk64Type)(DWORD MachineType, HANDLE hProcess, HANDLE hThread, LPSTACKFRAME64 StackFrame, PVOID ContextRecord, PREAD_PROCESS_MEMORY_ROUTINE64 ReadMemoryRoutine, PFUNCTION_TABLE_ACCESS_ROUTINE64 FunctionTableAccessRoutine, PGET_MODULE_BASE_ROUTINE64 GetModuleBaseRoutine, PTRANSLATE_ADDRESS_ROUTINE64 TranslateAddress); - typedef PVOID (WINAPI * SymFunctionTableAccess64Type)(HANDLE hProcess, DWORD64 dwAddr); - typedef DWORD64 (WINAPI * SymGetModuleBase64Type)(HANDLE hProcess, DWORD64 dwAddr); - typedef DWORD (WINAPI * SymSetOptionsType)(DWORD SymOptions); - typedef BOOL (WINAPI * SymInitializeWType)(HANDLE hProcess, PCWSTR UserSearchPath, BOOL fInvadeProcess); - typedef BOOL (WINAPI * SymCleanupType)(HANDLE hProcess); - typedef DWORD64 (WINAPI * SymLoadModule64Type)(HANDLE hProcess, HANDLE hFile, PCSTR ImageName, PCSTR ModuleName, DWORD64 BaseOfDll, DWORD SizeOfDll); - typedef BOOL (WINAPI * SymFromAddrType)(HANDLE hProcess, DWORD64 Address, PDWORD64 Displacement, PSYMBOL_INFO Symbol); - typedef BOOL (WINAPI * SymGetLineFromAddr64Type)(HANDLE hProcess, DWORD64 qwAddr, PDWORD pdwDisplacement, PIMAGEHLP_LINE64 Line64); - - StackWalk64Type pStackWalk64; - SymFunctionTableAccess64Type pSymFunctionTableAccess64; - SymGetModuleBase64Type pSymGetModuleBase64; - SymSetOptionsType pSymSetOptions; - SymInitializeWType pSymInitializeW; - SymCleanupType pSymCleanup; - SymLoadModule64Type pSymLoadModule64; - SymFromAddrType pSymFromAddr; - SymGetLineFromAddr64Type pSymGetLineFromAddr64; -#endif - - - -SymbolLookup::SymbolLookup() - : initialized(false), - allowMemoryAllocation(true), - moduleListUpdated(false), - moduleInfoArray(), - moduleInfoArraySize(0) -{ -} - -SymbolLookup::~SymbolLookup() -{ - Shutdown(); -} - -void SymbolLookup::AddSourceCodeDirectory(const char* pDirectory) -{ - OVR_UNUSED(pDirectory); -} - -bool SymbolLookup::Initialize() -{ - if(!initialized) - { - #if defined(OVR_OS_MS) - // http://msdn.microsoft.com/en-us/library/windows/desktop/ms679294%28v=vs.85%29.aspx - HANDLE hProcess = GetCurrentProcess(); - HMODULE hDbgHelp = LoadLibraryW(L"DbgHelp.dll"); // It's best if the application supplies a recent version of this. - - if(hDbgHelp) - { - pStackWalk64 = (StackWalk64Type)(uintptr_t)::GetProcAddress(hDbgHelp, "StackWalk64"); - pSymFunctionTableAccess64 = (SymFunctionTableAccess64Type)(uintptr_t)::GetProcAddress(hDbgHelp, "SymFunctionTableAccess64"); - pSymGetModuleBase64 = (SymGetModuleBase64Type)(uintptr_t)::GetProcAddress(hDbgHelp, "SymGetModuleBase64"); - pSymSetOptions = (SymSetOptionsType)(uintptr_t)::GetProcAddress(hDbgHelp, "SymSetOptions"); - pSymInitializeW = (SymInitializeWType)(uintptr_t)::GetProcAddress(hDbgHelp, "SymInitializeW"); - pSymCleanup = (SymCleanupType)(uintptr_t)::GetProcAddress(hDbgHelp, "SymCleanup"); - pSymLoadModule64 = (SymLoadModule64Type)(uintptr_t)::GetProcAddress(hDbgHelp, "SymLoadModule64"); - pSymFromAddr = (SymFromAddrType)(uintptr_t)::GetProcAddress(hDbgHelp, "SymFromAddr"); - pSymGetLineFromAddr64 = (SymGetLineFromAddr64Type)(uintptr_t)::GetProcAddress(hDbgHelp, "SymGetLineFromAddr64"); - } - - pSymSetOptions(SYMOPT_UNDNAME | SYMOPT_DEFERRED_LOADS); - - // To consider: Use a manually created search path: - // wchar_t searchPathW[4096]; // Semicolon-separated strings. - // The current working directory of the application. - // The directory of the application itself (GetModuleFileName). - // The _NT_SYMBOL_PATH environment variable. - // The _NT_ALTERNATE_SYMBOL_PATH environment variable. - - if(pSymInitializeW(hProcess, nullptr /*searchPathW*/, FALSE)) - { - initialized = true; - } - #endif - } - - return true; -} - -void SymbolLookup::Shutdown() -{ - if(initialized) - { - initialized = false; - - #if defined(OVR_OS_MS) - HANDLE hProcess = GetCurrentProcess(); - - // SymCleanup should handle this for us. - //if(moduleListUpdated) - //{ - // for(size_t i = 0; i < moduleInfoArraySize; i++) - // pSymUnloadModule64(hProcess, moduleInfoArray[i].baseAddress); - //} - - moduleInfoArraySize = 0; - - pSymCleanup(hProcess); - #endif - } -} - - -void SymbolLookup::EnableMemoryAllocation(bool enabled) -{ - allowMemoryAllocation = enabled; -} - - -OVR_DISABLE_MSVC_WARNING(4740) // flow in or out of inline asm code suppresses global optimization -OVR_DISABLE_MSVC_WARNING(4748) // /GS can not protect parameters and local variables from local buffer overrun because optimizations are disabled in function - - -size_t SymbolLookup::GetBacktrace(void* addressArray[], size_t addressArrayCapacity, size_t skipCount, void* platformThreadContext, OVR::ThreadSysId threadSysIdHelp) -{ - #if defined(OVR_OS_WIN64) || (defined(OVR_OS_MS) && defined(OVR_OS_CONSOLE)) - OVR_UNUSED(threadSysIdHelp); - - if(platformThreadContext == nullptr) - return RtlCaptureStackBackTrace(1, (ULONG)addressArrayCapacity, addressArray, nullptr); - - // We need to get the call stack of another thread. - size_t frameIndex = 0; - CONTEXT context; - PRUNTIME_FUNCTION pRuntimeFunction; - ULONG64 imageBase = 0; - ULONG64 imageBasePrev = 0; - - memcpy(&context, (CONTEXT*)platformThreadContext, sizeof(CONTEXT)); - context.ContextFlags = CONTEXT_CONTROL; - - if(context.Rip && (frameIndex < addressArrayCapacity)) - addressArray[frameIndex++] = (void*)(uintptr_t)context.Rip; - - while(context.Rip && (frameIndex < addressArrayCapacity)) - { - imageBasePrev = imageBase; - pRuntimeFunction = (PRUNTIME_FUNCTION)RtlLookupFunctionEntry(context.Rip, &imageBase, nullptr); - - if(pRuntimeFunction) - { - VOID* handlerData = nullptr; - ULONG64 establisherFramePointers[2] = { 0, 0 }; - RtlVirtualUnwind(UNW_FLAG_NHANDLER, imageBase, context.Rip, pRuntimeFunction, &context, &handlerData, establisherFramePointers, nullptr); - } - else - { - context.Rip = (ULONG64)(*(PULONG64)context.Rsp); - context.Rsp += 8; - } - - if(context.Rip && (frameIndex < addressArrayCapacity)) - { - if(skipCount) - --skipCount; - else - addressArray[frameIndex++] = (void*)(uintptr_t)context.Rip; - } - } - - return frameIndex; - - #elif defined(OVR_OS_WIN32) - OVR_UNUSED(threadSysIdHelp); - - size_t frameIndex = 0; - - if(pStackWalk64) - { - CONTEXT context; - - if(platformThreadContext) - { - memcpy(&context, platformThreadContext, sizeof(context)); - context.ContextFlags = CONTEXT_CONTROL; - } - else - { - memset(&context, 0, sizeof(context)); - context.ContextFlags = CONTEXT_CONTROL; - - __asm { - mov context.Ebp, EBP - mov context.Esp, ESP - call GetEIP - GetEIP: - pop context.Eip - } - } - - STACKFRAME64 sf; - memset(&sf, 0, sizeof(sf)); - sf.AddrPC.Offset = context.Eip; - sf.AddrPC.Mode = AddrModeFlat; - sf.AddrStack.Offset = context.Esp; - sf.AddrStack.Mode = AddrModeFlat; - sf.AddrFrame.Offset = context.Ebp; - sf.AddrFrame.Mode = AddrModeFlat; - - const HANDLE hCurrentProcess = ::GetCurrentProcess(); - const HANDLE hCurrentThread = ::GetCurrentThread(); - - if(!platformThreadContext) // If we are reading the current thread's call stack then we ignore this current function. - skipCount++; - - while(frameIndex < addressArrayCapacity) - { - if(!pStackWalk64(IMAGE_FILE_MACHINE_I386, hCurrentProcess, hCurrentThread, &sf, &context, nullptr, pSymFunctionTableAccess64, pSymGetModuleBase64, nullptr)) - break; - - if(sf.AddrFrame.Offset == 0) - break; - - if(skipCount) - --skipCount; - else - addressArray[frameIndex++] = ((void*)(uintptr_t)sf.AddrPC.Offset); - } - } - - return frameIndex; - - #elif defined(OVR_OS_APPLE) - struct StackFrame - { - StackFrame* pParentStackFrame; - void* pReturnPC; - }; - - void* pInstruction; - StackFrame* pStackFrame; - size_t frameIndex = 0; - - if(platformThreadContext) - { - #if defined(OVR_CPU_ARM) - arm_thread_state_t* pThreadState = (arm_thread_state_t*)platformThreadContext; - pStackFrame = (StackFrame*)pThreadState->__fp; - pInstruction = (void*) pThreadState->__pc; - #define FrameIsAligned(pStackFrame) ((((uintptr_t)pStackFrame) & 0x1) == 0) - #elif defined(OVR_CPU_X86_64) - x86_thread_state_t* pThreadState = (x86_thread_state_t*)platformThreadContext; - pInstruction = (void*) pThreadState->uts.ts64.__rip; - pStackFrame = (StackFrame*)pThreadState->uts.ts64.__rbp; - #define FrameIsAligned(pStackFrame) ((((uintptr_t)pStackFrame) & 0xf) == 0) - #elif defined(OVR_CPU_X86) - x86_thread_state_t* pThreadState = (x86_thread_state_t*)platformThreadContext; - pInstruction = (void*) pThreadState->uts.ts32.__eip; - pStackFrame = (StackFrame*)pThreadState->uts.ts32.__ebp; - #define FrameIsAligned(pStackFrame) ((((uintptr_t)pStackFrame) & 0xf) == 8) - #endif - - if(frameIndex < addressArrayCapacity) - addressArray[frameIndex++] = pInstruction; - } - else // Else get the current values... - { - pStackFrame = (StackFrame*)__builtin_frame_address(0); - GetInstructionPointer(pInstruction); - } - - pthread_t threadSelf = pthread_self(); - void* pCurrentStackBase = pthread_get_stackaddr_np(threadSelf); - void* pCurrentStackLimit = (void*)((uintptr_t)pCurrentStackBase - pthread_get_stacksize_np(threadSelf)); - bool threadIsCurrent = (platformThreadContext == nullptr) || (((void*)pStackFrame > pCurrentStackLimit) && ((void*)pStackFrame <= pCurrentStackBase)); - StackFrame* pStackBase; - StackFrame* pStackLimit; - - if(threadIsCurrent) - { - pStackBase = (StackFrame*)pCurrentStackBase; - pStackLimit = (StackFrame*)pCurrentStackLimit; - } - else if(threadSysIdHelp) - { - pthread_t threadHandle = pthread_from_mach_thread_np((mach_port_t)threadSysIdHelp); - pStackBase = (StackFrame*)pthread_get_stackaddr_np(threadHandle); - pStackLimit = (StackFrame*)((uintptr_t)pStackBase - pthread_get_stacksize_np(threadHandle)); - } - else - { // We guess what the limits are. - pStackBase = pStackFrame + ((384 * 1024) / sizeof(StackFrame)); - pStackLimit = pStackFrame - ((384 * 1024) / sizeof(StackFrame)); - } - - if((frameIndex < addressArrayCapacity) && pStackFrame && FrameIsAligned(pStackFrame)) - { - addressArray[frameIndex++] = pStackFrame->pReturnPC; - - while(pStackFrame && pStackFrame->pReturnPC && (frameIndex < addressArrayCapacity)) - { - pStackFrame = pStackFrame->pParentStackFrame; - - if(pStackFrame && FrameIsAligned(pStackFrame) && pStackFrame->pReturnPC && (pStackFrame > pStackLimit) && (pStackFrame < pStackBase)) - { - if(skipCount) - --skipCount; - else - addressArray[frameIndex++] = pStackFrame->pReturnPC; - } - else - break; - } - } - - return frameIndex; - - #elif defined(OVR_OS_LINUX) && (defined( __LIBUNWIND__) || defined(LIBUNWIND_AVAIL)) - // Libunwind-based solution. Requires installation of libunwind package. - // Libunwind isn't always safe for threads that are in signal handlers. - // An approach to get the callstack of another thread is to use signal injection into the target thread. - - OVR_UNUSED(platformThreadContext); - OVR_UNUSED(threadSysIdHelp); - - size_t frameIndex = 0; - unw_cursor_t cursor; - unw_context_t uc; - unw_word_t ip, sp; - - unw_getcontext(&uc); // This gets the current thread's context. We could alternatively initialize another thread's context with it. - unw_init_local(&cursor, &uc); - - while((unw_step(&cursor) > 0) && (frameIndex < addressArrayCapacity)) - { - // We can get the function name here too on some platforms with unw_get_proc_info() and unw_get_proc_name(). - - if(skipCount) - --skipCount; - else - { - unw_get_reg(&cursor, UNW_REG_IP, &ip); - addressArray[frameIndex++] = (void*)ip; - } - } - - return frameIndex; - #else - OVR_UNUSED(addressArray); - OVR_UNUSED(addressArrayCapacity); - OVR_UNUSED(skipCount); - OVR_UNUSED(platformThreadContext); - OVR_UNUSED(threadSysIdHelp); - - return 0; - #endif -} - - -size_t SymbolLookup::GetBacktraceFromThreadHandle(void* addressArray[], size_t addressArrayCapacity, size_t skipCount, OVR::ThreadHandle threadHandle) -{ - #if defined(OVR_OS_MS) - size_t count = 0; - DWORD threadSysId = (DWORD)ConvertThreadHandleToThreadSysId(threadHandle); - - // Compare to 0, compare to the self 'pseudohandle' and compare to the self id. - if((threadHandle == OVR_THREADHANDLE_INVALID) || (threadHandle == ::GetCurrentThread()) || (threadSysId == ::GetCurrentThreadId())) // If threadSysId refers to the current thread... - return GetBacktrace(addressArray, addressArrayCapacity, skipCount, nullptr); - - // We are working with another thread. We need to suspend it and get its CONTEXT. - // Suspending other threads is risky, as they may be in some state that cannot be safely blocked. - BOOL result = false; - DWORD suspendResult = ::SuspendThread(threadHandle); // Requires that the handle have THREAD_SUSPEND_RESUME rights. - - if(suspendResult != (DWORD)-1) // Returns previous suspend count, or -1 if failed. - { - CONTEXT context; - context.ContextFlags = CONTEXT_CONTROL | CONTEXT_INTEGER; // Requires that the handle have THREAD_GET_CONTEXT rights. - result = ::GetThreadContext(threadHandle, &context); - count = GetBacktrace(addressArray, addressArrayCapacity, skipCount, &context); - suspendResult = ::ResumeThread(threadHandle); - OVR_ASSERT_AND_UNUSED(suspendResult != (DWORD)-1, suspendResult); - } - - return count; - - #elif defined(OVR_OS_APPLE) - mach_port_t threadSysID = pthread_mach_thread_np((pthread_t)threadHandle); // Convert pthread_t to mach thread id. - return GetBacktraceFromThreadSysId(addressArray, addressArrayCapacity, skipCount, (OVR::ThreadSysId)threadSysID); - - #elif defined(OVR_OS_LINUX) - // To do. - OVR_UNUSED(addressArray); - OVR_UNUSED(addressArrayCapacity); - OVR_UNUSED(skipCount); - OVR_UNUSED(threadHandle); - return 0; - #endif -} - - -size_t SymbolLookup::GetBacktraceFromThreadSysId(void* addressArray[], size_t addressArrayCapacity, size_t skipCount, OVR::ThreadSysId threadSysId) -{ - #if defined(OVR_OS_MS) - OVR::ThreadHandle threadHandle = ConvertThreadSysIdToThreadHandle(threadSysId); - if(threadHandle) - { - size_t count = GetBacktraceFromThreadHandle(addressArray, addressArrayCapacity, skipCount, threadHandle); - FreeThreadHandle(threadHandle); - return count; - } - return 0; - - #elif defined(OVR_OS_APPLE) - mach_port_t threadCurrent = pthread_mach_thread_np(pthread_self()); - mach_port_t thread = (mach_port_t)threadSysId; - - if(thread == threadCurrent) - { - return GetBacktrace(addressArray, addressArrayCapacity, skipCount, nullptr); - } - else - { - kern_return_t result = thread_suspend(thread); // Do we need to do this if it's an thread who exception is being handled? - size_t count = 0; - - if(result == KERN_SUCCESS) - { - #if defined(OVR_CPU_X86) || defined(OVR_CPU_X86_64) - x86_thread_state_t threadState; - #elif defined(OVR_CPU_ARM) - arm_thread_state_t threadState; - #endif - mach_msg_type_number_t stateCount = MACHINE_THREAD_STATE_COUNT; - - result = thread_get_state(thread, MACHINE_THREAD_STATE, (natural_t*)(uintptr_t)&threadState, &stateCount); - - if(result == KERN_SUCCESS) - count = GetBacktrace(addressArray, addressArrayCapacity, skipCount, &threadState, threadSysId); - - thread_resume(thread); - - return count; - } - } - - return 0; - - #elif defined(OVR_OS_LINUX) - // To do. - OVR_UNUSED(addressArray); - OVR_UNUSED(addressArrayCapacity); - OVR_UNUSED(skipCount); - OVR_UNUSED(threadSysId); - return 0; - #endif -} - - -// We need to return the required moduleInfoArrayCapacity. -size_t SymbolLookup::GetModuleInfoArray(ModuleInfo* pModuleInfoArray, size_t moduleInfoArrayCapacity) -{ - #if defined(OVR_OS_MS) - size_t moduleCountRequired = 0; // The count we would copy to pModuleInfoArray if moduleInfoArrayCapacity was enough. - size_t moduleCount = 0; // The count we actually copy to pModuleInfoArray. Will be <= moduleInfoArrayCapacity. - HANDLE hProcess = GetCurrentProcess(); - HMODULE hModuleArray[200]; - DWORD cbNeeded = 0; - MODULEINFO mi; - - if(EnumProcessModules(hProcess, hModuleArray, sizeof(hModuleArray), &cbNeeded)) - { - moduleCountRequired = ((cbNeeded / sizeof(HMODULE)) < OVR_ARRAY_COUNT(hModuleArray)) ? (cbNeeded / sizeof(HMODULE)) : OVR_ARRAY_COUNT(hModuleArray); - moduleCount = MIN(moduleCountRequired, OVR_ARRAY_COUNT(hModuleArray)); - moduleCount = MIN(moduleCount, moduleInfoArrayCapacity); - - for(size_t i = 0; i < moduleCount; i++) - { - ModuleInfo& moduleInfo = pModuleInfoArray[i]; - - memset(&mi, 0, sizeof(mi)); - BOOL result = GetModuleInformation(hProcess, hModuleArray[i], &mi, sizeof(mi)); - - if(result) - { - wchar_t pathW[MAX_PATH]; - char pathA[MAX_PATH * 3]; // *3 to handle UTF8 multibyte encoding. - - moduleInfo.handle = hModuleArray[i]; - moduleInfo.baseAddress = (uintptr_t)mi.lpBaseOfDll; - moduleInfo.size = mi.SizeOfImage; - - GetModuleFileNameW(hModuleArray[i], pathW, OVR_ARRAY_COUNT(pathW)); - OVR::UTF8Util::EncodeString(pathA, pathW, -1); // Problem: DecodeString provides no way to specify the destination capacity. - OVR::OVR_strlcpy(moduleInfo.filePath, pathA, OVR_ARRAY_COUNT(moduleInfo.filePath)); - - const char* fileName = GetFileNameFromPath(pathA); - OVR::OVR_strlcpy(moduleInfo.name, fileName, OVR_ARRAY_COUNT(moduleInfo.name)); - } - else - { - moduleInfo.handle = 0; - moduleInfo.baseAddress = 0; - moduleInfo.size = 0; - moduleInfo.filePath[0] = 0; - moduleInfo.name[0] = 0; - } - } - } - - return moduleCountRequired; - - #elif defined(OVR_OS_MAC) - size_t moduleCountRequired = 0; - size_t moduleCount = 0; - - struct MacModuleInfo // This struct exists solely so we can have a local function within this function.. - { - static void AddMacModuleInfo(ModuleInfo* pModuleInfoArrayL, size_t& moduleCountRequiredL, size_t& moduleCountL, size_t moduleInfoArrayCapacityL, - const char* pTypeFilterL, const char* pModulePath, uintptr_t currentSegmentPos, const MachHeader* pMachHeader, uint64_t offset) - { - for(size_t i = 0; i < pMachHeader->ncmds; i++) - { - const SegmentCommand* pSegmentCommand = reinterpret_cast<const SegmentCommand*>(currentSegmentPos); - - if(pSegmentCommand->cmd == kLCSegment) - { - const size_t segnameSize = (sizeof(pSegmentCommand->segname) + 1); // +1 so we can have a trailing '\0'. - char segname[segnameSize]; - - memcpy(segname, pSegmentCommand->segname, sizeof(pSegmentCommand->segname)); - segname[segnameSize - 1] = '\0'; - - if(!pTypeFilterL || OVR_strncmp(segname, pTypeFilterL, sizeof(segname))) - { - moduleCountRequiredL++; - - if(moduleCountL < moduleInfoArrayCapacityL) - { - ModuleInfo& info = pModuleInfoArrayL[moduleCountL++]; - - info.baseAddress = (uint64_t)(pSegmentCommand->vmaddr + offset); - info.handle = reinterpret_cast<ModuleHandle>((uintptr_t)info.baseAddress); - info.size = (uint64_t)pSegmentCommand->vmsize; - OVR_strlcpy(info.filePath, pModulePath, OVR_ARRAY_COUNT(info.filePath)); - OVR_strlcpy(info.name, GetFileNameFromPath(pModulePath), OVR_ARRAY_COUNT(info.name)); - - info.permissions[0] = (pSegmentCommand->initprot & VM_PROT_READ) ? 'r' : '-'; - info.permissions[1] = (pSegmentCommand->initprot & VM_PROT_WRITE) ? 'w' : '-'; - info.permissions[2] = (pSegmentCommand->initprot & VM_PROT_EXECUTE) ? 'x' : '-'; - info.permissions[3] = '/'; - info.permissions[4] = (pSegmentCommand->maxprot & VM_PROT_READ) ? 'r' : '-'; - info.permissions[5] = (pSegmentCommand->maxprot & VM_PROT_WRITE) ? 'w' : '-'; - info.permissions[6] = (pSegmentCommand->maxprot & VM_PROT_EXECUTE) ? 'x' : '-'; - info.permissions[7] = '\0'; - - OVR_strlcpy(info.type, pSegmentCommand->segname, OVR_ARRAY_COUNT(info.type)); - } - } - } - - currentSegmentPos += pSegmentCommand->cmdsize; - } - } - }; - - // Iterate dyld_all_image_infos->infoArray - const struct dyld_all_image_infos* pAllImageInfos = _dyld_get_all_image_infos(); - - for(uint32_t i = 0; i < pAllImageInfos->infoArrayCount; i++) - { - const char* pModulePath = pAllImageInfos->infoArray[i].imageFilePath; - - if(pModulePath && *pModulePath) - { - uintptr_t currentSegmentPos = (uintptr_t)pAllImageInfos->infoArray[i].imageLoadAddress; - const MachHeader* pMachHeader = reinterpret_cast<const MachHeader*>(currentSegmentPos); - uint64_t offset = (uint64_t)_dyld_get_image_vmaddr_slide(i); - - currentSegmentPos += sizeof(*pMachHeader); - - MacModuleInfo::AddMacModuleInfo(pModuleInfoArray, moduleCountRequired, moduleCount, moduleInfoArrayCapacity, - nullptr /*"__TEXT"*/, pModulePath, currentSegmentPos, pMachHeader, offset); - } - } - - // In addition to iterating dyld_all_image_infos->infoArray we need to also iterate /usr/lib/dyld entries. - const MachHeader* pMachHeader = (const MachHeader*)pAllImageInfos->dyldImageLoadAddress; - uintptr_t currentSegmentPos = (uintptr_t)pMachHeader + sizeof(*pMachHeader); - char modulePath[OVR_MAX_PATH] = ""; - pid_t pid = getpid(); - int filenameLen = proc_regionfilename((int)pid, currentSegmentPos, modulePath, (uint32_t)sizeof(modulePath)); - - if(filenameLen > 0) - MacModuleInfo::AddMacModuleInfo(pModuleInfoArray, moduleCountRequired, moduleCount, moduleInfoArrayCapacity, - "__TEXT", modulePath, currentSegmentPos, pMachHeader, 0); - - return moduleCountRequired; - - #elif defined(EA_PLATFORM_LINUX) - // One approach is to read /proc/self/maps, which is supported by Linux (though not BSD). - // Linux glibc dladdr() can tell us what module an arbitrary function address comes from, but can't tell us the list of modules. - OVR_UNUSED(pModuleInfoArray); - OVR_UNUSED(moduleInfoArrayCapacity); - return 0; - - #else - OVR_UNUSED(pModuleInfoArray); - OVR_UNUSED(moduleInfoArrayCapacity); - return 0; - #endif -} - - -size_t SymbolLookup::GetThreadList(ThreadHandle* threadHandleArray, ThreadSysId* threadSysIdArray, size_t threadArrayCapacity) -{ - size_t countRequired = 0; - size_t count = 0; - - #if defined(OVR_OS_MS) - // Print a list of threads. - DWORD currentProcessId = GetCurrentProcessId(); - HANDLE hThreadSnap = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, currentProcessId); // ICreateToolhelp32Snapshot actually ignores currentProcessId. - - if(hThreadSnap != INVALID_HANDLE_VALUE) - { - THREADENTRY32 te32; - te32.dwSize = sizeof(THREADENTRY32); - - if(Thread32First(hThreadSnap, &te32)) - { - do - { - if(te32.th32OwnerProcessID == currentProcessId) - { - HANDLE hThread = ConvertThreadSysIdToThreadHandle(te32.th32ThreadID); - - if(hThread) - { - ++countRequired; - - if((threadHandleArray || threadSysIdArray) && (count < threadArrayCapacity)) - { - if(threadHandleArray) - threadHandleArray[count] = hThread; // The caller must call CloseHandle on this thread, or call DoneThreadList on the returned array. - if(threadSysIdArray) - threadSysIdArray[count] = ConvertThreadHandleToThreadSysId(hThread); - ++count; - } - - if(!threadHandleArray) // If we aren't giving this back to the user... - FreeThreadHandle(hThread); - } - } - } while(Thread32Next(hThreadSnap, &te32)); - } - - CloseHandle(hThreadSnap); - } - - #elif defined(OVR_OS_APPLE) - mach_port_t taskSelf = mach_task_self(); - thread_act_port_array_t threadArray; - mach_msg_type_number_t threadCount; - - kern_return_t result = task_threads(taskSelf, &threadArray, &threadCount); - - if(result == KERN_SUCCESS) - { - for(mach_msg_type_number_t i = 0; i < threadCount; i++) - { - ++countRequired; - - if((threadHandleArray || threadSysIdArray) && (count < threadArrayCapacity)) - { - if(threadHandleArray) - threadHandleArray[count] = pthread_from_mach_thread_np(threadArray[i]); - if(threadSysIdArray) - threadSysIdArray[count] = threadArray[i]; - ++count; - } - } - - vm_deallocate(taskSelf, (vm_address_t)threadArray, threadCount * sizeof(thread_act_t)); - } - - #elif defined(OVR_OS_LINUX) - // To do. - OVR_UNUSED(count); - OVR_UNUSED(threadHandleArray); - OVR_UNUSED(threadSysIdArray); - OVR_UNUSED(threadArrayCapacity); - #endif - - return countRequired; -} - - -void SymbolLookup::DoneThreadList(ThreadHandle* threadHandleArray, ThreadSysId* threadSysIdArray, size_t threadArrayCount) -{ - #if defined(OVR_OS_MS) - for(size_t i = 0; i != threadArrayCount; ++i) - { - if(threadHandleArray[i]) - { - CloseHandle(threadHandleArray[i]); - threadHandleArray[i] = OVR_THREADHANDLE_INVALID; - } - } - - OVR_UNUSED(threadSysIdArray); - #else - OVR_UNUSED(threadHandleArray); - OVR_UNUSED(threadSysIdArray); - OVR_UNUSED(threadArrayCount); - #endif -} - - -// Writes a given thread's callstack wity symbols to the given output. -// It may not be safe to call this from an exception handler, as sOutput allocates memory. -bool SymbolLookup::ReportThreadCallstack(OVR::String& sOutput, size_t skipCount, ThreadSysId threadSysId) -{ - if(!threadSysId) - threadSysId = GetCurrentThreadSysId(); - - void* addressArray[64]; - size_t addressCount = GetBacktraceFromThreadSysId(addressArray, OVR_ARRAY_COUNT(addressArray), skipCount, threadSysId); - - // Print the header - char headerBuffer[256]; - char threadName[32]; - char threadHandleStr[24]; - char threadSysIdStr[24]; - char stackBaseStr[24]; - char stackLimitStr[24]; - void* pStackBase; - void* pStackLimit; - //void* pStackCurrent; // Current stack pointer. To do: support reporting this. - ThreadHandle threadHandle = ConvertThreadSysIdToThreadHandle(threadSysId); - OVR::GetThreadStackBounds(pStackBase, pStackLimit, threadHandle); - - Thread::GetThreadName(threadName, OVR_ARRAY_COUNT(threadName), threadName); - SprintfThreadHandle(threadHandleStr, OVR_ARRAY_COUNT(threadHandleStr), threadHandle); - SprintfThreadSysId(threadSysIdStr, OVR_ARRAY_COUNT(threadSysIdStr), threadSysId); - SprintfAddress(stackBaseStr, OVR_ARRAY_COUNT(stackBaseStr), pStackBase); - SprintfAddress(stackLimitStr, OVR_ARRAY_COUNT(stackLimitStr), pStackLimit); - - if(threadName[0]) - OVR_snprintf(headerBuffer, OVR_ARRAY_COUNT(headerBuffer), "Thread \"%s\" handle: %s, id: %s, stack base: %s, stack limit: %s\r\n", threadName, threadHandleStr, threadSysIdStr, stackBaseStr, stackLimitStr); - else - OVR_snprintf(headerBuffer, OVR_ARRAY_COUNT(headerBuffer), "Thread handle: %s, id: %s, stack base: %s, stack limit: %s\r\n", threadHandleStr, threadSysIdStr, stackBaseStr, stackLimitStr); - - sOutput += headerBuffer; - - // Print the backtrace info - char backtraceBuffer[1024]; // Sometimes function symbol names are very long. - SymbolInfo symbolInfo; - const char* pModuleName; - - if(addressCount == 0) - { - sOutput += "<Unable to read backtrace>\r\n"; - } - else - { - for(size_t i = 0; i < addressCount; ++i) - { - LookupSymbol((uint64_t)addressArray[i], symbolInfo); - - if(symbolInfo.pModuleInfo && symbolInfo.pModuleInfo->name[0]) - pModuleName = symbolInfo.pModuleInfo->name; - else - pModuleName = "(unknown module)"; - - char addressStr[24]; - SprintfAddress(addressStr, OVR_ARRAY_COUNT(addressStr), addressArray[i]); - - if(symbolInfo.filePath[0]) - OVR_snprintf(backtraceBuffer, OVR_ARRAY_COUNT(backtraceBuffer), "%-2u %-24s %s %s+%d %s:%d\r\n", (unsigned)i, pModuleName, addressStr, symbolInfo.function, symbolInfo.functionOffset, symbolInfo.filePath, symbolInfo.fileLineNumber); - else - OVR_snprintf(backtraceBuffer, OVR_ARRAY_COUNT(backtraceBuffer), "%-2u %-24s %s %s+%d\r\n", (unsigned)i, pModuleName, addressStr, symbolInfo.function, symbolInfo.functionOffset); - - sOutput += backtraceBuffer; - } - } - - FreeThreadHandle(threadHandle); - - return (addressCount > 0); -} - - -// Writes all thread's callstacks with symbols to the given output. -// It may not be safe to call this from an exception handler, as sOutput allocates memory. -bool SymbolLookup::ReportThreadCallstacks(OVR::String& sOutput, size_t skipCount) -{ - ThreadSysId threadSysIdArray[64]; - size_t threadSysIdCount = GetThreadList(nullptr, threadSysIdArray, OVR_ARRAY_COUNT(threadSysIdArray)); - - if(threadSysIdCount > OVR_ARRAY_COUNT(threadSysIdArray)) - threadSysIdCount = OVR_ARRAY_COUNT(threadSysIdArray); - - for(size_t i = 0; i < threadSysIdCount; i++) - { - String sTemp; - ReportThreadCallstack(sTemp, skipCount, threadSysIdArray[i]); - if(i > 0) - sOutput += "\r\n"; - sOutput += sTemp; - } - - return (threadSysIdCount > 0); -} - - -bool SymbolLookup::RefreshModuleList() -{ - if(!moduleListUpdated) - { - #if defined(OVR_OS_MS) - // We can't rely on SymRefreshModuleList because it's present in DbgHelp 6.5, - // which doesn't distribute with Windows 7. - - // Currently we support only refreshing the list once ever. With a little effort we could revise this code to - // support re-refreshing the list at runtime to account for the possibility that modules have recently been - // added or removed. - if(pSymLoadModule64) - { - const size_t requiredCount = GetModuleInfoArray(moduleInfoArray, OVR_ARRAY_COUNT(moduleInfoArray)); - moduleInfoArraySize = MIN(requiredCount, OVR_ARRAY_COUNT(moduleInfoArray)); - - HANDLE hProcess = GetCurrentProcess(); - - for(size_t i = 0; i < moduleInfoArraySize; i++) - pSymLoadModule64(hProcess, nullptr, moduleInfoArray[i].filePath, nullptr, moduleInfoArray[i].baseAddress, (DWORD)moduleInfoArray[i].size); - - moduleListUpdated = true; - } - #else - const size_t requiredCount = GetModuleInfoArray(moduleInfoArray, OVR_ARRAY_COUNT(moduleInfoArray)); - moduleInfoArraySize = MIN(requiredCount, OVR_ARRAY_COUNT(moduleInfoArray)); - moduleListUpdated = true; - #endif - } - - return true; -} - - -bool SymbolLookup::LookupSymbol(uint64_t address, SymbolInfo& symbolInfo) -{ - return LookupSymbols(&address, &symbolInfo, 1); -} - - -bool SymbolLookup::LookupSymbols(uint64_t* addressArray, SymbolInfo* pSymbolInfoArray, size_t arraySize) -{ - if(!moduleListUpdated) - { - RefreshModuleList(); - } - - #if defined(OVR_OS_MS) - union SYMBOL_INFO_UNION - { - SYMBOL_INFO msSymbolInfo; - char suffixPadding[sizeof(SYMBOL_INFO) + 1024]; - }; - - for(size_t i = 0; i < arraySize; i++) - { - uint64_t& address = addressArray[i]; - SymbolInfo& symbolInfo = pSymbolInfoArray[i]; - - // Copy the address and ModuleInfo - symbolInfo.address = addressArray[i]; - symbolInfo.pModuleInfo = GetModuleInfoForAddress(address); // We could also use siu.msSymbolInfo.ModBase to get the module slightly faster. - - // Get the function/offset. - SYMBOL_INFO_UNION siu; - memset(&siu, 0, sizeof(siu)); - siu.msSymbolInfo.SizeOfStruct = sizeof(siu.msSymbolInfo); - siu.msSymbolInfo.MaxNameLen = sizeof(siu.suffixPadding) - sizeof(SYMBOL_INFO) + 1; // +1 because SYMBOL_INFO itself has Name[1]. - - HANDLE hProcess = GetCurrentProcess(); - DWORD64 displacement64 = 0; - bool bResult = (pSymFromAddr != nullptr) && (pSymFromAddr(hProcess, address, &displacement64, &siu.msSymbolInfo) != FALSE); - - if(bResult) - { - symbolInfo.size = siu.msSymbolInfo.Size; - OVR_strlcpy(symbolInfo.function, siu.msSymbolInfo.Name, OVR_ARRAY_COUNT(symbolInfo.function)); - symbolInfo.functionOffset = (int32_t)displacement64; - } - else - { - symbolInfo.size = kMISizeInvalid; - symbolInfo.function[0] = 0; - symbolInfo.functionOffset = kMIFunctionOffsetInvalid; - } - - // Get the file/line - IMAGEHLP_LINE64 iLine64; - DWORD displacement = 0; - memset(&iLine64, 0, sizeof(iLine64)); - iLine64.SizeOfStruct = sizeof(iLine64); - - bResult = (pSymGetLineFromAddr64 != nullptr) && (pSymGetLineFromAddr64(hProcess, address, &displacement, &iLine64) != FALSE); - - if(bResult) - { - OVR_strlcpy(symbolInfo.filePath, iLine64.FileName, OVR_ARRAY_COUNT(symbolInfo.filePath)); - symbolInfo.fileLineNumber = (int32_t)iLine64.LineNumber; - } - else - { - symbolInfo.filePath[0] = 0; - symbolInfo.fileLineNumber = kMILineNumberInvalid; - } - - // To do: get the source code when possible. We need to use the user-registered directory paths and the symbolInfo.filePath - // and find the given file in the tree(s), then open the file and find the symbolInfo.fileLineNumber line (and surrounding lines). - // symbolInfo.sourceCode[1024] - symbolInfo.sourceCode[0] = '\0'; - } - - #elif defined(OVR_OS_APPLE) - // Apple has an internal CoreSymbolication library which could help with this. - // Third party implementations of the CoreSymbolication header are available and could be used - // to get file/line info better than other means. It used Objective C, so we'll need a .m or .mm file. - - memset(pSymbolInfoArray, 0, arraySize * sizeof(SymbolInfo)); - - for(size_t i = 0; i < arraySize; i++) - { - pSymbolInfoArray[i].address = addressArray[i]; - pSymbolInfoArray[i].pModuleInfo = GetModuleInfoForAddress(addressArray[i]); - } - - // Problem: backtrace_symbols allocates memory from malloc. If you got into a SIGSEGV due to - // malloc arena corruption (quite common) you will likely fault in backtrace_symbols. - // To do: Use allowMemoryAllocation here. - - #if (OVR_PTR_SIZE == 4) - // backtrace_symbols takes a void* array, but we have a uint64_t array. So for 32 bit we - // need to convert the 64 bit array to 32 bit temporarily for the backtrace_symbols call. - void* ptr32Array[256]; // To do: Remove this limit. - for(size_t i = 0, iEnd = MIN(arraySize, OVR_ARRAY_COUNT(ptr32Array)); i < iEnd; i++) - ptr32Array[i] = reinterpret_cast<void*>(addressArray[i]); - char** symbolArray = backtrace_symbols(reinterpret_cast<void**>(ptr32Array), (int)arraySize); - #else - char** symbolArray = backtrace_symbols(reinterpret_cast<void**>(addressArray), (int)arraySize); - #endif - - if(symbolArray) - { - for(size_t i = 0; i < arraySize; i++) - { - - // Generates a string like this: "0 OculusWorldDemo 0x000000010000cfd5 _ZN18OculusWorldDemoApp9OnStartupEiPPKc + 213" - static_assert(OVR_ARRAY_COUNT(pSymbolInfoArray[i].function) == 128, "Need to change the string format size below"); - - sscanf(symbolArray[i], "%*d %*s %*x %128s + %d", pSymbolInfoArray[i].function, &pSymbolInfoArray[i].functionOffset); - - if(allowMemoryAllocation) - { - int status = 0; - char* strDemangled = abi::__cxa_demangle(pSymbolInfoArray[i].function, nullptr, nullptr, &status); - - if(strDemangled) - { - OVR_strlcpy(pSymbolInfoArray[i].function, strDemangled, OVR_ARRAY_COUNT(pSymbolInfoArray[i].function)); - free(strDemangled); - } - } - } - - free(symbolArray); - } - - // To consider: use CoreSybolication to get file/line info instead. atos is a bit slow and cumbersome. - // https://developer.apple.com/library/mac/documentation/Darwin/Reference/ManPages/man1/atos.1.html - // atos -p <pid> <addr> <addr> ... - // atos -o <binary image path> -l <load-address> <addr> <addr> ... - // Generates output like this: "OVR::CreateException(OVR::CreateExceptionType) (in OculusWorldDemo) (ExceptionHandler.cpp:598)" - for(size_t i = 0; i < arraySize; i++) - { - struct stat statStruct; - - if(pSymbolInfoArray[i].pModuleInfo && pSymbolInfoArray[i].pModuleInfo->filePath[0] && (stat(pSymbolInfoArray[i].pModuleInfo->filePath, &statStruct) == 0)) - { - char command[PATH_MAX * 2]; // Problem: We can't unilaterally use pSymbolInfoArray[0] for all addresses. We need to match addresses to the corresponding modules. - OVR_snprintf(command, OVR_ARRAY_COUNT(command), "atos -o %s -l 0x%llx 0x%llx", - pSymbolInfoArray[i].pModuleInfo->filePath, (int64_t)pSymbolInfoArray[i].pModuleInfo->baseAddress, (int64_t)pSymbolInfoArray[i].address); - - char output[512]; - if(SpawnShellCommand(command, output, OVR_ARRAY_COUNT(output)) != (size_t)-1) - { - char* pLastOpenParen = strrchr(output, '('); - char* pColon = strrchr(output, ':'); - - if(pLastOpenParen && (pColon > pLastOpenParen)) - { - *pColon = '\0'; - OVR_strlcpy(pSymbolInfoArray[i].filePath, pLastOpenParen + 1, OVR_ARRAY_COUNT(pSymbolInfoArray[i].filePath)); - } - } - } - } - - #elif defined(OVR_OS_LINUX) - // We can use libunwind's unw_get_proc_name to try to get function name info. It can work regardless of relocation. - // Use backtrace_symbols and addr2line. Need to watch out for module load-time relocation. - // Ned to pass the -rdynamic flag to the linker. It will cause the linker to out in the link - // tables the name of all the none static functions in your code, not just the exported ones. - OVR_UNUSED(addressArray); - OVR_UNUSED(pSymbolInfoArray); - OVR_UNUSED(arraySize); - #endif - - return true; // To do: Return true only if something was found. -} - - -const ModuleInfo* SymbolLookup::GetModuleInfoForAddress(uint64_t address) -{ - // This is a linear seach. To consider: it would be significantly faster to search by - // address if we ordered it by base address and did a binary search. - for(size_t i = 0; i < moduleInfoArraySize; ++i) - { - const ModuleInfo& mi = moduleInfoArray[i]; - - if((mi.baseAddress <= address) && (address < (mi.baseAddress + mi.size))) - return &mi; - } - - return nullptr; -} - - - - -ExceptionInfo::ExceptionInfo() - : time() - , timeVal(0) - , backtrace() - , backtraceCount(0) - , threadHandle(OVR_THREADHANDLE_INVALID) - , threadSysId(OVR_THREADSYSID_INVALID) - , threadName() - , pExceptionInstructionAddress(nullptr) - , pExceptionMemoryAddress(nullptr) - , cpuContext() - , exceptionDescription() - , symbolInfo() - #if defined(OVR_OS_MS) - , exceptionRecord() - #elif defined(OVR_OS_APPLE) - , exceptionType(0) - , cpuExceptionId(0) - , cpuExceptionIdError(0) - , machExceptionDetail() - , machExceptionDetailCount(0) - #endif -{ -} - - - -ExceptionHandler::ExceptionHandler() - : enabled(false) - , reportPrivacyEnabled(true) - , exceptionResponse(kERHandle) - , exceptionListener(nullptr) - , exceptionListenerUserValue(0) - , appDescription() - , codeBasePathArray() - , reportFilePath() - , miniDumpFlags(0) - , miniDumpFilePath() - , file(nullptr) - , scratchBuffer() - , exceptionOccurred(false) - , handlingBusy(0) - , reportFilePathActual() - , minidumpFilePathActual() - , terminateReturnValue(0) - , exceptionInfo() - #if defined(OVR_OS_MS) - , vectoredHandle(nullptr) - , previousFilter(nullptr) - , pExceptionPointers(nullptr) - #elif defined(OVR_OS_MAC) - , machHandlerInitialized(false) - , machExceptionPort(0) - , machExceptionPortsSaved() - , machThreadShouldContinue(false) - , machThreadExecuting(false) - , machThread((pthread_t)OVR_THREADHANDLE_INVALID) - #endif -{ - SetExceptionPaths("default", "default"); -} - - -ExceptionHandler::~ExceptionHandler() -{ - if(enabled) - { - Enable(false); - } -} - - -#if defined(OVR_OS_MS) - static ExceptionHandler* sExceptionHandler = nullptr; - - LONG WINAPI Win32ExceptionFilter(LPEXCEPTION_POINTERS pExceptionPointers) - { - if(sExceptionHandler) - return (LONG)sExceptionHandler->ExceptionFilter(pExceptionPointers); - return EXCEPTION_CONTINUE_SEARCH; - } - - LONG ExceptionHandler::ExceptionFilter(LPEXCEPTION_POINTERS pExceptionPointers) - { - // Exception codes < 0x80000000 are not true exceptions but rather are debugger notifications. They include DBG_TERMINATE_THREAD, - // DBG_TERMINATE_PROCESS, DBG_CONTROL_BREAK, DBG_COMMAND_EXCEPTION, DBG_CONTROL_C, DBG_PRINTEXCEPTION_C, DBG_RIPEXCEPTION, - // and 0x406d1388 (thread named, http://blogs.msdn.com/b/stevejs/archive/2005/12/19/505815.aspx). - - if(pExceptionPointers->ExceptionRecord->ExceptionCode < 0x80000000) - return EXCEPTION_CONTINUE_SEARCH; - - // VC++ C++ exceptions use code 0xe06d7363 ('Emsc') - // http://support.microsoft.com/kb/185294 - // http://blogs.msdn.com/b/oldnewthing/archive/2010/07/30/10044061.aspx - if(pExceptionPointers->ExceptionRecord->ExceptionCode == 0xe06d7363) - return EXCEPTION_CONTINUE_SEARCH; - - if(handlingBusy.CompareAndSet_Acquire(0, 1)) // If we can successfully change it from 0 to 1. - { - exceptionOccurred = true; - - this->pExceptionPointers = pExceptionPointers; - - // Disable the handler while we do this processing. - ULONG result = RemoveVectoredExceptionHandler(vectoredHandle); - OVR_ASSERT_AND_UNUSED(result != 0, result); - - // Time - exceptionInfo.timeVal = time(nullptr); - exceptionInfo.time = *gmtime(&exceptionInfo.timeVal); - - // Thread id - // This is the thread id of the current thread and not the exception thread. - if(!DuplicateHandle(GetCurrentProcess(), GetCurrentThread(), GetCurrentProcess(), &exceptionInfo.threadHandle, 0, true, DUPLICATE_SAME_ACCESS)) - exceptionInfo.threadHandle = 0; - exceptionInfo.threadSysId = ConvertThreadHandleToThreadSysId(exceptionInfo.threadHandle); - - OVR::GetThreadName(exceptionInfo.threadHandle, exceptionInfo.threadName, OVR_ARRAY_COUNT(exceptionInfo.threadName)); - - // Backtraces - exceptionInfo.backtraceCount = symbolLookup.GetBacktrace(exceptionInfo.backtrace, OVR_ARRAY_COUNT(exceptionInfo.backtrace)); - - // Context - exceptionInfo.cpuContext = *pExceptionPointers->ContextRecord; - exceptionInfo.exceptionRecord = *pExceptionPointers->ExceptionRecord; - exceptionInfo.pExceptionInstructionAddress = exceptionInfo.exceptionRecord.ExceptionAddress; - if((exceptionInfo.exceptionRecord.ExceptionCode == EXCEPTION_ACCESS_VIOLATION) || (exceptionInfo.exceptionRecord.ExceptionCode == EXCEPTION_IN_PAGE_ERROR)) - exceptionInfo.pExceptionMemoryAddress = (void*)exceptionInfo.exceptionRecord.ExceptionInformation[1]; // ExceptionInformation[0] indicates if it was a read (0), write (1), or data execution attempt (8). - else - exceptionInfo.pExceptionMemoryAddress = pExceptionPointers->ExceptionRecord->ExceptionAddress; - - WriteExceptionDescription(); - - if(miniDumpFilePath[0]) - WriteMiniDump(); - - if(reportFilePath[0]) - WriteReport(); - - if(exceptionListener) - exceptionListener->HandleException(exceptionListenerUserValue, this, &exceptionInfo, reportFilePathActual); - - if(exceptionInfo.threadHandle) - { - CloseHandle(exceptionInfo.threadHandle); - exceptionInfo.threadHandle = 0; - } - - // Restore the handler that we temporarily disabled above. - vectoredHandle = AddVectoredExceptionHandler(1, Win32ExceptionFilter); - - handlingBusy.Store_Release(0); - } - - if(exceptionResponse == ExceptionHandler::kERTerminate) - { - TerminateProcess(GetCurrentProcess(), (UINT)terminateReturnValue); - return terminateReturnValue; - } - else if(exceptionResponse == ExceptionHandler::kERThrow) - return EXCEPTION_CONTINUE_SEARCH; - else if(exceptionResponse == ExceptionHandler::kERContinue) - return EXCEPTION_CONTINUE_EXECUTION; - return EXCEPTION_EXECUTE_HANDLER; - } - -#endif // defined(OVR_OS_MS) - - -#if defined(OVR_OS_APPLE) - // http://www.opensource.apple.com/source/xnu/xnu-2050.22.13/ - // http://www.opensource.apple.com/source/xnu/xnu-2050.22.13/osfmk/man/ - // http://www.opensource.apple.com/source/Libc/Libc-825.26/ - // https://mikeash.com/pyblog/friday-qa-2013-01-11-mach-exception-handlers.html - - void* ExceptionHandler::MachHandlerThreadFunction() - { - __Request__mach_exception_raise_state_identity_t msg; - __Reply__mach_exception_raise_state_identity_t reply; - mach_msg_return_t result; - - machThreadExecuting = true; - pthread_setname_np("ExceptionHandler"); - - while(machThreadShouldContinue) - { - mach_msg_option_t options = MACH_RCV_MSG | MACH_RCV_LARGE; - natural_t timeout = 0; // Would be better to support a non-zero time. - - if(timeout) - options |= MACH_RCV_TIMEOUT; - - result = mach_msg(&msg.Head, options, 0, sizeof(msg), machExceptionPort, timeout, MACH_PORT_NULL); - - if(msg.Head.msgh_id != sMachCancelMessageType) - { - if(result == MACH_MSG_SUCCESS) - { - if(mach_exc_server_OVR(&msg.Head, &reply.Head) == 0) //This will call our HandleMachException function. - result = ~MACH_MSG_SUCCESS; - } - - // Send the reply - if(result == MACH_MSG_SUCCESS) - { - result = mach_msg(&reply.Head, MACH_SEND_MSG, reply.Head.msgh_size, 0, MACH_PORT_NULL, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL); - - if(result != MACH_MSG_SUCCESS) - { - // Failure. - } - } - } - } - - machThreadExecuting = false; - - return nullptr; - } - - - kern_return_t ExceptionHandler::HandleMachException(mach_port_t /*machPort*/, mach_port_t threadSysId, mach_port_t machTask, - exception_type_t machExceptionType, mach_exception_data_type_t* pExceptionDetail, - mach_msg_type_number_t exceptionDetailCount, int* /*pMachExceptionFlavor*/, thread_state_t threadStatePrev, - mach_msg_type_number_t /*threadStatePrevCount*/, thread_state_t /*threadStateNew*/, - mach_msg_type_number_t* /*pThreadStateNewCount*/) - { - // We don't want to handle exceptions for other processes. - if(machTask != mach_task_self()) - return ForwardMachException(threadSysId, machTask, machExceptionType, pExceptionDetail, exceptionDetailCount); - - if(handlingBusy.CompareAndSet_Acquire(0, 1)) // If we can successfully change it from 0 to 1. - { - exceptionOccurred = true; - - // Disable the handler while we do this processing. - // To do. - - // Time - exceptionInfo.timeVal = time(nullptr); - exceptionInfo.time = *gmtime(&exceptionInfo.timeVal); - - // Thread id - exceptionInfo.threadHandle = pthread_from_mach_thread_np(threadSysId); - exceptionInfo.threadSysId = threadSysId; - pthread_getname_np((pthread_t)exceptionInfo.threadHandle, exceptionInfo.threadName, sizeof(exceptionInfo.threadName)); - - // Backtraces - exceptionInfo.backtraceCount = symbolLookup.GetBacktraceFromThreadSysId(exceptionInfo.backtrace, OVR_ARRAY_COUNT(exceptionInfo.backtrace), 0, threadSysId); - - // Context - #if defined(OVR_CPU_X86) || defined(OVR_CPU_X86_64) - // We can read x86_THREAD_STATE directly fromk threadStatePrev. - exceptionInfo.cpuContext.threadState = *reinterpret_cast<x86_thread_state_t*>(threadStatePrev); - - mach_msg_type_number_t stateCount = x86_FLOAT_STATE_COUNT; - thread_get_state(threadSysId, x86_FLOAT_STATE, (natural_t*)&exceptionInfo.cpuContext.floatState, &stateCount); - - stateCount = x86_DEBUG_STATE_COUNT; - thread_get_state(threadSysId, x86_DEBUG_STATE, (natural_t*)&exceptionInfo.cpuContext.debugState, &stateCount); - - stateCount = x86_AVX_STATE_COUNT; - thread_get_state(threadSysId, x86_AVX_STATE, (natural_t*)&exceptionInfo.cpuContext.avxState, &stateCount); - - stateCount = x86_EXCEPTION_STATE_COUNT; - thread_get_state(threadSysId, x86_EXCEPTION_STATE, (natural_t*)&exceptionInfo.cpuContext.exceptionState, &stateCount); - - #if defined(OVR_CPU_X86) - exceptionInfo.pExceptionInstructionAddress = (void*)exceptionInfo.cpuContext.threadState.uts.ts32.__eip; - exceptionInfo.pExceptionMemoryAddress = (void*)exceptionInfo.cpuContext.exceptionState.ues.es32.__faultvaddr; - exceptionInfo.cpuExceptionId = exceptionInfo.cpuContext.exceptionState.ues.es32.__trapno; - exceptionInfo.cpuExceptionIdError = exceptionInfo.cpuContext.exceptionState.ues.es32.__err; - #else - exceptionInfo.pExceptionInstructionAddress = (void*)exceptionInfo.cpuContext.threadState.uts.ts64.__rip; - exceptionInfo.pExceptionMemoryAddress = (void*)exceptionInfo.cpuContext.exceptionState.ues.es64.__faultvaddr; - exceptionInfo.cpuExceptionId = exceptionInfo.cpuContext.exceptionState.ues.es64.__trapno; - exceptionInfo.cpuExceptionIdError = exceptionInfo.cpuContext.exceptionState.ues.es64.__err; - #endif - #endif - - exceptionInfo.exceptionType = machExceptionType; - - exceptionInfo.machExceptionDetailCount = MIN(exceptionDetailCount, OVR_ARRAY_COUNT(exceptionInfo.machExceptionDetail)); - for(int i = 0; i < exceptionInfo.machExceptionDetailCount; i++) - exceptionInfo.machExceptionDetail[i] = pExceptionDetail[i]; - - WriteExceptionDescription(); - - if(reportFilePath[0]) - WriteReport(); - - if(miniDumpFilePath[0]) - WriteMiniDump(); - - if(exceptionListener) - exceptionListener->HandleException(exceptionListenerUserValue, this, &exceptionInfo, reportFilePathActual); - - // Re-restore the handler. - // To do. - - handlingBusy.Store_Release(0); - } - - kern_return_t result = KERN_FAILURE; // By default pass on the exception to another handler after we are done here. - - if(exceptionResponse == ExceptionHandler::kERTerminate) - ::exit(terminateReturnValue); - else if(exceptionResponse == ExceptionHandler::kERThrow) - ForwardMachException(threadSysId, machTask, machExceptionType, pExceptionDetail, exceptionDetailCount); - else if(exceptionResponse == ExceptionHandler::kERDefault) - ::exit(terminateReturnValue); - else if(exceptionResponse == ExceptionHandler::kERContinue) - result = KERN_SUCCESS; // This will trigger a re-execution of the function. - - return result; - } - - - bool ExceptionHandler::InitMachExceptionHandler() - { - if(!machHandlerInitialized) - { - mach_port_t machTaskSelf = mach_task_self(); - kern_return_t result = MACH_MSG_SUCCESS; - exception_mask_t mask = EXC_MASK_BAD_ACCESS | EXC_MASK_BAD_INSTRUCTION | EXC_MASK_ARITHMETIC | EXC_MASK_CRASH; - - if(machExceptionPort == MACH_PORT_NULL) - { - result = mach_port_allocate(machTaskSelf, MACH_PORT_RIGHT_RECEIVE, &machExceptionPort); - - if(result == MACH_MSG_SUCCESS) - { - result = mach_port_insert_right(machTaskSelf, machExceptionPort, machExceptionPort, MACH_MSG_TYPE_MAKE_SEND); - - if(result == MACH_MSG_SUCCESS) - result = task_get_exception_ports(machTaskSelf, mask, machExceptionPortsSaved.masks, &machExceptionPortsSaved.count, - machExceptionPortsSaved.ports, machExceptionPortsSaved.behaviors, machExceptionPortsSaved.flavors); - } - } - - if(result == MACH_MSG_SUCCESS) - { - result = task_set_exception_ports(machTaskSelf, mask, machExceptionPort, EXCEPTION_STATE_IDENTITY | MACH_EXCEPTION_CODES, MACHINE_THREAD_STATE); - - if(result == MACH_MSG_SUCCESS) - { - machThreadShouldContinue = true; - - pthread_attr_t attr; - pthread_attr_init(&attr); - - result = pthread_create(&machThread, &attr, MachHandlerThreadFunctionStatic, (void*)this); - pthread_attr_destroy(&attr); - - machHandlerInitialized = (result == 0); - } - } - - if(!machHandlerInitialized) - ShutdownMachExceptionHandler(); - } - - return machHandlerInitialized; - } - - - void ExceptionHandler::ShutdownMachExceptionHandler() - { - if(machThreadExecuting) - { - machThreadShouldContinue = false; // Tell it to stop. - - // Cancel the current exception handler thread (which is probably blocking in a call to mach_msg) by sending it a cencel message. - struct CancelMessage - { - mach_msg_header_t msgHeader; - }; - - CancelMessage msg; - memset(&msg.msgHeader, 0, sizeof(CancelMessage)); - msg.msgHeader.msgh_id = sMachCancelMessageType; - msg.msgHeader.msgh_size = sizeof(CancelMessage); - msg.msgHeader.msgh_bits = MACH_MSGH_BITS_REMOTE(MACH_MSG_TYPE_MAKE_SEND); - msg.msgHeader.msgh_remote_port = machExceptionPort; - msg.msgHeader.msgh_local_port = MACH_PORT_NULL; - - mach_msg_return_t result = mach_msg(&msg.msgHeader, MACH_SEND_MSG, msg.msgHeader.msgh_size, 0, MACH_PORT_NULL, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL); - - if(result == MACH_MSG_SUCCESS) - { - const double threeSecondsLater = ovr_GetTimeInSeconds() + 3.f; - - while(machThreadExecuting && (ovr_GetTimeInSeconds() < threeSecondsLater)) - { - timespec ts = { 0, 1000000000 }; - nanosleep(&ts, nullptr); - } - } - - void* joinResult = nullptr; - pthread_join(machThread, &joinResult); - machThread = 0; - } - - if(machExceptionPort != MACH_PORT_NULL) - { - // Restore the previous ports - kern_return_t result = KERN_SUCCESS; - mach_port_t machTaskSelf = mach_task_self(); - - for(unsigned i = 0; (i < machExceptionPortsSaved.count) && (result == KERN_SUCCESS); i++) - { - result = task_set_exception_ports(machTaskSelf, machExceptionPortsSaved.masks[i], machExceptionPortsSaved.ports[i], - machExceptionPortsSaved.behaviors[i], machExceptionPortsSaved.flavors[i]); - } - - mach_port_deallocate(machTaskSelf, machExceptionPort); - machExceptionPort = MACH_PORT_NULL; - } - - machHandlerInitialized = false; - } - - - kern_return_t ExceptionHandler::ForwardMachException(mach_port_t thread, mach_port_t task, exception_type_t exceptionType, - mach_exception_data_t pExceptionDetail, mach_msg_type_number_t exceptionDetailCount) - { - kern_return_t result = KERN_FAILURE; - mach_msg_type_number_t i; - - for(i = 0; i < machExceptionPortsSaved.count; i++) - { - if(machExceptionPortsSaved.masks[i] & (1 << exceptionType)) - break; - } - - if(i < machExceptionPortsSaved.count) - { - mach_port_t port = machExceptionPortsSaved.ports[i]; - exception_behavior_t behavior = machExceptionPortsSaved.behaviors[i]; - thread_state_flavor_t flavor = machExceptionPortsSaved.flavors[i]; - mach_msg_type_number_t threadStateCount = THREAD_STATE_MAX; - thread_state_data_t threadState; - - if(behavior != EXCEPTION_DEFAULT) - thread_get_state(thread, flavor, threadState, &threadStateCount); - - switch(behavior) - { - case EXCEPTION_DEFAULT: - result = mach_exception_raise_OVR(port, thread, task, exceptionType, pExceptionDetail, exceptionDetailCount); - break; - - case EXCEPTION_STATE: - result = mach_exception_raise_state_OVR(port, exceptionType, pExceptionDetail, exceptionDetailCount, - &flavor, threadState, threadStateCount, threadState, &threadStateCount); - break; - - case EXCEPTION_STATE_IDENTITY: - result = mach_exception_raise_state_identity_OVR(port, thread, task, exceptionType, pExceptionDetail, - exceptionDetailCount, &flavor, threadState, threadStateCount, threadState, &threadStateCount); - break; - - default: - result = KERN_FAILURE; - break; - } - - if(behavior != EXCEPTION_DEFAULT) - result = thread_set_state(thread, flavor, threadState, threadStateCount); - } - - return result; - } - - -#endif // OVR_OS_APPLE - - -bool ExceptionHandler::Enable(bool enable) -{ - #if defined(OVR_OS_MS) - if(enable && !enabled) - { - OVR_ASSERT(vectoredHandle == nullptr); - vectoredHandle = AddVectoredExceptionHandler(1, Win32ExceptionFilter); // Windows call. - enabled = (vectoredHandle != nullptr); - OVR_ASSERT(enabled); - sExceptionHandler = this; - return enabled; - } - else if(!enable && enabled) - { - if(sExceptionHandler == this) - sExceptionHandler = nullptr; - OVR_ASSERT(vectoredHandle != nullptr); - ULONG result = RemoveVectoredExceptionHandler(vectoredHandle); // Windows call. - OVR_ASSERT_AND_UNUSED(result != 0, result); - vectoredHandle = nullptr; - enabled = false; - return true; - } - - #elif defined(OVR_OS_APPLE) - - if(enable && !enabled) - { - enabled = InitMachExceptionHandler(); - OVR_ASSERT(enabled); - sExceptionHandler = this; - return enabled; - } - else if(!enable && enabled) - { - if(sExceptionHandler == this) - sExceptionHandler = nullptr; - ShutdownMachExceptionHandler(); - enabled = false; - return true; - } - #else - OVR_UNUSED(enable); - #endif - - return true; -} - - -void ExceptionHandler::EnableReportPrivacy(bool enable) -{ - reportPrivacyEnabled = enable; -} - -void ExceptionHandler::WriteExceptionDescription() -{ - #if defined(OVR_OS_MS) - // There is some extra information available for AV exception. - if(exceptionInfo.exceptionRecord.ExceptionCode == EXCEPTION_ACCESS_VIOLATION) - { - const char* error = (exceptionInfo.exceptionRecord.ExceptionInformation[0] == 0) ? "reading" : - ((exceptionInfo.exceptionRecord.ExceptionInformation[0] == 1) ? "writing" : "executing"); - - char addressStr[24]; - SprintfAddress(addressStr, OVR_ARRAY_COUNT(addressStr), exceptionInfo.pExceptionMemoryAddress); - OVR::OVR_snprintf(exceptionInfo.exceptionDescription, OVR_ARRAY_COUNT(exceptionInfo.exceptionDescription), "ACCESS_VIOLATION %s address %s", error, addressStr); - } - else - { - exceptionInfo.exceptionDescription[0] = 0; - - // Process "standard" exceptions, other than 'access violation' - #define FORMAT_EXCEPTION(x) \ - case EXCEPTION_##x: \ - OVR::OVR_strlcpy(exceptionInfo.exceptionDescription, #x, OVR_ARRAY_COUNT(exceptionInfo.exceptionDescription)); \ - break; - - switch(exceptionInfo.exceptionRecord.ExceptionCode) - { - //FORMAT_EXCEPTION(ACCESS_VIOLATION) Already handled above. - FORMAT_EXCEPTION(DATATYPE_MISALIGNMENT) - FORMAT_EXCEPTION(BREAKPOINT) - FORMAT_EXCEPTION(SINGLE_STEP) - FORMAT_EXCEPTION(ARRAY_BOUNDS_EXCEEDED) - FORMAT_EXCEPTION(FLT_DENORMAL_OPERAND) - FORMAT_EXCEPTION(FLT_DIVIDE_BY_ZERO) - FORMAT_EXCEPTION(FLT_INEXACT_RESULT) - FORMAT_EXCEPTION(FLT_INVALID_OPERATION) - FORMAT_EXCEPTION(FLT_OVERFLOW) - FORMAT_EXCEPTION(FLT_STACK_CHECK) - FORMAT_EXCEPTION(FLT_UNDERFLOW) - FORMAT_EXCEPTION(INT_DIVIDE_BY_ZERO) - FORMAT_EXCEPTION(INT_OVERFLOW) - FORMAT_EXCEPTION(PRIV_INSTRUCTION) - FORMAT_EXCEPTION(IN_PAGE_ERROR) - FORMAT_EXCEPTION(ILLEGAL_INSTRUCTION) - FORMAT_EXCEPTION(NONCONTINUABLE_EXCEPTION) - FORMAT_EXCEPTION(STACK_OVERFLOW) - FORMAT_EXCEPTION(INVALID_DISPOSITION) - FORMAT_EXCEPTION(GUARD_PAGE) - FORMAT_EXCEPTION(INVALID_HANDLE) - #if defined(EXCEPTION_POSSIBLE_DEADLOCK) && defined(STATUS_POSSIBLE_DEADLOCK) // This type seems to be non-existant in practice. - FORMAT_EXCEPTION(POSSIBLE_DEADLOCK) - #endif - } - - // If not one of the "known" exceptions, try to get the string from NTDLL.DLL's message table. - if(exceptionInfo.exceptionDescription[0] == 0) - { - char addressStr[24]; - SprintfAddress(addressStr, OVR_ARRAY_COUNT(addressStr), exceptionInfo.pExceptionMemoryAddress); - - #if !defined(OVR_OS_CONSOLE) // If FormatMessage is supported... - char buffer[384]; - DWORD capacity = OVR_ARRAY_COUNT(buffer); - - const size_t length = (size_t)FormatMessageA(FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_HMODULE, - GetModuleHandleW(L"NTDLL.DLL"), exceptionInfo.exceptionRecord.ExceptionCode, 0, buffer, capacity, nullptr); - if(length) - OVR::OVR_snprintf(exceptionInfo.exceptionDescription, OVR_ARRAY_COUNT(exceptionInfo.exceptionDescription), - "%s at instruction %s", buffer, addressStr); - #endif - - // If everything else failed just show the hex code. - if(exceptionInfo.exceptionDescription[0] == 0) - OVR::OVR_snprintf(exceptionInfo.exceptionDescription, OVR_ARRAY_COUNT(exceptionInfo.exceptionDescription), - "Unknown exception 0x%08x at instruction %s", exceptionInfo.exceptionRecord.ExceptionCode, addressStr); - } - } - - #elif defined(OVR_OS_APPLE) - struct MachExceptionInfo - { - static const char* GetCPUExceptionIdString(uint32_t cpuExceptionId) - { - const char* id; - - #if defined(OVR_CPU_X86) || defined(OVR_CPU_X86_64) - switch (cpuExceptionId) - { - case 0: id = "integer div/0"; break; - case 1: id = "breakpoint fault"; break; - case 2: id = "non-maskable interrupt"; break; - case 3: id = "int 3"; break; - case 4: id = "overflow"; break; - case 5: id = "bounds check failure"; break; - case 6: id = "invalid instruction"; break; - case 7: id = "coprocessor unavailable"; break; - case 8: id = "exception within exception"; break; - case 9: id = "coprocessor segment overrun"; break; - case 10: id = "invalid task switch"; break; - case 11: id = "segment not present"; break; - case 12: id = "stack exception"; break; - case 13: id = "general protection fault"; break; - case 14: id = "page fault"; break; - case 16: id = "coprocessor error"; break; - default: id = "<unknown>"; break; - } - #else - // To do: Support ARM or others. - #endif - - return id; - } - - static const char* GetMachExceptionTypeString(uint64_t exceptionCause) - { - switch (exceptionCause) - { - case EXC_ARITHMETIC: return "EXC_ARITHMETIC"; - case EXC_BAD_ACCESS: return "EXC_BAD_ACCESS"; - case EXC_BAD_INSTRUCTION: return "EXC_BAD_INSTRUCTION"; - case EXC_BREAKPOINT: return "EXC_BREAKPOINT"; - case EXC_CRASH: return "EXC_CRASH"; - case EXC_EMULATION: return "EXC_EMULATION"; - case EXC_MACH_SYSCALL: return "EXC_MACH_SYSCALL"; - case EXC_RPC_ALERT: return "EXC_RPC_ALERT"; - case EXC_SOFTWARE: return "EXC_SOFTWARE"; - case EXC_SYSCALL: return "EXC_SYSCALL"; - }; - - return "EXC_<unknown>"; - } - - static const char* GetMachExceptionIdString(uint64_t machExceptionId, uint64_t code0) - { - const char* id = "<unknown>"; - - #if defined(OVR_CPU_X86) || defined(OVR_CPU_X86_64) - switch (machExceptionId) - { - case EXC_ARITHMETIC: - switch (code0) - { - case EXC_I386_BOUND: id = "EXC_I386_BOUND"; break; - case EXC_I386_DIV: id = "EXC_I386_DIV"; break; - case EXC_I386_EMERR: id = "EXC_I386_EMERR"; break; - case EXC_I386_EXTERR: id = "EXC_I386_EXTERR"; break; - case EXC_I386_EXTOVR: id = "EXC_I386_EXTOVR"; break; - case EXC_I386_INTO: id = "EXC_I386_INTO"; break; - case EXC_I386_NOEXT: id = "EXC_I386_NOEXT"; break; - case EXC_I386_SSEEXTERR: id = "EXC_I386_SSEEXTERR"; break; - } - break; - - case EXC_BAD_INSTRUCTION: - if(code0 == EXC_I386_INVOP) - id = "EXC_I386_INVOP"; - break; - - case EXC_BREAKPOINT: - if(code0 == EXC_I386_BPT) - id = "EXC_I386_BPT"; - else if(code0 == EXC_I386_SGL) - id = "EXC_I386_SGL"; - break; - }; - #else - // To do. - #endif - - return id; - } - }; - - OVR::OVR_snprintf(exceptionInfo.exceptionDescription, OVR_ARRAY_COUNT(exceptionInfo.exceptionDescription), - "Mach exception type: %llu (%s)\r\n", exceptionInfo.exceptionType, MachExceptionInfo::GetMachExceptionTypeString(exceptionInfo.exceptionType)); - - OVR::OVR_snprintf(scratchBuffer, OVR_ARRAY_COUNT(scratchBuffer), "CPU exception info: exception id: %u (%s), exception id error: %u, fault memory address: %p\r\n", - exceptionInfo.cpuExceptionId, MachExceptionInfo::GetCPUExceptionIdString(exceptionInfo.cpuExceptionId), exceptionInfo.cpuExceptionIdError, exceptionInfo.pExceptionMemoryAddress); - OVR::OVR_strlcat(exceptionInfo.exceptionDescription, scratchBuffer, OVR_ARRAY_COUNT(exceptionInfo.exceptionDescription)); - - - OVR::OVR_snprintf(scratchBuffer, OVR_ARRAY_COUNT(scratchBuffer), "Mach exception info: exception id: %llu (%s), 0x%llx (%llu)\r\n", (uint64_t)exceptionInfo.machExceptionDetail[0], - MachExceptionInfo::GetMachExceptionIdString(exceptionInfo.exceptionType, exceptionInfo.machExceptionDetail[0]), - (uint64_t)exceptionInfo.machExceptionDetail[1], (uint64_t)exceptionInfo.machExceptionDetail[1]); - OVR::OVR_strlcat(exceptionInfo.exceptionDescription, scratchBuffer, OVR_ARRAY_COUNT(exceptionInfo.exceptionDescription)); - #else - // To do. - exceptionInfo.exceptionDescription[0] = 0; - #endif -} - - -void ExceptionHandler::WriteReportLine(const char* pLine) -{ - fwrite(pLine, strlen(pLine), 1, file); -} - - -void ExceptionHandler::WriteReportLineF(const char* format, ...) -{ - va_list args; - va_start(args, format); - int length = OVR_vsnprintf(scratchBuffer, OVR_ARRAY_COUNT(scratchBuffer), format, args); - if(length >= (int)OVR_ARRAY_COUNT(scratchBuffer)) // If we didn't have enough space... - length = (OVR_ARRAY_COUNT(scratchBuffer) - 1); // ... use what we have. - va_end(args); - - fwrite(scratchBuffer, length, 1, file); -} - - -// Thread <name> <handle> <id> -// 0 <module> <address> <function> <file>:<line> -// 1 <module> <address> <function> <file>:<line> -// . . . -// -void ExceptionHandler::WriteThreadCallstack(ThreadHandle threadHandle, ThreadSysId threadSysId, const char* additionalInfo) -{ - // We intentionally do not directly use the SymbolInfo::ReportThreadCallstack function because that function allocates memory, - // which we cannot do due to possibly being within an exception handler. - - // Print the header - char threadName[32]; - char threadHandleStr[32]; - char threadSysIdStr[32]; - char stackBaseStr[24]; - char stackLimitStr[24]; - char stackCurrentStr[24]; - void* pStackBase; - void* pStackLimit; - bool isExceptionThread = (threadSysId == exceptionInfo.threadSysId); - - #if defined(OVR_OS_MS) && (OVR_PTR_SIZE == 8) - void* pStackCurrent = (threadSysId == exceptionInfo.threadSysId) ? (void*)exceptionInfo.cpuContext.Rsp : nullptr; // We would need to suspend the thread, get its context, resume it, then read the rsp register. It turns out we are already doing that suspend/resume below in the backtrace call. - #elif defined(OVR_OS_MS) - void* pStackCurrent = (threadSysId == exceptionInfo.threadSysId) ? (void*)exceptionInfo.cpuContext.Esp : nullptr; - #elif defined(OVR_OS_MAC) && (OVR_PTR_SIZE == 8) - void* pStackCurrent = (threadSysId == exceptionInfo.threadSysId) ? (void*)exceptionInfo.cpuContext.threadState.uts.ts64.__rsp : nullptr; - #elif defined(OVR_OS_MAC) - void* pStackCurrent = (threadSysId == exceptionInfo.threadSysId) ? (void*)exceptionInfo.cpuContext.threadState.uts.ts32.__esp : nullptr; - #elif defined(OVR_OS_LINUX) - void* pStackCurrent = nullptr; // To do. - #endif - - OVR::GetThreadStackBounds(pStackBase, pStackLimit, threadHandle); - - OVR::Thread::GetThreadName(threadName, OVR_ARRAY_COUNT(threadName), threadName); - SprintfThreadHandle(threadHandleStr, OVR_ARRAY_COUNT(threadHandleStr), threadHandle); - SprintfThreadSysId(threadSysIdStr, OVR_ARRAY_COUNT(threadSysIdStr), threadSysId); - SprintfAddress(stackBaseStr, OVR_ARRAY_COUNT(stackBaseStr), pStackBase); - SprintfAddress(stackLimitStr, OVR_ARRAY_COUNT(stackLimitStr), pStackLimit); - SprintfAddress(stackCurrentStr, OVR_ARRAY_COUNT(stackCurrentStr), pStackCurrent); - - if(threadName[0]) - WriteReportLineF("Thread \"%s\" handle: %s, id: %s, stack base: %s, stack limit: %s, stack current: %s, %s\r\n", threadName, threadHandleStr, threadSysIdStr, stackBaseStr, stackLimitStr, stackCurrentStr, additionalInfo ? additionalInfo : ""); - else - WriteReportLineF("Thread handle: %s, id: %s, stack base: %s, stack limit: %s, stack current: %s, %s\r\n", threadHandleStr, threadSysIdStr, stackBaseStr, stackLimitStr, stackCurrentStr, additionalInfo ? additionalInfo : ""); - - // Print the backtrace info - void* addressArray[64]; - size_t addressCount = symbolLookup.GetBacktraceFromThreadSysId(addressArray, OVR_ARRAY_COUNT(addressArray), 0, threadSysId); - SymbolInfo symbolInfo; - const char* pModuleName; - size_t backtraceSkipCount = 0; - - if(isExceptionThread) - { - // If this thread is the exception thread, skip some frames. - #if defined(OVR_OS_MS) - size_t i, iEnd = MIN(16, addressCount); - - for(i = 0; i < iEnd; i++) - { - symbolLookup.LookupSymbol((uint64_t)addressArray[i], symbolInfo); - if(strstr(symbolInfo.function, "UserExceptionDispatcher") != nullptr) - break; - } - - if(i < iEnd) // If found... - backtraceSkipCount = i; - else if(addressCount >= 9) // Else default to 9, which is coincidentally what works. - backtraceSkipCount = 9; - else - backtraceSkipCount = 0; - - addressArray[backtraceSkipCount] = exceptionInfo.pExceptionInstructionAddress; - #endif - } - - if(addressCount == 0) - { - WriteReportLine("<Unable to read backtrace>\r\n\r\n"); - } - else - { - for(size_t i = backtraceSkipCount; i < addressCount; ++i) - { - symbolLookup.LookupSymbol((uint64_t)addressArray[i], symbolInfo); - - if(symbolInfo.pModuleInfo && symbolInfo.pModuleInfo->name[0]) - pModuleName = symbolInfo.pModuleInfo->name; - else - pModuleName = "(unknown module)"; - - char addressStr[24]; - SprintfAddress(addressStr, OVR_ARRAY_COUNT(addressStr), addressArray[i]); - - if(symbolInfo.filePath[0]) - WriteReportLineF("%-2u %-24s %s %s+%d %s:%d\r\n%s", (unsigned)i, pModuleName, addressStr, - symbolInfo.function, symbolInfo.functionOffset, symbolInfo.filePath, - symbolInfo.fileLineNumber, (i + 1) == addressCount ? "\r\n" : ""); - else - WriteReportLineF("%-2u %-24s %s %s+%d\r\n%s", (unsigned)i, pModuleName, addressStr, - symbolInfo.function, symbolInfo.functionOffset, (i + 1) == addressCount ? "\r\n" : ""); // If this is the last line, append another \r\n. - } - } -} - - -void ExceptionHandler::WriteReport() -{ - // It's important that we don't allocate any memory here if we can help it. - using namespace OVR; - - if(strstr(reportFilePath, "%s")) // If the user-specified file path includes a date/time component... - { - char dateTimeBuffer[64]; - FormatDateTime(dateTimeBuffer, OVR_ARRAY_COUNT(dateTimeBuffer), exceptionInfo.timeVal, true, true, false, true); - OVR_snprintf(reportFilePathActual, OVR_ARRAY_COUNT(reportFilePathActual), reportFilePath, dateTimeBuffer); - } - else - { - OVR_strlcpy(reportFilePathActual, reportFilePath, OVR_ARRAY_COUNT(reportFilePathActual)); - } - - file = fopen(reportFilePathActual, "w"); - OVR_ASSERT(file != nullptr); - if(!file) - return; - - symbolLookup.Initialize(); - - { - // Exception information - WriteReportLine("Exception Info\r\n"); - - WriteReportLineF("Exception report file: %s\r\n", reportFilePathActual); - - #if defined(OVR_OS_MS) - if(miniDumpFilePath[0]) - WriteReportLineF("Exception minidump file: %s\r\n", minidumpFilePathActual); - #endif - - char dateTimeBuffer[64]; - FormatDateTime(dateTimeBuffer, OVR_ARRAY_COUNT(dateTimeBuffer), exceptionInfo.timeVal, true, true, false, false); - WriteReportLineF("Time (GMT): %s\r\n", dateTimeBuffer); - - FormatDateTime(dateTimeBuffer, OVR_ARRAY_COUNT(scratchBuffer), exceptionInfo.timeVal, true, true, true, false); - WriteReportLineF("Time (local): %s\r\n", dateTimeBuffer); - WriteReportLineF("Thread name: %s\r\n", exceptionInfo.threadName[0] ? exceptionInfo.threadName : "(not available)"); // It's never possible on Windows to get thread names, as they are stored in the debugger at runtime. - - SprintfThreadHandle(scratchBuffer, OVR_ARRAY_COUNT(scratchBuffer), exceptionInfo.threadHandle); - OVR_strlcat(scratchBuffer, "\r\n", OVR_ARRAY_COUNT(scratchBuffer)); - WriteReportLine("Thread handle: "); - WriteReportLine(scratchBuffer); - - SprintfThreadSysId(scratchBuffer, OVR_ARRAY_COUNT(scratchBuffer), exceptionInfo.threadSysId); - OVR_strlcat(scratchBuffer, "\r\n", OVR_ARRAY_COUNT(scratchBuffer)); - WriteReportLine("Thread sys id: "); - WriteReportLine(scratchBuffer); - - char addressStr[24]; - SprintfAddress(addressStr, OVR_ARRAY_COUNT(addressStr), exceptionInfo.pExceptionInstructionAddress); - WriteReportLineF("Exception instruction address: %s (see callstack below)\r\n", addressStr); - WriteReportLineF("Exception description: %s\r\n", exceptionInfo.exceptionDescription); - - if(symbolLookup.LookupSymbol((uint64_t)exceptionInfo.pExceptionInstructionAddress, exceptionInfo.symbolInfo)) - { - if(exceptionInfo.symbolInfo.filePath[0]) - WriteReportLineF("Exception location: %s (%d)\r\n", exceptionInfo.symbolInfo.filePath, exceptionInfo.symbolInfo.fileLineNumber); - else - WriteReportLineF("Exception location: %s (%d)\r\n", exceptionInfo.symbolInfo.function, exceptionInfo.symbolInfo.functionOffset); - } - - // To consider: print exceptionInfo.cpuContext registers - } - - // OVR information - WriteReportLine("\r\nOVR Info\r\n"); - WriteReportLineF("OVR time: %f\r\n", ovr_GetTimeInSeconds()); - WriteReportLineF("OVR version: %s\r\n", ovr_GetVersionString()); - - // OVR util information - // The following would be useful to use if they didn't allocate memory, which we can't do. - // To do: see if we can have versions of the functions below which don't allocate memory - // or allocate it safely (e.g. use an alternative heap). - // String OVR::GetDisplayDriverVersion(); - // String OVR::GetCameraDriverVersion(); - - // OVR HMD information - WriteReportLine("\r\nOVR HMD Info\r\n"); - - const OVR::List<OVR::CAPI::HMDState>& hmdStateList = OVR::CAPI::HMDState::GetHMDStateList(); - const OVR::CAPI::HMDState* pHMDState = hmdStateList.GetFirst(); - - if(hmdStateList.IsNull(pHMDState)) - { - WriteReportLine("No HMDs found.\r\n"); - } - - while(!hmdStateList.IsNull(pHMDState)) - { - if(pHMDState->pProfile) - { - const char* user = pHMDState->pProfile->GetValue(OVR_KEY_USER); - - if(user) - WriteReportLineF("Profile user: %s\r\n", reportPrivacyEnabled ? "<disabled by report privacy settings>" : user); - else - WriteReportLine("Null profile user\r\n"); - - float NeckEyeDistance[2]; - float EyeToNoseDistance[2]; - float MaxEyeToPlateDist[2]; - pHMDState->pProfile->GetFloatValues(OVR_KEY_NECK_TO_EYE_DISTANCE, NeckEyeDistance, 2); - pHMDState->pProfile->GetFloatValues(OVR_KEY_EYE_TO_NOSE_DISTANCE, EyeToNoseDistance, 2); - pHMDState->pProfile->GetFloatValues(OVR_KEY_MAX_EYE_TO_PLATE_DISTANCE, MaxEyeToPlateDist, 2); - - WriteReportLineF("Player height: %f, eye height: %f, IPD: %f, Neck eye distance: %f,%f, eye relief dial: %d, eye to nose distance: %f,%f, max eye to plate distance: %f,%f, custom eye render: %s\r\n", - pHMDState->pProfile->GetFloatValue(OVR_KEY_PLAYER_HEIGHT, 0.f), - pHMDState->pProfile->GetFloatValue(OVR_KEY_EYE_HEIGHT, 0.f), - pHMDState->pProfile->GetFloatValue(OVR_KEY_IPD, 0.f), - NeckEyeDistance[0], NeckEyeDistance[1], - pHMDState->pProfile->GetIntValue(OVR_KEY_EYE_RELIEF_DIAL, 0), - EyeToNoseDistance[0], EyeToNoseDistance[1], - MaxEyeToPlateDist[0], MaxEyeToPlateDist[1], - pHMDState->pProfile->GetBoolValue(OVR_KEY_CUSTOM_EYE_RENDER, false) ? "yes" : "no"); - - // Not currently used: - // OVR_KEY_NAME - // OVR_KEY_GENDER - // OVR_KEY_EYE_CUP - // OVR_KEY_CAMERA_POSITION - } - else - { - WriteReportLine("Null HMD profile\r\n"); - } - - if(pHMDState->pHmdDesc) // This should usually be true. - { - WriteReportLineF("HMD %d: Type: %u ProductName: %s, Manufacturer: %s VendorId: %d, ProductId: %d, SerialNumber: %s, FirmwareMajor: %d, FirmwareMinor: %d, Resolution: %dx%d, DisplayDeviceName: %s, DisplayId: %d\r\n", - 0, (unsigned)pHMDState->pHmdDesc->Type, pHMDState->pHmdDesc->ProductName, pHMDState->pHmdDesc->Manufacturer, pHMDState->pHmdDesc->VendorId, - pHMDState->pHmdDesc->ProductId, pHMDState->pHmdDesc->SerialNumber, pHMDState->pHmdDesc->FirmwareMajor, pHMDState->pHmdDesc->FirmwareMinor, - pHMDState->pHmdDesc->Resolution.w, pHMDState->pHmdDesc->Resolution.h, pHMDState->pHmdDesc->DisplayDeviceName, pHMDState->pHmdDesc->DisplayId); - - // HSW display state - ovrHSWDisplayState hswDS; - ovrHmd_GetHSWDisplayState(pHMDState->pHmdDesc, &hswDS); - WriteReportLineF("HSW displayed for hmd: %s\r\n", hswDS.Displayed ? "yes" : "no"); - } - - char threadIdStr[24]; - SprintfAddress(threadIdStr, OVR_ARRAY_COUNT(threadIdStr), pHMDState->BeginFrameThreadId); - - WriteReportLineF("Hmd Caps: %x, Hmd Service Caps: %x, Latency test active: %s, Last frame time: %f, Last get frame time: %f, Rendering configred: %s, Begin frame called: %s, Begin frame thread id: %s\r\n", - pHMDState->EnabledHmdCaps, pHMDState->EnabledServiceHmdCaps, pHMDState->LatencyTestActive ? "yes" : "no", pHMDState->LastFrameTimeSeconds, pHMDState->LastGetFrameTimeSeconds, pHMDState->RenderingConfigured ? "yes" : "no", - pHMDState->BeginFrameCalled ? "yes" : "no", threadIdStr); - - if(pHMDState->pLastError) - { - WriteReportLineF("OVR last error for hmd: %s\r\n", pHMDState->pLastError); - } - - pHMDState = hmdStateList.GetNext(pHMDState); - } - - #if defined(OVR_OS_WIN32) - { - WriteReportLine("\r\nApp Info\r\n"); - - // Print the app path. - char appPath[MAX_PATH]; - GetCurrentProcessFilePath(appPath, OVR_ARRAY_COUNT(appPath)); - WriteReportLineF("Process path: %s\r\n", appPath); - - #if (OVR_PTR_SIZE == 4) - WriteReportLine("App format: 32 bit\r\n"); - #else - WriteReportLine("App format: 64 bit\r\n"); - #endif - - // Print the app version - wchar_t pathW[MAX_PATH] = {}; - GetModuleFileNameW(0, pathW, (DWORD)OVR_ARRAY_COUNT(pathW)); - DWORD dwUnused; - DWORD dwSize = GetFileVersionInfoSizeW(pathW, &dwUnused); - scratchBuffer[0] = 0; - - if(dwSize > 0) - { - void* const pVersionData = SafeMMapAlloc(dwSize); - - if(pVersionData) - { - if(GetFileVersionInfoW(pathW, 0, dwSize, pVersionData)) - { - VS_FIXEDFILEINFO* pFFI; - UINT size; - - if(VerQueryValueA(pVersionData, "\\", (void**)&pFFI, &size)) - { - WriteReportLineF("App version: %u.%u.%u.%u\r\n", - HIWORD(pFFI->dwFileVersionMS), LOWORD(pFFI->dwFileVersionMS), - HIWORD(pFFI->dwFileVersionLS), LOWORD(pFFI->dwFileVersionLS)); - } - } - - SafeMMapFree(pVersionData, dwSize); - } - } - - if(!scratchBuffer[0]) // If version info couldn't be found or read... - WriteReportLine("App version info not present\r\n"); - } - - { - WriteReportLine("\r\nSystem Info\r\n"); - - OSVERSIONINFOEXW vi; - memset(&vi, 0, sizeof(vi)); - vi.dwOSVersionInfoSize = sizeof(vi); - GetVersionExW((LPOSVERSIONINFOW)&vi); // Cast to the older type. - - char osVersionName[256]; - GetOSVersionName(osVersionName, OVR_ARRAY_COUNT(osVersionName)); - WriteReportLineF("OS name: %s, version: %u.%u build %u, %s, platform id: %u, service pack: %ls\r\n", - osVersionName, vi.dwMajorVersion, vi.dwMinorVersion, vi.dwBuildNumber, Is64BitOS() ? "64 bit" : "32 bit", - vi.dwPlatformId, vi.szCSDVersion[0] ? vi.szCSDVersion : L"<none>"); - - WriteReportLineF("Debugger present: %s\r\n", OVRIsDebuggerPresent() ? "yes" : "no"); - - // System info - SYSTEM_INFO systemInfo; - GetNativeSystemInfo(&systemInfo); - - WriteReportLineF("Processor count: %u\r\n", systemInfo.dwNumberOfProcessors); - - // Windows Vista and later: - // BOOL WINAPI GetLogicalProcessorInformation(PSYSTEM_LOGICAL_PROCESSOR_INFORMATION Buffer, PDWORD ReturnLength); - - if(systemInfo.wProcessorArchitecture == 0) - WriteReportLineF("Processor type: x86\r\n"); - else if(systemInfo.wProcessorArchitecture == 9) - WriteReportLineF("Processor type: x86-64\r\n"); - else if(systemInfo.wProcessorArchitecture == 10) - WriteReportLineF("Processor type: x86 on x86-64\r\n"); - - WriteReportLineF("Processor level: %u\r\n", systemInfo.wProcessorLevel); - WriteReportLineF("Processor revision: %u\r\n", systemInfo.wProcessorRevision); - - // Memory information - MEMORYSTATUSEX memoryStatusEx; - memset(&memoryStatusEx, 0, sizeof(memoryStatusEx)); - memoryStatusEx.dwLength = sizeof(memoryStatusEx); - GlobalMemoryStatusEx(&memoryStatusEx); - - WriteReportLineF("Memory load: %d%%\r\n", memoryStatusEx.dwMemoryLoad); - WriteReportLineF("Total physical memory: %I64d MiB\r\n", memoryStatusEx.ullTotalPhys / (1024 * 1024)); // Or are Mebibytes equal to (1024 * 1000) - WriteReportLineF("Available physical memory: %I64d MiB\r\n", memoryStatusEx.ullAvailPhys / (1024 * 1024)); - WriteReportLineF("Total page file memory: %I64d MiB\r\n", memoryStatusEx.ullTotalPageFile / (1024 * 1024)); - WriteReportLineF("Available page file memory: %I64d MiB\r\n", memoryStatusEx.ullAvailPageFile / (1024 * 1024)); - WriteReportLineF("Total virtual memory: %I64d MiB\r\n", memoryStatusEx.ullTotalVirtual / (1024 * 1024)); - WriteReportLineF("Free virtual memory: %I64d MiB\r\n", memoryStatusEx.ullAvailVirtual / (1024 * 1024)); - - DISPLAY_DEVICE dd; - memset(&dd, 0, sizeof(DISPLAY_DEVICE)); - dd.cb = sizeof(DISPLAY_DEVICE); - - for(int i = 0; EnumDisplayDevicesW(nullptr, (DWORD)i, &dd, EDD_GET_DEVICE_INTERFACE_NAME); ++i) - { - WriteReportLineF("Display Device %d name: %ls, context: %ls, primary: %s, mirroring: %s\r\n", - i, dd.DeviceName, dd.DeviceString, (dd.StateFlags & DISPLAY_DEVICE_PRIMARY_DEVICE) ? "yes" : "no", (dd.StateFlags & DISPLAY_DEVICE_MIRRORING_DRIVER) ? "yes" : "no"); - } - } - - // Print video card information - // http://msdn.microsoft.com/en-us/library/aa394512%28v=vs.85%29.aspx - { - IWbemLocator* pIWbemLocator = nullptr; - BSTR bstrServer = nullptr; - IWbemServices* pIWbemServices = nullptr; - BSTR bstrWQL = nullptr; - BSTR bstrPath = nullptr; - IEnumWbemClassObject* pEnum = nullptr; - - CoInitializeEx(nullptr, COINIT_MULTITHREADED); - - HRESULT hr = CoCreateInstance(__uuidof(WbemLocator), nullptr, CLSCTX_INPROC_SERVER, __uuidof(IWbemLocator), (LPVOID*)&pIWbemLocator); - if(FAILED(hr)) - goto End; - - bstrServer = SysAllocString(L"\\\\.\\root\\cimv2"); - hr = pIWbemLocator->ConnectServer(bstrServer, nullptr, nullptr, 0L, 0L, nullptr, nullptr, &pIWbemServices); - if(FAILED(hr)) - goto End; - - hr = CoSetProxyBlanket(pIWbemServices, RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE, nullptr, RPC_C_AUTHN_LEVEL_CALL, - RPC_C_IMP_LEVEL_IMPERSONATE, nullptr, EOAC_DEFAULT); - if(FAILED(hr)) - goto End; - - bstrWQL = SysAllocString(L"WQL"); - bstrPath = SysAllocString(L"select * from Win32_VideoController"); - hr = pIWbemServices->ExecQuery(bstrWQL, bstrPath, WBEM_FLAG_FORWARD_ONLY, nullptr, &pEnum); - if(FAILED(hr)) - goto End; - - ULONG uReturned; - IWbemClassObject* pObj = nullptr; - hr = pEnum->Next(WBEM_INFINITE, 1, &pObj, &uReturned); - if(FAILED(hr)) - goto End; - - WriteReportLine("\r\nDisplay adapter list\r\n"); - - for(unsigned i = 0; SUCCEEDED(hr) && uReturned; i++) - { - char sString[256]; - VARIANT var; - - if(i > 0) - WriteReportLine("\r\n"); - - WriteReportLineF("Info for display adapter %u\r\n", i); - - hr = pObj->Get(L"Name", 0, &var, nullptr, nullptr); - if(SUCCEEDED(hr)) - { - WideCharToMultiByte(CP_ACP, 0, var.bstrVal, -1, sString, sizeof(sString), nullptr, nullptr); - WriteReportLineF("Display Adapter Name: %s\r\n", sString); - } - - hr = pObj->Get(L"AdapterRAM", 0, &var, nullptr, nullptr); - if(SUCCEEDED(hr)) - { - WriteReportLineF("Display Adapter RAM: %u %s\r\n", - ((uint32_t)var.lVal > (1024*1024*1024) ? (uint32_t)var.lVal/(1024*1024*1024) : (uint32_t)var.lVal/(1024*1024)), ((uint32_t)var.lVal > (1024*1024*1024) ? "GiB" : "MiB")); - } - - hr = pObj->Get(L"DeviceID", 0, &var, nullptr, nullptr); - if(SUCCEEDED(hr)) - { - WideCharToMultiByte(CP_ACP, 0, var.bstrVal, -1, sString, sizeof(sString), nullptr, nullptr); - WriteReportLineF("Display Adapter DeviceID: %s\r\n", sString); - } - - hr = pObj->Get(L"DriverVersion", 0, &var, nullptr, nullptr); - if(SUCCEEDED(hr)) - { - WideCharToMultiByte(CP_ACP, 0, var.bstrVal, -1, sString, sizeof(sString), nullptr, nullptr); - WriteReportLineF("Display Adapter DriverVersion: %s\r\n", sString); - } - - hr = pObj->Get(L"DriverDate", 0, &var, nullptr, nullptr); - if(SUCCEEDED(hr)) - { - // http://technet.microsoft.com/en-us/library/ee156576.aspx - wchar_t year[5] = { var.bstrVal[0], var.bstrVal[1], var.bstrVal[2], var.bstrVal[3], 0 }; - wchar_t month[3] = { var.bstrVal[4], var.bstrVal[5], 0 }; - wchar_t monthDay[3] = { var.bstrVal[6], var.bstrVal[7], 0 }; - - WriteReportLineF("Display Adapter DriverDate (US format): %ls/%ls/%ls\r\n", month, monthDay, year); - } - - // VideoProcessor - hr = pObj->Get(L"VideoProcessor", 0, &var, nullptr, nullptr); - if(SUCCEEDED(hr)) - { - WideCharToMultiByte(CP_ACP, 0, var.bstrVal, -1, sString, sizeof(sString), nullptr, nullptr); - WriteReportLineF("Display Adapter VideoProcessor %s\r\n", sString); - } - - hr = pObj->Get(L"VideoModeDescription", 0, &var, nullptr, nullptr); - if(SUCCEEDED(hr)) - { - WideCharToMultiByte(CP_ACP, 0, var.bstrVal, -1, sString, sizeof(sString), nullptr, nullptr); - WriteReportLineF("Display Adapter VideoModeDescription: %s\r\n", sString); - } - - pObj->Release(); - - hr = pEnum->Next(WBEM_INFINITE, 1, &pObj, &uReturned); - } - - End: - if(pEnum) - pEnum->Release(); - if(bstrPath) - SysFreeString(bstrPath); - if(bstrWQL) - SysFreeString(bstrWQL); - if(pIWbemServices) - pIWbemServices->Release(); - if(bstrServer) - SysFreeString(bstrServer); - if(pIWbemLocator) - pIWbemLocator->Release(); - - CoUninitialize(); - } - - { - // Print a list of threads. - DWORD currentProcessId = GetCurrentProcessId(); - HANDLE hThreadSnap = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, currentProcessId); // ICreateToolhelp32Snapshot actually ignores currentProcessId. - - if(hThreadSnap != INVALID_HANDLE_VALUE) - { - THREADENTRY32 te32; - te32.dwSize = sizeof(THREADENTRY32); - - if(Thread32First(hThreadSnap, &te32)) - { - WriteReportLine("\r\nThread list\r\n"); - - do { - if(te32.th32OwnerProcessID == currentProcessId) - { - HANDLE hThread = ConvertThreadSysIdToThreadHandle(te32.th32ThreadID); - - if(hThread) - { - char buffer[96]; // Can't use scratchBuffer, because it's used by WriteThreadCallstack. - OVR_snprintf(buffer, OVR_ARRAY_COUNT(buffer), "base priority: %ld, delta priority: %ld", te32.tpBasePri, te32.tpDeltaPri); - - bool threadIsExceptionThread = (te32.th32ThreadID == (DWORD)exceptionInfo.threadSysId); - if(threadIsExceptionThread) - OVR_strlcat(buffer, ", exception thread", OVR_ARRAY_COUNT(buffer)); - - WriteThreadCallstack(hThread, (OVR::ThreadSysId)te32.th32ThreadID, buffer); - FreeThreadHandle(hThread); - } - } - } while(Thread32Next(hThreadSnap, &te32)); - } - - CloseHandle(hThreadSnap); - } - } - - { - // Print a list of the current modules within this process. - // DbgHelp.dll also provides a EnumerateLoadedModules64 function. - // To do: Convert the code below to use the GetModuleInfoArray function which we now have. - #if defined(OVR_OS_CONSOLE) - struct MODULEINFO { - LPVOID lpBaseOfDll; - DWORD SizeOfImage; - LPVOID EntryPoint; - }; - HMODULE hModule = LoadLibraryW(L"toolhelpx.dll"); - #else - HMODULE hModule = LoadLibraryW(L"psapi.dll"); - #endif - - if(hModule) - { - typedef BOOL (WINAPI * ENUMPROCESSMODULES) (HANDLE hProcess, HMODULE* phModule, DWORD cb, LPDWORD lpcbNeeded); - typedef DWORD (WINAPI * GETMODULEBASENAME) (HANDLE hProcess, HMODULE hModule, LPWSTR lpFilename, DWORD nSize); - typedef DWORD (WINAPI * GETMODULEFILENAMEEX) (HANDLE hProcess, HMODULE hModule, LPWSTR lpFilename, DWORD nSize); - typedef BOOL (WINAPI * GETMODULEINFORMATION)(HANDLE hProcess, HMODULE hModule, MODULEINFO* pmi, DWORD nSize); - - #if defined(OVR_OS_CONSOLE) - ENUMPROCESSMODULES pEnumProcessModules = (ENUMPROCESSMODULES) (uintptr_t)GetProcAddress(hModule, "K32EnumProcessModules"); - GETMODULEBASENAME pGetModuleBaseName = (GETMODULEBASENAME) (uintptr_t)GetProcAddress(hModule, "K32GetModuleBaseNameW"); - GETMODULEFILENAMEEX pGetModuleFileNameEx = (GETMODULEFILENAMEEX) (uintptr_t)GetProcAddress(hModule, "K32GetModuleFileNameExW"); - GETMODULEINFORMATION pGetModuleInformation = (GETMODULEINFORMATION)(uintptr_t)GetProcAddress(hModule, "K32GetModuleInformation"); - #else - ENUMPROCESSMODULES pEnumProcessModules = (ENUMPROCESSMODULES) (uintptr_t)GetProcAddress(hModule, "EnumProcessModules"); - GETMODULEBASENAME pGetModuleBaseName = (GETMODULEBASENAME) (uintptr_t)GetProcAddress(hModule, "GetModuleBaseNameW"); - GETMODULEFILENAMEEX pGetModuleFileNameEx = (GETMODULEFILENAMEEX) (uintptr_t)GetProcAddress(hModule, "GetModuleFileNameExW"); - GETMODULEINFORMATION pGetModuleInformation = (GETMODULEINFORMATION)(uintptr_t)GetProcAddress(hModule, "GetModuleInformation"); - #endif - - HANDLE hProcess = GetCurrentProcess(); - HMODULE hModuleArray[200]; - DWORD cbNeeded; - - if(pEnumProcessModules(hProcess, hModuleArray, sizeof(hModuleArray), &cbNeeded)) - { - size_t actualModuleCount = (cbNeeded / sizeof(HMODULE)); - - if(actualModuleCount > OVR_ARRAY_COUNT(hModuleArray)) //If hModuleArray's capacity was not enough... - actualModuleCount = OVR_ARRAY_COUNT(hModuleArray); - - // Print a header - WriteReportLine("\r\nModule list\r\n"); - - #if (OVR_PTR_SIZE == 4) - WriteReportLine("Base Size Entrypoint Name Path\r\n"); - #else - WriteReportLine("Base Size Entrypoint Name Path\r\n"); - #endif - - // And go through the list one by one - for(size_t i = 0; i < actualModuleCount; i++) - { - MODULEINFO mi; - size_t length; - - if(!pGetModuleInformation(hProcess, hModuleArray[i], &mi, sizeof(mi))) - { - mi.EntryPoint = nullptr; - mi.lpBaseOfDll = nullptr; - mi.SizeOfImage = 0; - } - - // Write the base name. - wchar_t name[MAX_PATH + 3]; - name[0] = '"'; - if(pGetModuleBaseName(hProcess, hModuleArray[i], name + 1, MAX_PATH)) - length = wcslen(name); - else - { - wcscpy(name + 1, L"(unknown)"); - length = 10; - } - - name[length] = '"'; - name[length + 1] = '\0'; - - // Write the path - wchar_t path[MAX_PATH + 3]; - path[0] = '"'; - if(pGetModuleFileNameEx(hProcess, hModuleArray[i], path + 1, MAX_PATH)) - length = wcslen(path); - else - { - wcscpy(path + 1, L"(unknown)"); - length = 10; - } - path[length] = '"'; - path[length + 1] = '\0'; - - #if (OVR_PTR_SIZE == 4) - WriteReportLineF("0x%08x, 0x%08x 0x%08x %-24ls %ls\r\n", (uint32_t)mi.lpBaseOfDll, (uint32_t)mi.SizeOfImage, (uint32_t)mi.EntryPoint, name, path); - #else - WriteReportLineF("0x%016I64x 0x%016I64x 0x%016I64x %-24ls %ls\r\n", (uint64_t)mi.lpBaseOfDll, (uint64_t)mi.SizeOfImage, (uint64_t)mi.EntryPoint, name, path); - #endif - } - } - } - } - - { - // Print a list of processes. - // DbgHelp.dll provides a SymEnumProcesses function, but it's available with DbgHelp.dll v6.2 which doesn't ship with Windows until Windows 8. - WriteReportLine("\r\nProcess list\r\n"); - - if(reportPrivacyEnabled) - WriteReportLine("Disabled by report privacy settings\r\n"); - else - { - HANDLE hProcessSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); - - if(hProcessSnapshot != INVALID_HANDLE_VALUE) - { - PROCESSENTRY32W pe32; - memset(&pe32, 0, sizeof(pe32)); - pe32.dwSize = sizeof(pe32); - - if(Process32FirstW(hProcessSnapshot, &pe32)) - { - WriteReportLine("Process Id File\r\n"); - - do { - // Try to get the full path to the process, as pe32.szExeFile holds only the process file name. - // This will typically fail with a privilege error unless this process has debug privileges: http://support.microsoft.com/kb/131065/en-us - wchar_t filePathW[MAX_PATH]; - const wchar_t* pFilePathW = pe32.szExeFile; - HANDLE hProcess = ::OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, pe32.th32ProcessID); // With Windows Vista+ we can use PROCESS_QUERY_LIMITED_INFORMATION. - if(hProcess) - { - if(GetProcessImageFileName(hProcess, filePathW, (DWORD)OVR_ARRAY_COUNT(filePathW))) - pFilePathW = filePathW; - } - - WriteReportLineF("0x%08x %ls\r\n", pe32.th32ProcessID, pFilePathW); - } while(Process32NextW(hProcessSnapshot, &pe32)); - } - - CloseHandle(hProcessSnapshot); - } - else - { - WriteReportLine("Unable to read process list\r\n"); - } - } - } - - #elif defined(OVR_OS_APPLE) - - WriteReportLine("\r\nApp Info\r\n"); - - // App path - const pid_t processId = getpid(); - WriteReportLineF("Process id: ", "%lld (0x%llx)\r\n", (int64_t)processId, (int64_t)processId); - - char appPath[PATH_MAX]; - GetCurrentProcessFilePath(appPath, OVR_ARRAY_COUNT(appPath)); - WriteReportLineF("Process path: %s\r\n", appPath); - - #if (OVR_PTR_SIZE == 4) - WriteReportLine("App format: 32 bit\r\n"); - #else - WriteReportLine("App format: 64 bit\r\n"); - #endif - - // App version - // To do. - - // System Info - WriteReportLine("\r\nSystem Info\r\n"); - - char osVersionName[256]; - GetOSVersionName(osVersionName, OVR_ARRAY_COUNT(osVersionName)); - WriteReportLineF("OS name: %s, %s\r\n", osVersionName, Is64BitOS() ? "64 bit" : "32 bit"); - - int name[2]; - int intValue; - size_t length; - char tempBuffer[256]; - - name[0] = CTL_KERN; - name[1] = KERN_OSTYPE; - length = sizeof(tempBuffer); - tempBuffer[0] = 0; - if(sysctl(name, 2, tempBuffer, &length, nullptr, 0) == 0) - { - WriteReportLineF("KERN_OSTYPE: %s\r\n", tempBuffer); - } - - name[0] = CTL_KERN; - name[1] = KERN_OSREV; - length = sizeof(intValue); - intValue = 0; - if(sysctl(name, 2, &intValue, &length, nullptr, 0) == 0) - { - WriteReportLineF("KERN_OSREV: %d\r\n", intValue); - } - - name[0] = CTL_KERN; - name[1] = KERN_OSRELEASE; - length = sizeof(tempBuffer); - tempBuffer[0] = 0; - if(sysctl(name, 2, tempBuffer, &length, nullptr, 0) == 0) - WriteReportLineF("KERN_OSRELEASE: %s\r\n", tempBuffer); - - name[0] = CTL_HW; - name[1] = HW_MACHINE; - length = sizeof(tempBuffer); - tempBuffer[0] = 0; - if(sysctl(name, 2, tempBuffer, &length, nullptr, 0) == 0) - WriteReportLineF("HW_MACHINE: %s\r\n", tempBuffer); - - name[0] = CTL_HW; - name[1] = HW_MODEL; - length = sizeof(tempBuffer); - tempBuffer[0] = 0; - if(sysctl(name, 2, tempBuffer, &length, nullptr, 0) == 0) - WriteReportLineF("sHW_MODEL: %s\r\n", tempBuffer); - - name[0] = CTL_HW; - name[1] = HW_NCPU; - length = sizeof(intValue); - intValue = 0; - if(sysctl(name, 2, &intValue, &length, nullptr, 0) == 0) - WriteReportLineF("HW_NCPU: %d\r\n", intValue); - - length = sizeof(tempBuffer); - tempBuffer[0] = 0; - if(sysctlbyname("machdep.cpu.brand_string", &tempBuffer, &length, nullptr, 0) == 0) - WriteReportLineF("machdep.cpu.brand_string: %s\r\n", tempBuffer); - - length = sizeof(tempBuffer); - tempBuffer[0] = 0; - if(sysctlbyname("hw.acpi.thermal.tz0.temperature", &tempBuffer, &length, nullptr, 0) == 0) - WriteReportLineF("hw.acpi.thermal.tz0.temperature: %s\r\n", tempBuffer); - - host_basic_info_data_t hostinfo; - mach_msg_type_number_t count = HOST_BASIC_INFO_COUNT; - kern_return_t kr = host_info(mach_host_self(), HOST_BASIC_INFO, (host_info_t)&hostinfo, &count); - - if(kr == KERN_SUCCESS) - { - const uint64_t memoryMib = (uint64_t)hostinfo.max_mem / (1024 * 1024); - WriteReportLineF("System memory: %lld Mib (%.1f Gib)\r\n", memoryMib, (double)memoryMib / 1024); - } - - // Video card info - // To do. - - // Thread list - mach_port_t taskSelf = mach_task_self(); - thread_act_port_array_t threadArray; - mach_msg_type_number_t threadCount; - - kern_return_t result = task_threads(taskSelf, &threadArray, &threadCount); - - if(result == KERN_SUCCESS) - { - WriteReportLine("\r\nThread list\r\n"); - - for(mach_msg_type_number_t i = 0; i < threadCount; i++) - { - union TBIUnion{ - natural_t words[THREAD_INFO_MAX]; - thread_basic_info tbi; - }; - - TBIUnion tbiUnion; - mach_port_t thread = threadArray[i]; - pthread_t pthread = pthread_from_mach_thread_np(thread); // We assume the thread was created through pthreads. - - char threadState[32] = "unknown"; - mach_msg_type_number_t threadInfoCount = THREAD_INFO_MAX; - result = thread_info(thread, THREAD_BASIC_INFO, (thread_info_t)&tbiUnion, &threadInfoCount); - - if(result == KERN_SUCCESS) - { - const char* state; - - switch (tbiUnion.tbi.run_state) - { - case TH_STATE_HALTED: state = "halted"; break; - case TH_STATE_RUNNING: state = "running"; break; - case TH_STATE_STOPPED: state = "stopped"; break; - case TH_STATE_UNINTERRUPTIBLE: state = "uninterruptible"; break; - case TH_STATE_WAITING: state = "waiting"; break; - default: state = "<unknown>"; break; - } - - OVR_snprintf(threadState, OVR_ARRAY_COUNT(threadState), "%s", state); - if(tbiUnion.tbi.flags & TH_FLAGS_IDLE) - OVR_strlcat(threadState, ", idle", sizeof(threadState)); - if(tbiUnion.tbi.flags & TH_FLAGS_SWAPPED) - OVR_strlcat(threadState, ", swapped", sizeof(threadState)); - } - - thread_identifier_info threadIdentifierInfo; - memset(&threadIdentifierInfo, 0, sizeof(threadIdentifierInfo)); - - mach_msg_type_number_t threadIdentifierInfoCount = THREAD_IDENTIFIER_INFO_COUNT; - thread_info(thread, THREAD_IDENTIFIER_INFO, (thread_info_t)&threadIdentifierInfo, &threadIdentifierInfoCount); - - proc_threadinfo procThreadInfo; - memset(&procThreadInfo, 0, sizeof(procThreadInfo)); - result = proc_pidinfo(processId, PROC_PIDTHREADINFO, threadIdentifierInfo.thread_handle, &procThreadInfo, sizeof(procThreadInfo)); - OVR_UNUSED(result); - - char buffer[256]; // Can't use scratchBuffer, because it's used by WriteThreadCallstack. - OVR_snprintf(buffer, OVR_ARRAY_COUNT(buffer), "state: %s, suspend count: %d, kernel priority: %d", threadState, (int)tbiUnion.tbi.suspend_count, (int)procThreadInfo.pth_curpri); - - bool threadIsExceptionThread = (thread == exceptionInfo.threadSysId); - if(threadIsExceptionThread) - OVR_strlcat(buffer, ", exception thread", OVR_ARRAY_COUNT(buffer)); - - WriteThreadCallstack(pthread, thread, buffer); - } - - vm_deallocate(taskSelf, (vm_address_t)threadArray, threadCount * sizeof(thread_act_t)); - } - - - WriteReportLine("\r\nModule list\r\n"); - - const size_t mifCapacity = 256; - const size_t mifAllocSize = mifCapacity * sizeof(ModuleInfo); - ModuleInfo* moduleInfoArray = (ModuleInfo*)SafeMMapAlloc(mifAllocSize); - - if(moduleInfoArray) - { - #if (OVR_PTR_SIZE == 4) - WriteReportLine("Base Size Name Path\r\n"); - #else - WriteReportLine("Base Size Name Path\r\n"); - #endif - - size_t moduleCount = symbolLookup.GetModuleInfoArray(moduleInfoArray, mifCapacity); - if(moduleCount > mifCapacity) - moduleCount = mifCapacity; - - for(size_t i = 0; i < moduleCount; i++) - { - const ModuleInfo& mi = moduleInfoArray[i]; - - #if (OVR_PTR_SIZE == 4) - WriteReportLineF("0x%08x, 0x%08x %-24s %s\r\n", (uint32_t)mi.baseAddress, (uint32_t)mi.size, mi.name, mi.filePath); - #else - WriteReportLineF("0x%016llx 0x%016llx %-24s %s\r\n", (uint64_t)mi.baseAddress, (uint64_t)mi.size, mi.name, mi.filePath); - #endif - } - - SafeMMapFree(moduleInfoArray, mifAllocSize); - } - - - WriteReportLine("\r\nProcess list\r\n"); - - if(reportPrivacyEnabled) - WriteReportLine("Disabled by report privacy settings\r\n"); - else - { - WriteReportLine("Process Id File\r\n"); - - pid_t pidArray[1024]; - int processCount = proc_listpids(PROC_ALL_PIDS, 0, pidArray, sizeof(pidArray)); // Important that we use sizeof not OVR_ARRAY_COUNT. - char processFilePath[PATH_MAX]; - - for(int i = 0; i < processCount; i++) - { - if(proc_pidpath(pidArray[i], processFilePath, sizeof(processFilePath)) > 0) - WriteReportLineF("%-10d %s\r\n", pidArray[i], processFilePath); - } - - if(!processCount) - WriteReportLine("Unable to read process list\r\n"); - } - - #elif defined(OVR_OS_UNIX) - Is64BitOS(); - GetCurrentProcessFilePath(nullptr, 0); - GetFileNameFromPath(nullptr); - GetOSVersionName(nullptr, 0); - - #endif // OVR_OS_MS - - symbolLookup.Shutdown(); - - fclose(file); - file = nullptr; -} - - -void ExceptionHandler::WriteMiniDump() -{ - if(strstr(miniDumpFilePath, "%s")) // If the user-specified file path includes a date/time component... - { - char dateTimeBuffer[64]; - FormatDateTime(dateTimeBuffer, OVR_ARRAY_COUNT(dateTimeBuffer), exceptionInfo.timeVal, true, true, false, true); - OVR_snprintf(minidumpFilePathActual, OVR_ARRAY_COUNT(minidumpFilePathActual), miniDumpFilePath, dateTimeBuffer); - } - else - { - OVR_strlcpy(minidumpFilePathActual, miniDumpFilePath, OVR_ARRAY_COUNT(minidumpFilePathActual)); - } - - #if defined(OVR_OS_WIN32) || defined(OVR_OS_WIN64) || (defined(OVR_OS_MS) && defined(OVR_OS_CONSOLE)) - #if defined(OVR_OS_CONSOLE) - typedef BOOL (WINAPI * MINIDUMPWRITEDUMP)(HANDLE hProcess, DWORD ProcessId, HANDLE hFile, MINIDUMP_TYPE dumpType, CONST PMINIDUMP_EXCEPTION_INFORMATION ExceptionParam, CONST PMINIDUMP_USER_STREAM_INFORMATION UserStreamParam, CONST PVOID CallbackParam); - HMODULE hModuleDbgHelp = LoadLibraryW(L"toolhelpx.dll"); - #else - typedef BOOL (WINAPI * MINIDUMPWRITEDUMP)(HANDLE hProcess, DWORD ProcessId, HANDLE hFile, MINIDUMP_TYPE dumpType, CONST PMINIDUMP_EXCEPTION_INFORMATION ExceptionParam, CONST PMINIDUMP_USER_STREAM_INFORMATION UserStreamParam, CONST PMINIDUMP_CALLBACK_INFORMATION CallbackParam); - HMODULE hModuleDbgHelp = LoadLibraryW(L"DbgHelp.dll"); - #endif - - MINIDUMPWRITEDUMP pMiniDumpWriteDump = hModuleDbgHelp ? (MINIDUMPWRITEDUMP)(void*)GetProcAddress(hModuleDbgHelp, "MiniDumpWriteDump") : nullptr; - - if(pMiniDumpWriteDump) - { - wchar_t miniDumpFilePathW[OVR_MAX_PATH]; - OVR::UTF8Util::DecodeString(miniDumpFilePathW, minidumpFilePathActual, -1); // Problem: DecodeString provides no way to specify the destination capacity. - - HANDLE hFile = CreateFileW(miniDumpFilePathW, GENERIC_READ | GENERIC_WRITE, 0, 0, CREATE_ALWAYS, FILE_FLAG_WRITE_THROUGH, 0); - - if(hFile != INVALID_HANDLE_VALUE) - { - MINIDUMP_EXCEPTION_INFORMATION minidumpExceptionInfo = { ::GetCurrentThreadId(), pExceptionPointers, TRUE }; - - #if defined(OVR_OS_CONSOLE) - BOOL result = pMiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(), hFile, - (MINIDUMP_TYPE)miniDumpType, &exceptionInfo, - (CONST PMINIDUMP_USER_STREAM_INFORMATION)nullptr, nullptr); - #else - BOOL result = pMiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(), hFile, - (MINIDUMP_TYPE)miniDumpFlags, &minidumpExceptionInfo, - (CONST PMINIDUMP_USER_STREAM_INFORMATION)nullptr, (CONST PMINIDUMP_CALLBACK_INFORMATION)nullptr); - #endif - - OVR_ASSERT_AND_UNUSED(result, result); - CloseHandle(hFile); - hFile = 0; - } - else - { - OVR_ASSERT(pMiniDumpWriteDump); // OVR_FAIL_F(("ExceptionHandler::WriteMiniDump: Failed to create minidump file at %s", minidumpFilePathActual)); - } - } - - FreeLibrary(hModuleDbgHelp); - #else - // Some platforms support various forms or exception reports and core dumps which are automatically generated upon us - // returning from our own exception handling. We might want to put something here if we are using a custom version of - // this, such as Google Breakpad. - #endif -} - - -void ExceptionHandler::SetExceptionListener(ExceptionListener* pExceptionListener, uintptr_t userValue) -{ - exceptionListener = pExceptionListener; - exceptionListenerUserValue = userValue; -} - - -void ExceptionHandler::SetAppDescription(const char* pAppDescription) -{ - appDescription = pAppDescription; -} - - -void ExceptionHandler::SetExceptionPaths(const char* exceptionReportPath, const char* exceptionMiniDumpFilePath) -{ - char tempPath[OVR_MAX_PATH]; - - if(exceptionReportPath) - { - if(OVR_stricmp(exceptionReportPath, "default") == 0) - { - GetUserDocumentsDirectory(tempPath, OVR_ARRAY_COUNT(tempPath)); - OVR::OVR_strlcat(tempPath, "Exception Report (%s).txt", OVR_ARRAY_COUNT(tempPath)); - exceptionReportPath = tempPath; - } - - OVR_strlcpy(reportFilePath, exceptionReportPath, OVR_ARRAY_COUNT(reportFilePath)); - } - else - { - reportFilePath[0] = '\0'; - } - - if(exceptionMiniDumpFilePath) - { - if(OVR_stricmp(exceptionMiniDumpFilePath, "default") == 0) - { - GetUserDocumentsDirectory(tempPath, OVR_ARRAY_COUNT(tempPath)); - OVR::OVR_strlcat(tempPath, "Exception Minidump (%s).mdmp", OVR_ARRAY_COUNT(tempPath)); - exceptionMiniDumpFilePath = tempPath; - } - - OVR_strlcpy(miniDumpFilePath, exceptionMiniDumpFilePath, OVR_ARRAY_COUNT(miniDumpFilePath)); - } - else - { - miniDumpFilePath[0] = '\0'; - } -} - - -void ExceptionHandler::SetCodeBaseDirectoryPaths(const char* codeBaseDirectoryPathArray[], size_t codeBaseDirectoryPathCount) -{ - for(size_t i = 0, iCount = OVR::Alg::Min<size_t>(codeBaseDirectoryPathCount, OVR_ARRAY_COUNT(codeBasePathArray)); i != iCount; ++i) - { - codeBasePathArray[i] = codeBaseDirectoryPathArray[i]; - } -} - -const char* ExceptionHandler::GetExceptionUIText(const char* exceptionReportPath) -{ - char* uiText = nullptr; - OVR::SysFile file(exceptionReportPath, SysFile::Open_Read, SysFile::Mode_ReadWrite); - - if(file.IsValid()) - { - size_t length = (size_t)file.GetLength(); - uiText = (char*)OVR::SafeMMapAlloc(length + 1); - - if(uiText) - { - file.Read((uint8_t*)uiText, (int)length); - uiText[length] = '\0'; - file.Close(); - - // Currently on Mac our message box implementation is unable to display arbitrarily large amounts of text. - // So we reduce its size to a more summary version before presenting. - #if defined(OVR_OS_MAC) - struct Find { static char* PreviousChar(char* p, char c){ while(*p != c) p--; return p; } }; // Assumes the given c is present prior to p. - - // Print that the full report is at <file path> - // Exception Info section - // Exception thread callstack. - char empty[] = ""; - char* pExceptionInfoBegin = strstr(uiText, "Exception Info") ? strstr(uiText, "Exception Info") : empty; - char* pExceptionInfoEnd = (pExceptionInfoBegin == empty) ? (empty + 1) : strstr(uiText, "\r\n\r\n"); - char* pExceptionThreadArea = strstr(uiText, ", exception thread"); - char* pExceptionThreadBegin = pExceptionThreadArea ? Find::PreviousChar(pExceptionThreadArea, '\n') + 1 : empty; - char* pExceptionThreadEnd = (pExceptionThreadBegin == empty) ? (empty + 1) : strstr(pExceptionThreadArea, "\r\n\r\n"); - - if(!pExceptionInfoEnd) - pExceptionInfoEnd = pExceptionInfoBegin; - *pExceptionInfoEnd = '\0'; - - if(!pExceptionThreadEnd) - pExceptionThreadEnd = pExceptionThreadBegin; - *pExceptionThreadEnd = '\0'; - - size_t uiTextBriefLength = OVR_snprintf(nullptr, 0, "Full report:%s\n\nSummary report:\n%s\n\n%s", exceptionReportPath, pExceptionInfoBegin, pExceptionThreadBegin); - char* uiTextBrief = (char*)OVR::SafeMMapAlloc(uiTextBriefLength + 1); - - if(uiTextBrief) - { - OVR_snprintf(uiTextBrief, uiTextBriefLength + 1, "Full report:%s\n\nSummary report:\n%s\n\n%s", exceptionReportPath, pExceptionInfoBegin, pExceptionThreadBegin); - OVR::SafeMMapFree(uiText, length); - uiText = uiTextBrief; - } - #endif - } - } - - return uiText; -} - -void ExceptionHandler::FreeExceptionUIText(const char* messageBoxText) -{ - OVR::SafeMMapFree(messageBoxText, OVR_strlen(messageBoxText)); -} - - -} // namespace OVR - - -OVR_RESTORE_MSVC_WARNING() - diff --git a/LibOVR/Src/Kernel/OVR_DebugHelp.h b/LibOVR/Src/Kernel/OVR_DebugHelp.h deleted file mode 100644 index 2430ae4..0000000 --- a/LibOVR/Src/Kernel/OVR_DebugHelp.h +++ /dev/null @@ -1,461 +0,0 @@ -/************************************************************************************ - -Filename : OVR_DebugHelp.h -Content : Platform-independent exception handling interface -Created : October 6, 2014 - -Copyright : Copyright 2014 Oculus VR, LLC. All Rights reserved. - -Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -************************************************************************************/ - -#ifndef OVR_ExceptionHandler_h -#define OVR_ExceptionHandler_h - - -#include "OVR_Types.h" -#include "OVR_String.h" -#include "OVR_Threads.h" -#include "OVR_Atomic.h" -#include "OVR_Nullptr.h" -#include <stdio.h> -#include <time.h> - -#if defined(OVR_OS_WIN32) || defined(OVR_OS_WIN64) - #include <Windows.h> - -#elif defined(OVR_OS_APPLE) - #include <pthread.h> - #include <mach/thread_status.h> - #include <mach/mach_types.h> - - extern "C" void* MachHandlerThreadFunctionStatic(void*); - extern "C" int catch_mach_exception_raise_state_identity_OVR(mach_port_t, mach_port_t, mach_port_t, exception_type_t, mach_exception_data_type_t*, - mach_msg_type_number_t, int*, thread_state_t, mach_msg_type_number_t, thread_state_t, mach_msg_type_number_t*); -#elif defined(OVR_OS_LINUX) - #include <pthread.h> -#endif - - -OVR_DISABLE_MSVC_WARNING(4351) // new behavior: elements of array will be default initialized - - -namespace OVR { - - // Thread identifiers - //typedef void* ThreadHandle; // Already defined by OVR Threads. Same as Windows thread handle, Unix pthread_t. - //typedef void* ThreadId; // Already defined by OVR Threads. Used by Windows as DWORD thread id, by Unix as pthread_t. - typedef uintptr_t ThreadSysId; // System thread identifier. Used by Windows the same as ThreadId (DWORD), thread_act_t on Mac/BSD, lwp id on Linux. - - // Thread constants - // To do: Move to OVR Threads - #define OVR_THREADHANDLE_INVALID ((ThreadHandle*)nullptr) - #define OVR_THREADID_INVALID ((ThreadId*)nullptr) - #define OVR_THREADSYSID_INVALID ((uintptr_t)0) - - OVR::ThreadSysId ConvertThreadHandleToThreadSysId(OVR::ThreadHandle threadHandle); - OVR::ThreadHandle ConvertThreadSysIdToThreadHandle(OVR::ThreadSysId threadSysId); // The returned handle must be freed with FreeThreadHandle. - void FreeThreadHandle(OVR::ThreadHandle threadHandle); // Frees the handle returned by ConvertThreadSysIdToThreadHandle. - OVR::ThreadSysId GetCurrentThreadSysId(); - - // CPUContext - #if defined(OVR_OS_MS) - typedef CONTEXT CPUContext; - #elif defined(OVR_OS_MAC) - struct CPUContext - { - x86_thread_state_t threadState; // This works for both x86 and x64. - x86_float_state_t floatState; - x86_debug_state_t debugState; - x86_avx_state_t avxState; - x86_exception_state exceptionState; - - CPUContext() { memset(this, 0, sizeof(CPUContext)); } - }; - #elif defined(OVR_OS_LINUX) - typedef int CPUContext; // To do. - #endif - - - // Tells if the current process appears to be running under a debugger. Does not attempt to - // detect the case of sleath debuggers (malware-related for example). - bool OVRIsDebuggerPresent(); - - // Exits the process with the given exit code. - #if !defined(OVR_NORETURN) - #if defined(OVR_CC_MSVC) - #define OVR_NORETURN __declspec(noreturn) - #else - #define OVR_NORETURN __attribute__((noreturn)) - #endif - #endif - OVR_NORETURN void ExitProcess(intptr_t processReturnValue); - - // Returns the instruction pointer of the caller for the position right after the call. - OVR_NO_INLINE void GetInstructionPointer(void*& pInstruction); - - // Returns the stack base and limit addresses for the given thread, or for the current thread if the threadHandle is default. - // The stack limit is a value less than the stack base on most platforms, as stacks usually grow downward. - // Some platforms (e.g. Microsoft) have dynamically resizing stacks, in which case the stack limit reflects the current limit. - void GetThreadStackBounds(void*& pStackBase, void*& pStackLimit, ThreadHandle threadHandle = OVR_THREADHANDLE_INVALID); - - - // Equates to VirtualAlloc/VirtualFree on Windows, mmap/munmap on Unix. - // These are useful for when you need system-supplied memory pages. - // These are also useful for when you need to allocate memory in a way - // that doesn't affect the application heap. - void* SafeMMapAlloc(size_t size); - void SafeMMapFree(const void* memory, size_t size); - - - // OVR_MAX_PATH - // Max file path length (for most uses). - // To do: move this to OVR_File. - #if defined(OVR_OS_MS) // http://msdn.microsoft.com/en-us/library/windows/desktop/aa365247%28v=vs.85%29.aspx - #define OVR_MAX_PATH 260 // Windows can use paths longer than this in some cases (network paths, UNC paths). - #else - #define OVR_MAX_PATH 1024 // This isn't a strict limit on all Unix-based platforms. - #endif - - - // ModuleHandle - #if defined(OVR_OS_MS) - typedef void* ModuleHandle; // from LoadLibrary() - #elif defined(OVR_OS_APPLE) || defined(OVR_OS_UNIX) - typedef void* ModuleHandle; // from dlopen() - #endif - - #define OVR_MODULEHANDLE_INVALID ((ModuleHandle*)nullptr) - - - - // Module info constants - static const ModuleHandle kMIHandleInvalid = OVR_MODULEHANDLE_INVALID; - static const uint64_t kMIAddressInvalid = 0xffffffffffffffffull; - static const uint64_t kMISizeInvalid = 0xffffffffffffffffull; - static const int32_t kMILineNumberInvalid = -1; - static const int32_t kMIFunctionOffsetInvalid = -1; - static const uint64_t kMIBaseAddressInvalid = 0xffffffffffffffffull; - static const uint64_t kMIBaseAddressUnspecified = 0xffffffffffffffffull; - - struct ModuleInfo - { - ModuleHandle handle; - uint64_t baseAddress; // The actual runtime base address of the module. May be different from the base address specified in the debug symbol file. - uint64_t size; - char filePath[OVR_MAX_PATH]; - char name[32]; - char type[8]; // Unix-specific. e.g. __TEXT - char permissions[8]; // Unix specific. e.g. "drwxr-xr-x" - - ModuleInfo() : handle(kMIHandleInvalid), baseAddress(kMIBaseAddressInvalid), size(0), filePath(), name(){} - }; - - - // Refers to symbol info for an instruction address. - // Info includes function name, source code file/line, and source code itself. - struct SymbolInfo - { - uint64_t address; - uint64_t size; - const ModuleInfo* pModuleInfo; - char filePath[OVR_MAX_PATH]; - int32_t fileLineNumber; - char function[128]; // This is a fixed size because we need to use it during application exceptions. - int32_t functionOffset; - char sourceCode[1024]; // This is a string representing the code itself and not a file path to the code. - - SymbolInfo() : address(kMIAddressInvalid), size(kMISizeInvalid), pModuleInfo(nullptr), filePath(), - fileLineNumber(kMILineNumberInvalid), function(), functionOffset(kMIFunctionOffsetInvalid), sourceCode() {} - }; - - - // Implements support for reading thread lists, module lists, backtraces, and backtrace symbols. - class SymbolLookup - { - public: - SymbolLookup(); - ~SymbolLookup(); - - void AddSourceCodeDirectory(const char* pDirectory); - - bool Initialize(); - void Shutdown(); - - // Should be disabled when within an exception handler. - void EnableMemoryAllocation(bool enabled); - - // Retrieves the backtrace (call stack) of the given thread. There may be some per-platform restrictions on this. - // Returns the number written, which will be <= addressArrayCapacity. - // This may not work on some platforms unless stack frames are enabled. - // For Microsoft platforms the platformThreadContext is CONTEXT*. - // For Apple platforms the platformThreadContext is x86_thread_state_t* or arm_thread_state_t*. - // If threadSysIdHelp is non-zero, it may be used by the implementation to help produce a better backtrace. - size_t GetBacktrace(void* addressArray[], size_t addressArrayCapacity, size_t skipCount = 0, void* platformThreadContext = nullptr, OVR::ThreadSysId threadSysIdHelp = OVR_THREADSYSID_INVALID); - - // Retrieves the backtrace for the given ThreadHandle. - // Returns the number written, which will be <= addressArrayCapacity. - size_t GetBacktraceFromThreadHandle(void* addressArray[], size_t addressArrayCapacity, size_t skipCount = 0, OVR::ThreadHandle threadHandle = OVR_THREADHANDLE_INVALID); - - // Retrieves the backtrace for the given ThreadSysId. - // Returns the number written, which will be <= addressArrayCapacity. - size_t GetBacktraceFromThreadSysId(void* addressArray[], size_t addressArrayCapacity, size_t skipCount = 0, OVR::ThreadSysId threadSysId = OVR_THREADSYSID_INVALID); - - // Gets a list of the modules (e.g. DLLs) present in the current process. - // Writes as many ModuleInfos as possible to pModuleInfoArray. - // Returns the required count of ModuleInfos, which will be > moduleInfoArrayCapacity if the capacity needs to be larger. - size_t GetModuleInfoArray(ModuleInfo* pModuleInfoArray, size_t moduleInfoArrayCapacity); - - // Retrieves a list of the current threads. Unless the process is paused the list is volatile. - // Returns the required capacity, which may be larger than threadArrayCapacity. - // Either array can be NULL to specify that it's not written to. - // For Windows the caller needs to CloseHandle the returned ThreadHandles. This can be done by calling DoneThreadList. - size_t GetThreadList(ThreadHandle* threadHandleArray, ThreadSysId* threadSysIdArray, size_t threadArrayCapacity); - - // Frees any references to thread handles or ids returned by GetThreadList; - void DoneThreadList(ThreadHandle* threadHandleArray, ThreadSysId* threadSysIdArray, size_t threadArrayCount); - - // Writes a given thread's callstack with symbols to the given output. - // It may not be safe to call this from an exception handler, as sOutput allocates memory. - bool ReportThreadCallstack(OVR::String& sOutput, size_t skipCount = 0, ThreadSysId threadSysId = OVR_THREADSYSID_INVALID); - - // Writes all thread's callstacks with symbols to the given output. - // It may not be safe to call this from an exception handler, as sOutput allocates memory. - bool ReportThreadCallstacks(OVR::String& sOutput, size_t skipCount = 0); - - // Retrieves symbol info for the given address. - bool LookupSymbol(uint64_t address, SymbolInfo& symbolInfo); - bool LookupSymbols(uint64_t* addressArray, SymbolInfo* pSymbolInfoArray, size_t arraySize); - - const ModuleInfo* GetModuleInfoForAddress(uint64_t address); // The returned ModuleInfo points to an internal structure. - - protected: - bool RefreshModuleList(); - - protected: - bool initialized; - bool allowMemoryAllocation; // True by default. If true then we allow allocating memory (and as a result provide less information). This is useful for when in an exception handler. - bool moduleListUpdated; - ModuleInfo moduleInfoArray[96]; // Cached list of modules we use. This is a fixed size because we need to use it during application exceptions. - size_t moduleInfoArraySize; - }; - - - - // ExceptionInfo - // We need to be careful to avoid data types that can allocate memory while we are - // handling an exception, as the memory system may be corrupted at that point in time. - struct ExceptionInfo - { - tm time; // GM time. - time_t timeVal; // GM time_t (seconds since 1970). - void* backtrace[64]; - size_t backtraceCount; - ThreadHandle threadHandle; // - ThreadSysId threadSysId; // - char threadName[32]; // Cannot be an allocating String object. - void* pExceptionInstructionAddress; - void* pExceptionMemoryAddress; - CPUContext cpuContext; - char exceptionDescription[1024]; // Cannot be an allocating String object. - SymbolInfo symbolInfo; // SymbolInfo for the exception location. - - #if defined(OVR_OS_MS) - EXCEPTION_RECORD exceptionRecord; // This is a Windows SDK struct. - #elif defined(OVR_OS_APPLE) - uint64_t exceptionType; // e.g. EXC_BAD_INSTRUCTION, EXC_BAD_ACCESS, etc. - uint32_t cpuExceptionId; // The x86/x64 CPU trap id. - uint32_t cpuExceptionIdError; // The x86/x64 CPU trap id extra info. - int64_t machExceptionDetail[4]; // Kernel exception code info. - int machExceptionDetailCount; // Count of valid entries. - #endif - - ExceptionInfo(); - }; - - - // Implments support for asynchronous exception handling and basic exception report generation. - // If you are implementing exception handling for a commercial application and want auto-uploading - // functionality you may want to consider using something like Google Breakpad. This exception handler - // is for in-application debug/diagnostic services, though it can write a report that has similar - // information to Breakpad or OS-provided reports such as Apple .crash files. - // - // Example usage: - // ExceptionHandler exceptionHandler; - // - // int main(int, char**) - // { - // exceptionHandler.Enable(true); - // exceptionHandler.SetExceptionListener(pSomeListener, 0); // Optional listener hook. - // } - // - class ExceptionHandler - { - public: - ExceptionHandler(); - ~ExceptionHandler(); - - bool Enable(bool enable); - - // Some report info can be considered private information of the user, such as the current process list, - // computer name, IP address or other identifying info, etc. We should not report this information for - // external users unless they agree to this. - void EnableReportPrivacy(bool enable); - - struct ExceptionListener - { - virtual ~ExceptionListener(){} - virtual int HandleException(uintptr_t userValue, ExceptionHandler* pExceptionHandler, ExceptionInfo* pExceptionInfo, const char* reportFilePath) = 0; - }; - - void SetExceptionListener(ExceptionListener* pExceptionListener, uintptr_t userValue); - - // What we do after handling the exception. - enum ExceptionResponse - { - kERContinue, // Continue execution. Will result in the exception being re-generated unless the application has fixed the cause. Similar to Windows EXCEPTION_CONTINUE_EXECUTION. - kERHandle, // Causes the OS to handle the exception as it normally would. Similar to Windows EXCEPTION_EXECUTE_HANDLER. - kERTerminate, // Exit the application. - kERThrow, // Re-throw the exception. Other handlers may catch it. Similar to Windows EXCEPTION_CONTINUE_SEARCH. - kERDefault // Usually set to kERTerminate. - }; - - void SetExceptionResponse(ExceptionResponse er) - { exceptionResponse = er; } - - // Allws you to add an arbitrary description of the current application, which will be added to exception reports. - void SetAppDescription(const char* appDescription); - - // If the report path has a "%s" in its name, then assume the path is a sprintf format and write it - // with the %s specified as a date/time string. - // The report path can be "default" to signify that you want to use the default user location. - // Example usage: - // handler.SetExceptionPaths("/Users/Current/Exceptions/Exception %s.txt"); - void SetExceptionPaths(const char* exceptionReportPath, const char* exceptionMinidumpPath = nullptr); - - // Allows you to specify base directories for code paths, which can be used to associate exception addresses to lines - // of code as opposed to just file names and line numbers, or function names plus binary offsets. - void SetCodeBaseDirectoryPaths(const char* codeBaseDirectoryPathArray[], size_t codeBaseDirectoryPathCount); - - // Given an exception report at a given file path, returns a string suitable for displaying in a message - // box or similar user interface during the handling of an exception. The returned string must be passed - // to FreeMessageBoxText when complete. - static const char* GetExceptionUIText(const char* exceptionReportPath); - static void FreeExceptionUIText(const char* messageBoxText); - - protected: - void WriteExceptionDescription(); - void WriteReport(); - void WriteReportLine(const char* pLine); - void WriteReportLineF(const char* format, ...); - void WriteThreadCallstack(ThreadHandle threadHandle, ThreadSysId threadSysId, const char* additionalInfo); - void WriteMiniDump(); - - // Runtime constants - bool enabled; - bool reportPrivacyEnabled; // Defaults to true. - ExceptionResponse exceptionResponse; // Defaults to kERHandle - ExceptionListener* exceptionListener; - uintptr_t exceptionListenerUserValue; - String appDescription; - String codeBasePathArray[6]; // 6 is arbitrary. - char reportFilePath[OVR_MAX_PATH];// May be an encoded path, in that it has "%s" in it or is named "default". See reporFiletPathActual for the runtime actual report path. - int miniDumpFlags; - char miniDumpFilePath[OVR_MAX_PATH]; - FILE* file; // Can/should we use OVR Files for this? - char scratchBuffer[4096]; - SymbolLookup symbolLookup; - - // Runtime variables - bool exceptionOccurred; - OVR::AtomicInt<uint32_t> handlingBusy; - char reportFilePathActual[OVR_MAX_PATH]; - char minidumpFilePathActual[OVR_MAX_PATH]; - int terminateReturnValue; - ExceptionInfo exceptionInfo; - - #if defined(OVR_OS_MS) - void* vectoredHandle; - LPTOP_LEVEL_EXCEPTION_FILTER previousFilter; - LPEXCEPTION_POINTERS pExceptionPointers; - - friend LONG WINAPI Win32ExceptionFilter(LPEXCEPTION_POINTERS pExceptionPointers); - LONG ExceptionFilter(LPEXCEPTION_POINTERS pExceptionPointers); - - #elif defined(OVR_OS_APPLE) - struct SavedExceptionPorts - { - SavedExceptionPorts() : count(0) { memset(this, 0, sizeof(SavedExceptionPorts)); } - - mach_msg_type_number_t count; - exception_mask_t masks[6]; - exception_handler_t ports[6]; - exception_behavior_t behaviors[6]; - thread_state_flavor_t flavors[6]; - }; - - friend void* ::MachHandlerThreadFunctionStatic(void*); - friend int ::catch_mach_exception_raise_state_identity_OVR(mach_port_t, mach_port_t, mach_port_t, exception_type_t, - mach_exception_data_type_t*, mach_msg_type_number_t, int*, thread_state_t, - mach_msg_type_number_t, thread_state_t, mach_msg_type_number_t*); - - bool InitMachExceptionHandler(); - void ShutdownMachExceptionHandler(); - void* MachHandlerThreadFunction(); - kern_return_t HandleMachException(mach_port_t port, mach_port_t thread, mach_port_t task, exception_type_t exceptionType, - mach_exception_data_type_t* pExceptionDetail, mach_msg_type_number_t exceptionDetailCount, - int* pFlavor, thread_state_t pOldState, mach_msg_type_number_t oldStateCount, thread_state_t pNewState, - mach_msg_type_number_t* pNewStateCount); - kern_return_t ForwardMachException(mach_port_t thread, mach_port_t task, exception_type_t exceptionType, - mach_exception_data_t pExceptionDetail, mach_msg_type_number_t exceptionDetailCount); - - bool machHandlerInitialized; - mach_port_t machExceptionPort; - SavedExceptionPorts machExceptionPortsSaved; - volatile bool machThreadShouldContinue; - volatile bool machThreadExecuting; - pthread_t machThread; - - #elif defined(OVR_OS_LINUX) - // To do. - #endif - }; - - - // Identifies basic exception types for the CreateException function. - enum CreateExceptionType - { - kCETAccessViolation, // Read or write to inaccessable memory. - kCETAlignment, // Misaligned read or write. - kCETDivideByZero, // Integer divide by zero. - kCETFPU, // Floating point / VPU exception. - kCETIllegalInstruction, // Illegal opcode. - kCETStackCorruption, // Stack frame was corrupted. - kCETStackOverflow, // Stack ran out of space, often due to infinite recursion. - kCETTrap // System/OS trap (system call). - }; - - - // Creates an exception of the given type, primarily for testing. - void CreateException(CreateExceptionType exceptionType); - - - -} // namespace OVR - - -OVR_RESTORE_MSVC_WARNING() - - -#endif // Header include guard diff --git a/LibOVR/Src/Kernel/OVR_Delegates.h b/LibOVR/Src/Kernel/OVR_Delegates.h deleted file mode 100644 index 88948b4..0000000 --- a/LibOVR/Src/Kernel/OVR_Delegates.h +++ /dev/null @@ -1,541 +0,0 @@ -/************************************************************************************ - -Filename : OVR_Delegates.h -Content : C++ Delegates -Created : June 15, 2014 -Authors : Chris Taylor - -Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); -you may not use the Oculus VR Rift SDK except in compliance with the License, -which is provided at the time of installation or download, or which -otherwise accompanies this software in either electronic or hard copy form. - -You may obtain a copy of the License at - -http://www.oculusvr.com/licenses/LICENSE-3.2 - -Unless required by applicable law or agreed to in writing, the Oculus VR SDK -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -************************************************************************************/ - -/* - Based on The Impossibly Fast C++ Delegates by Sergey Ryazanov from - http://www.codeproject.com/KB/cpp/ImpossiblyFastCppDelegate.aspx (2005) -*/ - -/* - Usage: - - Declare a delegate with a void (int) signature, also known as a - function that returns void and has one parameter that is an int: - typedef Delegate1<void, int> MyDelegate; - MyDelegate d; - - Point the delegate to a member function: - d.SetMember<A, &A::TestFunctionA>(&a); - d = MyDelegate::FromMember<A, &A::TestFunctionA>(&a); - - Point the delegate to a const member function: - d.SetConstMember<C, &C::TestFunctionA>(&c); - d = MyDelegate::FromConstMember<C, &C::TestFunctionA>(&c); - - Point the delegate to a free function: - d.SetFree<&FreeFunctionX>(); - d = MyDelegate::FromFree<&FreeFunctionX>(); - - Invoke the function via the delegate (works for all 3 cases): - d(1000); - - By default the delegates are uninitialized. - To clear an array of delegates quickly just zero the memory. - - This implementation is nicer than FastDelegates in my opinion - because it is simple and easy to read. It is a little slower - for virtual functions, but the size of the delegate is small, - and it will only get better as compilers improve. -*/ - -#ifndef OVR_Delegates_h -#define OVR_Delegates_h - -#include "OVR_Types.h" - -namespace OVR { - - -template <class ret_type> -class Delegate0 -{ - typedef ret_type (*StubPointer)(void *); - typedef Delegate0<ret_type> this_type; - - void *_object; - StubPointer _stub; - - OVR_FORCE_INLINE Delegate0(void *object, StubPointer stub) - { - _object = object; - _stub = stub; - } - - // Stubs - - template <ret_type (*F)()> - static OVR_FORCE_INLINE ret_type FreeStub(void * /*object*/) - { - return (F)(); - } - - template <class T, ret_type (T::*F)()> - static OVR_FORCE_INLINE ret_type MemberStub(void *object) - { - T *p = static_cast<T*>(object); - return (p->*F)(); - } - - template <class T, ret_type (T::*F)() const> - static OVR_FORCE_INLINE ret_type ConstMemberStub(void *object) - { - T *p = static_cast<T*>(object); - return (p->*F)(); - } - -public: - OVR_FORCE_INLINE Delegate0() : _object(0), _stub(0){} - - // Function invocation - - OVR_FORCE_INLINE ret_type operator()() const - { - return (*_stub)(_object); - } - - // Use stub pointer as a validity flag and equality checker - - OVR_FORCE_INLINE bool operator==(const this_type &rhs) const - { - return _object == rhs._object && _stub == rhs._stub; - } - - OVR_FORCE_INLINE bool operator!=(const this_type &rhs) const - { - return _object != rhs._object || _stub != rhs._stub; - } - - OVR_FORCE_INLINE bool IsValid() const - { - return _stub != 0; - } - - OVR_FORCE_INLINE bool operator!() const - { - return _stub == 0; - } - - OVR_FORCE_INLINE void Invalidate() - { - _stub = 0; - } - - // Delegate creation from a function - - template <ret_type (*F)()> - static OVR_FORCE_INLINE this_type FromFree() - { - return this_type(0, &FreeStub<F>); - } - - template <class T, ret_type (T::*F)()> - static OVR_FORCE_INLINE this_type FromMember(T *object) - { - return this_type(object, &MemberStub<T, F>); - } - - template <class T, ret_type (T::*F)() const> - static OVR_FORCE_INLINE this_type FromConstMember(T const *object) - { - return this_type(const_cast<T*>( object ), &ConstMemberStub<T, F>); - } - - // In-place assignment to a different function - - template <ret_type (*F)()> - OVR_FORCE_INLINE void SetFree() - { - *this = FromFree<F>(); - } - - template <class T, ret_type (T::*F)()> - OVR_FORCE_INLINE void SetMember(T *object) - { - *this = FromMember<T, F>(object); - } - - template <class T, ret_type (T::*F)() const> - OVR_FORCE_INLINE void SetConstMember(T const *object) - { - *this = FromConstMember<T, F>(object); - } -}; - - -template <class ret_type, class arg1_type> -class Delegate1 -{ - typedef ret_type (*StubPointer)(void *, arg1_type); - typedef Delegate1<ret_type, arg1_type> this_type; - - void *_object; - StubPointer _stub; - - OVR_FORCE_INLINE Delegate1(void *object, StubPointer stub) - { - _object = object; - _stub = stub; - } - - // Stubs - - template <ret_type (*F)(arg1_type)> - static OVR_FORCE_INLINE ret_type FreeStub(void * /*object*/, arg1_type a1) - { - return (F)(a1); - } - - template <class T, ret_type (T::*F)(arg1_type)> - static OVR_FORCE_INLINE ret_type MemberStub(void *object, arg1_type a1) - { - T *p = static_cast<T*>(object); - return (p->*F)(a1); - } - - template <class T, ret_type (T::*F)(arg1_type) const> - static OVR_FORCE_INLINE ret_type ConstMemberStub(void *object, arg1_type a1) - { - T *p = static_cast<T*>(object); - return (p->*F)(a1); - } - -public: - OVR_FORCE_INLINE Delegate1() : _object(0), _stub(0){} - - // Function invocation - - OVR_FORCE_INLINE ret_type operator()(arg1_type a1) const - { - return (*_stub)(_object, a1); - } - - // Use stub pointer as a validity flag and equality checker - - OVR_FORCE_INLINE bool operator==(const this_type &rhs) const - { - return _object == rhs._object && _stub == rhs._stub; - } - - OVR_FORCE_INLINE bool operator!=(const this_type &rhs) const - { - return _object != rhs._object || _stub != rhs._stub; - } - - OVR_FORCE_INLINE bool IsValid() const - { - return _stub != 0; - } - - OVR_FORCE_INLINE bool operator!() const - { - return _stub == 0; - } - - OVR_FORCE_INLINE void Invalidate() - { - _stub = 0; - } - - // Delegate creation from a function - - template <ret_type (*F)(arg1_type)> - static OVR_FORCE_INLINE this_type FromFree() - { - return this_type(0, &FreeStub<F>); - } - - template <class T, ret_type (T::*F)(arg1_type)> - static OVR_FORCE_INLINE this_type FromMember(T *object) - { - return this_type(object, &MemberStub<T, F>); - } - - template <class T, ret_type (T::*F)(arg1_type) const> - static OVR_FORCE_INLINE this_type FromConstMember(T const *object) - { - return this_type(const_cast<T*>( object ), &ConstMemberStub<T, F>); - } - - // In-place assignment to a different function - - template <ret_type (*F)(arg1_type)> - OVR_FORCE_INLINE void SetFree() - { - *this = FromFree<F>(); - } - - template <class T, ret_type (T::*F)(arg1_type)> - OVR_FORCE_INLINE void SetMember(T *object) - { - *this = FromMember<T, F>(object); - } - - template <class T, ret_type (T::*F)(arg1_type) const> - OVR_FORCE_INLINE void SetConstMember(T const *object) - { - *this = FromConstMember<T, F>(object); - } -}; - - -template <class ret_type, class arg1_type, class arg2_type> -class Delegate2 -{ - typedef ret_type (*StubPointer)(void *, arg1_type, arg2_type); - typedef Delegate2<ret_type, arg1_type, arg2_type> this_type; - - void *_object; - StubPointer _stub; - - OVR_FORCE_INLINE Delegate2(void *object, StubPointer stub) - { - _object = object; - _stub = stub; - } - - // Stubs - - template <ret_type (*F)(arg1_type, arg2_type)> - static OVR_FORCE_INLINE ret_type FreeStub(void * /*object*/, arg1_type a1, arg2_type a2) - { - return (F)(a1, a2); - } - - template <class T, ret_type (T::*F)(arg1_type, arg2_type)> - static OVR_FORCE_INLINE ret_type MemberStub(void *object, arg1_type a1, arg2_type a2) - { - T *p = static_cast<T*>(object); - return (p->*F)(a1, a2); - } - - template <class T, ret_type (T::*F)(arg1_type, arg2_type) const> - static OVR_FORCE_INLINE ret_type ConstMemberStub(void *object, arg1_type a1, arg2_type a2) - { - T *p = static_cast<T*>(object); - return (p->*F)(a1, a2); - } - -public: - OVR_FORCE_INLINE Delegate2() : _object(0), _stub(0){} - - // Function invocation - - OVR_FORCE_INLINE ret_type operator()(arg1_type a1, arg2_type a2) const - { - return (*_stub)(_object, a1, a2); - } - - // Use stub pointer as a validity flag and equality checker - - OVR_FORCE_INLINE bool operator==(const this_type &rhs) const - { - return _object == rhs._object && _stub == rhs._stub; - } - - OVR_FORCE_INLINE bool operator!=(const this_type &rhs) const - { - return _object != rhs._object || _stub != rhs._stub; - } - - OVR_FORCE_INLINE bool IsValid() const - { - return _stub != 0; - } - - OVR_FORCE_INLINE bool operator!() const - { - return _stub == 0; - } - - OVR_FORCE_INLINE void Invalidate() - { - _stub = 0; - } - - // Delegate creation from a function - - template <ret_type (*F)(arg1_type, arg2_type)> - static OVR_FORCE_INLINE this_type FromFree() - { - return this_type(0, &FreeStub<F>); - } - - template <class T, ret_type (T::*F)(arg1_type, arg2_type)> - static OVR_FORCE_INLINE this_type FromMember(T *object) - { - return this_type(object, &MemberStub<T, F>); - } - - template <class T, ret_type (T::*F)(arg1_type, arg2_type) const> - static OVR_FORCE_INLINE this_type FromConstMember(T const *object) - { - return this_type(const_cast<T*>( object ), &ConstMemberStub<T, F>); - } - - // In-place assignment to a different function - - template <ret_type (*F)(arg1_type, arg2_type)> - OVR_FORCE_INLINE void SetFree() - { - *this = FromFree<F>(); - } - - template <class T, ret_type (T::*F)(arg1_type, arg2_type)> - OVR_FORCE_INLINE void SetMember(T *object) - { - *this = FromMember<T, F>(object); - } - - template <class T, ret_type (T::*F)(arg1_type, arg2_type) const> - OVR_FORCE_INLINE void SetConstMember(T const *object) - { - *this = FromConstMember<T, F>(object); - } -}; - - -template <class ret_type, class arg1_type, class arg2_type, class arg3_type> -class Delegate3 -{ - typedef ret_type (*StubPointer)(void *, arg1_type, arg2_type, arg3_type); - typedef Delegate3<ret_type, arg1_type, arg2_type, arg3_type> this_type; - - void *_object; - StubPointer _stub; - - OVR_FORCE_INLINE Delegate3(void *object, StubPointer stub) - { - _object = object; - _stub = stub; - } - - // Stubs - - template <ret_type (*F)(arg1_type, arg2_type, arg3_type)> - static OVR_FORCE_INLINE ret_type FreeStub(void * /*object*/, arg1_type a1, arg2_type a2, arg3_type a3) - { - return (F)(a1, a2, a3); - } - - template <class T, ret_type (T::*F)(arg1_type, arg2_type, arg3_type)> - static OVR_FORCE_INLINE ret_type MemberStub(void *object, arg1_type a1, arg2_type a2, arg3_type a3) - { - T *p = static_cast<T*>(object); - return (p->*F)(a1, a2, a3); - } - - template <class T, ret_type (T::*F)(arg1_type, arg2_type, arg3_type) const> - static OVR_FORCE_INLINE ret_type ConstMemberStub(void *object, arg1_type a1, arg2_type a2, arg3_type a3) - { - T *p = static_cast<T*>(object); - return (p->*F)(a1, a2, a3); - } - -public: - OVR_FORCE_INLINE Delegate3() : _object(0), _stub(0){} - - // Function invocation - - OVR_FORCE_INLINE ret_type operator()(arg1_type a1, arg2_type a2, arg3_type a3) const - { - return (*_stub)(_object, a1, a2, a3); - } - - // Use stub pointer as a validity flag and equality checker - - OVR_FORCE_INLINE bool operator==(const this_type &rhs) const - { - return _object == rhs._object && _stub == rhs._stub; - } - - OVR_FORCE_INLINE bool operator!=(const this_type &rhs) const - { - return _object != rhs._object || _stub != rhs._stub; - } - - OVR_FORCE_INLINE bool IsValid() const - { - return _stub != 0; - } - - OVR_FORCE_INLINE bool operator!() const - { - return _stub == 0; - } - - OVR_FORCE_INLINE void Invalidate() - { - _stub = 0; - } - - // Delegate creation from a function - - template <ret_type (*F)(arg1_type, arg2_type, arg3_type)> - static OVR_FORCE_INLINE this_type FromFree() - { - return this_type(0, &FreeStub<F>); - } - - template <class T, ret_type (T::*F)(arg1_type, arg2_type, arg3_type)> - static OVR_FORCE_INLINE this_type FromMember(T *object) - { - return this_type(object, &MemberStub<T, F>); - } - - template <class T, ret_type (T::*F)(arg1_type, arg2_type, arg3_type) const> - static OVR_FORCE_INLINE this_type FromConstMember(T const *object) - { - return this_type(const_cast<T*>( object ), &ConstMemberStub<T, F>); - } - - // In-place assignment to a different function - - template <ret_type (*F)(arg1_type, arg2_type, arg3_type)> - OVR_FORCE_INLINE void SetFree() - { - *this = FromFree<F>(); - } - - template <class T, ret_type (T::*F)(arg1_type, arg2_type, arg3_type)> - OVR_FORCE_INLINE void SetMember(T *object) - { - *this = FromMember<T, F>(object); - } - - template <class T, ret_type (T::*F)(arg1_type, arg2_type, arg3_type) const> - OVR_FORCE_INLINE void SetConstMember(T const *object) - { - *this = FromConstMember<T, F>(object); - } -}; - -// Add more here if needed, but keep in mind that a short, simple interface -// is rewarded by making the delegates faster... - - -} // namespace OVR - -#endif // OVR_Delegates_h diff --git a/LibOVR/Src/Kernel/OVR_Deque.h b/LibOVR/Src/Kernel/OVR_Deque.h deleted file mode 100644 index 951ed84..0000000 --- a/LibOVR/Src/Kernel/OVR_Deque.h +++ /dev/null @@ -1,316 +0,0 @@ -/************************************************************************************ - -Filename : OVR_Deque.h -Content : Deque container -Created : Nov. 15, 2013 -Authors : Dov Katz - -Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); -you may not use the Oculus VR Rift SDK except in compliance with the License, -which is provided at the time of installation or download, or which -otherwise accompanies this software in either electronic or hard copy form. - -You may obtain a copy of the License at - -http://www.oculusvr.com/licenses/LICENSE-3.2 - -Unless required by applicable law or agreed to in writing, the Oculus VR SDK -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -*************************************************************************************/ - -#ifndef OVR_Deque_h -#define OVR_Deque_h - -#include "OVR_ContainerAllocator.h" - -namespace OVR{ - -template <class Elem, class Allocator = ContainerAllocator<Elem> > -class Deque -{ -public: - enum - { - DefaultCapacity = 500 - }; - - Deque(int capacity = DefaultCapacity); - virtual ~Deque(void); - - virtual void PushBack (const Elem &Item); // Adds Item to the end - virtual void PushFront (const Elem &Item); // Adds Item to the beginning - virtual Elem PopBack (void); // Removes Item from the end - virtual Elem PopFront (void); // Removes Item from the beginning - virtual const Elem& PeekBack (int count = 0) const; // Returns count-th Item from the end - virtual const Elem& PeekFront (int count = 0) const; // Returns count-th Item from the beginning - - virtual inline size_t GetSize (void) const; // Returns Number of Elements - OVR_FORCE_INLINE int GetSizeI (void) const - { - return (int)GetSize(); - } - virtual inline size_t GetCapacity(void) const; // Returns the maximum possible number of elements - virtual void Clear (void); // Remove all elements - virtual inline bool IsEmpty () const; - virtual inline bool IsFull () const; - -protected: - Elem *Data; // The actual Data array - const int Capacity; // Deque capacity - int Beginning; // Index of the first element - int End; // Index of the next after last element - - // Instead of calculating the number of elements, using this variable - // is much more convenient. - int ElemCount; - -private: - OVR_NON_COPYABLE(Deque); -}; - -template <class Elem, class Allocator = ContainerAllocator<Elem> > -class InPlaceMutableDeque : public Deque<Elem, Allocator> -{ - typedef Deque<Elem, Allocator> BaseType; - -public: - InPlaceMutableDeque( int capacity = BaseType::DefaultCapacity ) : BaseType( capacity ) {} - virtual ~InPlaceMutableDeque() {}; - - using BaseType::PeekBack; - using BaseType::PeekFront; - virtual Elem& PeekBack (int count = 0); // Returns count-th Item from the end - virtual Elem& PeekFront (int count = 0); // Returns count-th Item from the beginning -}; - -// Same as Deque, but allows to write more elements than maximum capacity -// Old elements are lost as they are overwritten with the new ones -template <class Elem, class Allocator = ContainerAllocator<Elem> > -class CircularBuffer : public InPlaceMutableDeque<Elem, Allocator> -{ - typedef InPlaceMutableDeque<Elem, Allocator> BaseType; - -public: - CircularBuffer(int MaxSize = BaseType::DefaultCapacity) : BaseType(MaxSize) { }; - virtual ~CircularBuffer(){} - - // The following methods are inline as a workaround for a VS bug causing erroneous C4505 warnings - // See: http://stackoverflow.com/questions/3051992/compiler-warning-at-c-template-base-class - inline virtual void PushBack (const Elem &Item); // Adds Item to the end, overwriting the oldest element at the beginning if necessary - inline virtual void PushFront (const Elem &Item); // Adds Item to the beginning, overwriting the oldest element at the end if necessary -}; - -//---------------------------------------------------------------------------------- - -// Deque Constructor function -template <class Elem, class Allocator> -Deque<Elem, Allocator>::Deque(int capacity) : -Capacity( capacity ), Beginning(0), End(0), ElemCount(0) -{ - Data = (Elem*) Allocator::Alloc(Capacity * sizeof(Elem)); -} - -// Deque Destructor function -template <class Elem, class Allocator> -Deque<Elem, Allocator>::~Deque(void) -{ - Clear(); - Allocator::Free(Data); -} - -template <class Elem, class Allocator> -void Deque<Elem, Allocator>::Clear() -{ - if (!IsEmpty()) - { - if (Beginning < End) - { - // no wrap-around - Allocator::DestructArray(Data + Beginning, End - Beginning); - } - else - { - // wrap-around - Allocator::DestructArray(Data + Beginning, Capacity - Beginning); - Allocator::DestructArray(Data, End); - } - } - - Beginning = 0; - End = 0; - ElemCount = 0; -} - -// Push functions -template <class Elem, class Allocator> -void Deque<Elem, Allocator>::PushBack(const Elem &Item) -{ - // Error Check: Make sure we aren't - // exceeding our maximum storage space - OVR_ASSERT( ElemCount < Capacity ); - - Allocator::Construct(Data + End, Item); - ++End; - ++ElemCount; - - // Check for wrap-around - if (End >= Capacity) - End -= Capacity; -} - -template <class Elem, class Allocator> -void Deque<Elem, Allocator>::PushFront(const Elem &Item) -{ - // Error Check: Make sure we aren't - // exceeding our maximum storage space - OVR_ASSERT( ElemCount < Capacity ); - - --Beginning; - // Check for wrap-around - if (Beginning < 0) - Beginning += Capacity; - - Allocator::Construct(Data + Beginning, Item); - ++ElemCount; -} - -// Pop functions -template <class Elem, class Allocator> -Elem Deque<Elem, Allocator>::PopFront(void) -{ - // Error Check: Make sure we aren't reading from an empty Deque - OVR_ASSERT( ElemCount > 0 ); - - Elem ReturnValue = Data[ Beginning ]; - Allocator::Destruct(Data + Beginning); - - ++Beginning; - --ElemCount; - - // Check for wrap-around - if (Beginning >= Capacity) - Beginning -= Capacity; - - return ReturnValue; -} - -template <class Elem, class Allocator> -Elem Deque<Elem, Allocator>::PopBack(void) -{ - // Error Check: Make sure we aren't reading from an empty Deque - OVR_ASSERT( ElemCount > 0 ); - - --End; - --ElemCount; - - // Check for wrap-around - if (End < 0) - End += Capacity; - - Elem ReturnValue = Data[ End ]; - Allocator::Destruct(Data + End); - - return ReturnValue; -} - -// Peek functions -template <class Elem, class Allocator> -const Elem& Deque<Elem, Allocator>::PeekFront(int count) const -{ - // Error Check: Make sure we aren't reading from an empty Deque - OVR_ASSERT( ElemCount > count ); - - int idx = Beginning + count; - if (idx >= Capacity) - idx -= Capacity; - return Data[ idx ]; -} - -template <class Elem, class Allocator> -const Elem& Deque<Elem, Allocator>::PeekBack(int count) const -{ - // Error Check: Make sure we aren't reading from an empty Deque - OVR_ASSERT( ElemCount > count ); - - int idx = End - count - 1; - if (idx < 0) - idx += Capacity; - return Data[ idx ]; -} - -// Mutable Peek functions -template <class Elem, class Allocator> -Elem& InPlaceMutableDeque<Elem, Allocator>::PeekFront(int count) -{ - // Error Check: Make sure we aren't reading from an empty Deque - OVR_ASSERT( BaseType::ElemCount > count ); - - int idx = BaseType::Beginning + count; - if (idx >= BaseType::Capacity) - idx -= BaseType::Capacity; - return BaseType::Data[ idx ]; -} - -template <class Elem, class Allocator> -Elem& InPlaceMutableDeque<Elem, Allocator>::PeekBack(int count) -{ - // Error Check: Make sure we aren't reading from an empty Deque - OVR_ASSERT( BaseType::ElemCount > count ); - - int idx = BaseType::End - count - 1; - if (idx < 0) - idx += BaseType::Capacity; - return BaseType::Data[ idx ]; -} - -template <class Elem, class Allocator> -inline size_t Deque<Elem, Allocator>::GetCapacity(void) const -{ - return Capacity; -} - -template <class Elem, class Allocator> -inline size_t Deque<Elem, Allocator>::GetSize(void) const -{ - return ElemCount; -} - -template <class Elem, class Allocator> -inline bool Deque<Elem, Allocator>::IsEmpty(void) const -{ - return ElemCount == 0; -} - -template <class Elem, class Allocator> -inline bool Deque<Elem, Allocator>::IsFull(void) const -{ - return ElemCount == Capacity; -} - -// ******* CircularBuffer<Elem> ******* -// Push functions -template <class Elem, class Allocator> -void CircularBuffer<Elem, Allocator>::PushBack(const Elem &Item) -{ - if (this->IsFull()) - this->PopFront(); - BaseType::PushBack(Item); -} - -template <class Elem, class Allocator> -void CircularBuffer<Elem, Allocator>::PushFront(const Elem &Item) -{ - if (this->IsFull()) - this->PopBack(); - BaseType::PushFront(Item); -} - -}; - -#endif diff --git a/LibOVR/Src/Kernel/OVR_File.cpp b/LibOVR/Src/Kernel/OVR_File.cpp deleted file mode 100644 index c431928..0000000 --- a/LibOVR/Src/Kernel/OVR_File.cpp +++ /dev/null @@ -1,585 +0,0 @@ -/************************************************************************** - -Filename : OVR_File.cpp -Content : File wrapper class implementation (Win32) - -Created : April 5, 1999 -Authors : Michael Antonov - -Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); -you may not use the Oculus VR Rift SDK except in compliance with the License, -which is provided at the time of installation or download, or which -otherwise accompanies this software in either electronic or hard copy form. - -You may obtain a copy of the License at - -http://www.oculusvr.com/licenses/LICENSE-3.2 - -Unless required by applicable law or agreed to in writing, the Oculus VR SDK -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -**************************************************************************/ - -#define GFILE_CXX - -// Standard C library (Captain Obvious guarantees!) -#include <stdio.h> - -#include "OVR_File.h" - -namespace OVR { - -// Buffered file adds buffering to an existing file -// FILEBUFFER_SIZE defines the size of internal buffer, while -// FILEBUFFER_TOLERANCE controls the amount of data we'll effectively try to buffer -#define FILEBUFFER_SIZE (8192-8) -#define FILEBUFFER_TOLERANCE 4096 - -// ** Constructor/Destructor - -// Hidden constructor -// Not supposed to be used -BufferedFile::BufferedFile() : DelegatedFile(0) -{ - pBuffer = (uint8_t*)OVR_ALLOC(FILEBUFFER_SIZE); - BufferMode = NoBuffer; - FilePos = 0; - Pos = 0; - DataSize = 0; -} - -// Takes another file as source -BufferedFile::BufferedFile(File *pfile) : DelegatedFile(pfile) -{ - pBuffer = (uint8_t*)OVR_ALLOC(FILEBUFFER_SIZE); - BufferMode = NoBuffer; - FilePos = pfile->LTell(); - Pos = 0; - DataSize = 0; -} - - -// Destructor -BufferedFile::~BufferedFile() -{ - // Flush in case there's data - if (pFile) - FlushBuffer(); - // Get rid of buffer - if (pBuffer) - OVR_FREE(pBuffer); -} - -/* -bool BufferedFile::VCopy(const Object &source) -{ - if (!DelegatedFile::VCopy(source)) - return 0; - - // Data members - BufferedFile *psource = (BufferedFile*)&source; - - // Buffer & the mode it's in - pBuffer = psource->pBuffer; - BufferMode = psource->BufferMode; - Pos = psource->Pos; - DataSize = psource->DataSize; - return 1; -} -*/ - -// Initializes buffering to a certain mode -bool BufferedFile::SetBufferMode(BufferModeType mode) -{ - if (!pBuffer) - return false; - if (mode == BufferMode) - return true; - - FlushBuffer(); - - // Can't set write mode if we can't write - if ((mode==WriteBuffer) && (!pFile || !pFile->IsWritable()) ) - return 0; - - // And SetMode - BufferMode = mode; - Pos = 0; - DataSize = 0; - return 1; -} - -// Flushes buffer -void BufferedFile::FlushBuffer() -{ - switch(BufferMode) - { - case WriteBuffer: - // Write data in buffer - FilePos += pFile->Write(pBuffer,Pos); - Pos = 0; - break; - - case ReadBuffer: - // Seek back & reset buffer data - if ((DataSize-Pos)>0) - FilePos = pFile->LSeek(-(int)(DataSize-Pos), Seek_Cur); - DataSize = 0; - Pos = 0; - break; - default: - // not handled! - break; - } -} - -// Reloads data for ReadBuffer -void BufferedFile::LoadBuffer() -{ - if (BufferMode == ReadBuffer) - { - // We should only reload once all of pre-loaded buffer is consumed. - OVR_ASSERT(Pos == DataSize); - - // WARNING: Right now LoadBuffer() assumes the buffer's empty - int sz = pFile->Read(pBuffer,FILEBUFFER_SIZE); - DataSize = sz<0 ? 0 : (unsigned)sz; - Pos = 0; - FilePos += DataSize; - } -} - - -// ** Overridden functions - -// We override all the functions that can possibly -// require buffer mode switch, flush, or extra calculations - -// Tell() requires buffer adjustment -int BufferedFile::Tell() -{ - if (BufferMode == ReadBuffer) - return int (FilePos - DataSize + Pos); - - int pos = pFile->Tell(); - // Adjust position based on buffer mode & data - if (pos!=-1) - { - OVR_ASSERT(BufferMode != ReadBuffer); - if (BufferMode == WriteBuffer) - pos += Pos; - } - return pos; -} - -int64_t BufferedFile::LTell() -{ - if (BufferMode == ReadBuffer) - return FilePos - DataSize + Pos; - - int64_t pos = pFile->LTell(); - if (pos!=-1) - { - OVR_ASSERT(BufferMode != ReadBuffer); - if (BufferMode == WriteBuffer) - pos += Pos; - } - return pos; -} - -int BufferedFile::GetLength() -{ - int len = pFile->GetLength(); - // If writing through buffer, file length may actually be bigger - if ((len!=-1) && (BufferMode==WriteBuffer)) - { - int currPos = pFile->Tell() + Pos; - if (currPos>len) - len = currPos; - } - return len; -} -int64_t BufferedFile::LGetLength() -{ - int64_t len = pFile->LGetLength(); - // If writing through buffer, file length may actually be bigger - if ((len!=-1) && (BufferMode==WriteBuffer)) - { - int64_t currPos = pFile->LTell() + Pos; - if (currPos>len) - len = currPos; - } - return len; -} - -/* -bool BufferedFile::Stat(FileStats *pfs) -{ - // Have to fix up length is stat - if (pFile->Stat(pfs)) - { - if (BufferMode==WriteBuffer) - { - int64_t currPos = pFile->LTell() + Pos; - if (currPos > pfs->Size) - { - pfs->Size = currPos; - // ?? - pfs->Blocks = (pfs->Size+511) >> 9; - } - } - return 1; - } - return 0; -} -*/ - -int BufferedFile::Write(const uint8_t *psourceBuffer, int numBytes) -{ - if ( (BufferMode==WriteBuffer) || SetBufferMode(WriteBuffer)) - { - // If not data space in buffer, flush - if ((FILEBUFFER_SIZE-(int)Pos)<numBytes) - { - FlushBuffer(); - // If bigger then tolerance, just write directly - if (numBytes>FILEBUFFER_TOLERANCE) - { - int sz = pFile->Write(psourceBuffer,numBytes); - if (sz > 0) - FilePos += sz; - return sz; - } - } - - // Enough space in buffer.. so copy to it - memcpy(pBuffer+Pos, psourceBuffer, numBytes); - Pos += numBytes; - return numBytes; - } - int sz = pFile->Write(psourceBuffer,numBytes); - if (sz > 0) - FilePos += sz; - return sz; -} - -int BufferedFile::Read(uint8_t *pdestBuffer, int numBytes) -{ - if ( (BufferMode==ReadBuffer) || SetBufferMode(ReadBuffer)) - { - // Data in buffer... copy it - if ((int)(DataSize-Pos) >= numBytes) - { - memcpy(pdestBuffer, pBuffer+Pos, numBytes); - Pos += numBytes; - return numBytes; - } - - // Not enough data in buffer, copy buffer - int readBytes = DataSize-Pos; - memcpy(pdestBuffer, pBuffer+Pos, readBytes); - numBytes -= readBytes; - pdestBuffer += readBytes; - Pos = DataSize; - - // Don't reload buffer if more then tolerance - // (No major advantage, and we don't want to write a loop) - if (numBytes>FILEBUFFER_TOLERANCE) - { - numBytes = pFile->Read(pdestBuffer,numBytes); - if (numBytes > 0) - { - FilePos += numBytes; - Pos = DataSize = 0; - } - return readBytes + ((numBytes==-1) ? 0 : numBytes); - } - - // Reload the buffer - // WARNING: Right now LoadBuffer() assumes the buffer's empty - LoadBuffer(); - if ((int)(DataSize-Pos) < numBytes) - numBytes = (int)DataSize-Pos; - - memcpy(pdestBuffer, pBuffer+Pos, numBytes); - Pos += numBytes; - return numBytes + readBytes; - - /* - // Alternative Read implementation. The one above is probably better - // due to FILEBUFFER_TOLERANCE. - int total = 0; - - do { - int bufferBytes = (int)(DataSize-Pos); - int copyBytes = (bufferBytes > numBytes) ? numBytes : bufferBytes; - - memcpy(pdestBuffer, pBuffer+Pos, copyBytes); - numBytes -= copyBytes; - pdestBuffer += copyBytes; - Pos += copyBytes; - total += copyBytes; - - if (numBytes == 0) - break; - LoadBuffer(); - - } while (DataSize > 0); - - return total; - */ - } - int sz = pFile->Read(pdestBuffer,numBytes); - if (sz > 0) - FilePos += sz; - return sz; -} - - -int BufferedFile::SkipBytes(int numBytes) -{ - int skippedBytes = 0; - - // Special case for skipping a little data in read buffer - if (BufferMode==ReadBuffer) - { - skippedBytes = (((int)DataSize-(int)Pos) >= numBytes) ? numBytes : (DataSize-Pos); - Pos += skippedBytes; - numBytes -= skippedBytes; - } - - if (numBytes) - { - numBytes = pFile->SkipBytes(numBytes); - // Make sure we return the actual number skipped, or error - if (numBytes!=-1) - { - skippedBytes += numBytes; - FilePos += numBytes; - Pos = DataSize = 0; - } - else if (skippedBytes <= 0) - skippedBytes = -1; - } - return skippedBytes; -} - -int BufferedFile::BytesAvailable() -{ - int available = pFile->BytesAvailable(); - // Adjust available size based on buffers - switch(BufferMode) - { - case ReadBuffer: - available += DataSize-Pos; - break; - case WriteBuffer: - available -= Pos; - if (available<0) - available= 0; - break; - default: - break; - } - return available; -} - -bool BufferedFile::Flush() -{ - FlushBuffer(); - return pFile->Flush(); -} - -// Seeking could be optimized better.. -int BufferedFile::Seek(int offset, int origin) -{ - if (BufferMode == ReadBuffer) - { - if (origin == Seek_Cur) - { - // Seek can fall either before or after Pos in the buffer, - // but it must be within bounds. - if (((unsigned(offset) + Pos)) <= DataSize) - { - Pos += offset; - return int (FilePos - DataSize + Pos); - } - - // Lightweight buffer "Flush". We do this to avoid an extra seek - // back operation which would take place if we called FlushBuffer directly. - origin = Seek_Set; - OVR_ASSERT(((FilePos - DataSize + Pos) + (uint64_t)offset) < ~(uint64_t)0); - offset = (int)(FilePos - DataSize + Pos) + offset; - Pos = DataSize = 0; - } - else if (origin == Seek_Set) - { - if (((unsigned)offset - (FilePos-DataSize)) <= DataSize) - { - OVR_ASSERT((FilePos-DataSize) < ~(uint64_t)0); - Pos = (unsigned)offset - (unsigned)(FilePos-DataSize); - return offset; - } - Pos = DataSize = 0; - } - else - { - FlushBuffer(); - } - } - else - { - FlushBuffer(); - } - - /* - // Old Seek Logic - if (origin == Seek_Cur && offset + Pos < DataSize) - { - //OVR_ASSERT((FilePos - DataSize) >= (FilePos - DataSize + Pos + offset)); - Pos += offset; - OVR_ASSERT(int (Pos) >= 0); - return int (FilePos - DataSize + Pos); - } - else if (origin == Seek_Set && unsigned(offset) >= FilePos - DataSize && unsigned(offset) < FilePos) - { - Pos = unsigned(offset - FilePos + DataSize); - OVR_ASSERT(int (Pos) >= 0); - return int (FilePos - DataSize + Pos); - } - - FlushBuffer(); - */ - - - FilePos = pFile->Seek(offset,origin); - return int (FilePos); -} - -int64_t BufferedFile::LSeek(int64_t offset, int origin) -{ - if (BufferMode == ReadBuffer) - { - if (origin == Seek_Cur) - { - // Seek can fall either before or after Pos in the buffer, - // but it must be within bounds. - if (((unsigned(offset) + Pos)) <= DataSize) - { - Pos += (unsigned)offset; - return int64_t(FilePos - DataSize + Pos); - } - - // Lightweight buffer "Flush". We do this to avoid an extra seek - // back operation which would take place if we called FlushBuffer directly. - origin = Seek_Set; - offset = (int64_t)(FilePos - DataSize + Pos) + offset; - Pos = DataSize = 0; - } - else if (origin == Seek_Set) - { - if (((uint64_t)offset - (FilePos-DataSize)) <= DataSize) - { - Pos = (unsigned)((uint64_t)offset - (FilePos-DataSize)); - return offset; - } - Pos = DataSize = 0; - } - else - { - FlushBuffer(); - } - } - else - { - FlushBuffer(); - } - -/* - OVR_ASSERT(BufferMode != NoBuffer); - - if (origin == Seek_Cur && offset + Pos < DataSize) - { - Pos += int (offset); - return FilePos - DataSize + Pos; - } - else if (origin == Seek_Set && offset >= int64_t(FilePos - DataSize) && offset < int64_t(FilePos)) - { - Pos = unsigned(offset - FilePos + DataSize); - return FilePos - DataSize + Pos; - } - - FlushBuffer(); - */ - - FilePos = pFile->LSeek(offset,origin); - return FilePos; -} - -int BufferedFile::CopyFromStream(File *pstream, int byteSize) -{ - // We can't rely on overridden Write() - // because delegation doesn't override virtual pointers - // So, just re-implement - uint8_t* buff = new uint8_t[0x4000]; - int count = 0; - int szRequest, szRead, szWritten; - - while(byteSize) - { - szRequest = (byteSize > int(sizeof(buff))) ? int(sizeof(buff)) : byteSize; - - szRead = pstream->Read(buff,szRequest); - szWritten = 0; - if (szRead > 0) - szWritten = Write(buff,szRead); - - count +=szWritten; - byteSize-=szWritten; - if (szWritten < szRequest) - break; - } - - delete[] buff; - - return count; -} - -// Closing files -bool BufferedFile::Close() -{ - switch(BufferMode) - { - case WriteBuffer: - FlushBuffer(); - break; - case ReadBuffer: - // No need to seek back on close - BufferMode = NoBuffer; - break; - default: - break; - } - return pFile->Close(); -} - - -// ***** Global path helpers - -// Find trailing short filename in a path. -const char* OVR_CDECL GetShortFilename(const char* purl) -{ - size_t len = OVR_strlen(purl); - for (size_t i=len; i>0; i--) - if (purl[i]=='\\' || purl[i]=='/') - return purl+i+1; - return purl; -} - -} // OVR - diff --git a/LibOVR/Src/Kernel/OVR_File.h b/LibOVR/Src/Kernel/OVR_File.h deleted file mode 100644 index d9d3b0f..0000000 --- a/LibOVR/Src/Kernel/OVR_File.h +++ /dev/null @@ -1,530 +0,0 @@ -/************************************************************************************ - -PublicHeader: Kernel -Filename : OVR_File.h -Content : Header for all internal file management - functions and structures - to be inherited by OS specific subclasses. -Created : September 19, 2012 -Notes : - -Notes : errno may not be preserved across use of BaseFile member functions - : Directories cannot be deleted while files opened from them are in use - (For the GetFullName function) - -Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); -you may not use the Oculus VR Rift SDK except in compliance with the License, -which is provided at the time of installation or download, or which -otherwise accompanies this software in either electronic or hard copy form. - -You may obtain a copy of the License at - -http://www.oculusvr.com/licenses/LICENSE-3.2 - -Unless required by applicable law or agreed to in writing, the Oculus VR SDK -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -************************************************************************************/ - -#ifndef OVR_File_h -#define OVR_File_h - -#include "OVR_RefCount.h" -#include "OVR_Std.h" -#include "OVR_Alg.h" - -#include <stdio.h> -#include "OVR_String.h" - -namespace OVR { - -// ***** Declared classes -class FileConstants; -class File; -class DelegatedFile; -class BufferedFile; - - -// ***** Flags for File & Directory accesses - -class FileConstants -{ -public: - - // *** File open flags - enum OpenFlags - { - Open_Read = 1, - Open_Write = 2, - Open_ReadWrite = 3, - - // Opens file and truncates it to zero length - // - file must have write permission - // - when used with Create, it opens an existing - // file and empties it or creates a new file - Open_Truncate = 4, - - // Creates and opens new file - // - does not erase contents if file already - // exists unless combined with Truncate - Open_Create = 8, - - // Returns an error value if the file already exists - Open_CreateOnly = 24, - - // Open file with buffering - Open_Buffered = 32 - }; - - // *** File Mode flags - enum Modes - { - Mode_Read = 0444, - Mode_Write = 0222, - Mode_Execute = 0111, - - Mode_ReadWrite = 0666 - }; - - // *** Seek operations - enum SeekOps - { - Seek_Set = 0, - Seek_Cur = 1, - Seek_End = 2 - }; - - // *** Errors - enum Errors - { - Error_FileNotFound = 0x1001, - Error_Access = 0x1002, - Error_IOError = 0x1003, - Error_DiskFull = 0x1004 - }; -}; - - -//----------------------------------------------------------------------------------- -// ***** File Class - -// The pure virtual base random-access file -// This is a base class to all files - -class File : public RefCountBase<File>, public FileConstants -{ -public: - File() { } - // ** Location Information - - // Returns a file name path relative to the 'reference' directory - // This is often a path that was used to create a file - // (this is not a global path, global path can be obtained with help of directory) - virtual const char* GetFilePath() = 0; - - - // ** File Information - - // Return 1 if file's usable (open) - virtual bool IsValid() = 0; - // Return 1 if file's writable, otherwise 0 - virtual bool IsWritable() = 0; - - // Return position - virtual int Tell() = 0; - virtual int64_t LTell() = 0; - - // File size - virtual int GetLength() = 0; - virtual int64_t LGetLength() = 0; - - // Returns file stats - // 0 for failure - //virtual bool Stat(FileStats *pfs) = 0; - - // Return errno-based error code - // Useful if any other function failed - virtual int GetErrorCode() = 0; - - - // ** Stream implementation & I/O - - // Blocking write, will write in the given number of bytes to the stream - // Returns : -1 for error - // Otherwise number of bytes read - virtual int Write(const uint8_t *pbufer, int numBytes) = 0; - // Blocking read, will read in the given number of bytes or less from the stream - // Returns : -1 for error - // Otherwise number of bytes read, - // if 0 or < numBytes, no more bytes available; end of file or the other side of stream is closed - virtual int Read(uint8_t *pbufer, int numBytes) = 0; - - // Skips (ignores) a given # of bytes - // Same return values as Read - virtual int SkipBytes(int numBytes) = 0; - - // Returns the number of bytes available to read from a stream without blocking - // For a file, this should generally be number of bytes to the end - virtual int BytesAvailable() = 0; - - // Causes any implementation's buffered data to be delivered to destination - // Return 0 for error - virtual bool Flush() = 0; - - - // Need to provide a more optimized implementation that doe snot necessarily involve a lot of seeking - inline bool IsEOF() { return !BytesAvailable(); } - - - // Seeking - // Returns new position, -1 for error - virtual int Seek(int offset, int origin=Seek_Set) = 0; - virtual int64_t LSeek(int64_t offset, int origin=Seek_Set) = 0; - // Seek simplification - int SeekToBegin() {return Seek(0); } - int SeekToEnd() {return Seek(0,Seek_End); } - int Skip(int numBytes) {return Seek(numBytes,Seek_Cur); } - - - // Appends other file data from a stream - // Return -1 for error, else # of bytes written - virtual int CopyFromStream(File *pstream, int byteSize) = 0; - - // Closes the file - // After close, file cannot be accessed - virtual bool Close() = 0; - - - // ***** Inlines for convenient primitive type serialization - - // Read/Write helpers -private: - uint64_t PRead64() { uint64_t v = 0; Read((uint8_t*)&v, 8); return v; } - uint32_t PRead32() { uint32_t v = 0; Read((uint8_t*)&v, 4); return v; } - uint16_t PRead16() { uint16_t v = 0; Read((uint8_t*)&v, 2); return v; } - uint8_t PRead8() { uint8_t v = 0; Read((uint8_t*)&v, 1); return v; } - void PWrite64(uint64_t v) { Write((uint8_t*)&v, 8); } - void PWrite32(uint32_t v) { Write((uint8_t*)&v, 4); } - void PWrite16(uint16_t v) { Write((uint8_t*)&v, 2); } - void PWrite8(uint8_t v) { Write((uint8_t*)&v, 1); } - -public: - - // Writing primitive types - Little Endian - inline void WriteUByte(uint8_t v) { PWrite8((uint8_t)Alg::ByteUtil::SystemToLE(v)); } - inline void WriteSByte(int8_t v) { PWrite8((uint8_t)Alg::ByteUtil::SystemToLE(v)); } - inline void WriteUInt8(uint8_t v) { PWrite8((uint8_t)Alg::ByteUtil::SystemToLE(v)); } - inline void WriteSInt8(int8_t v) { PWrite8((uint8_t)Alg::ByteUtil::SystemToLE(v)); } - inline void WriteUInt16(uint16_t v) { PWrite16((uint16_t)Alg::ByteUtil::SystemToLE(v)); } - inline void WriteSInt16(int16_t v) { PWrite16((uint16_t)Alg::ByteUtil::SystemToLE(v)); } - inline void WriteUInt32(uint32_t v) { PWrite32((uint32_t)Alg::ByteUtil::SystemToLE(v)); } - inline void WriteSInt32(int32_t v) { PWrite32((uint32_t)Alg::ByteUtil::SystemToLE(v)); } - inline void WriteUInt64(uint64_t v) { PWrite64((uint64_t)Alg::ByteUtil::SystemToLE(v)); } - inline void WriteSInt64(int64_t v) { PWrite64((uint64_t)Alg::ByteUtil::SystemToLE(v)); } - inline void WriteFloat(float v) { v = Alg::ByteUtil::SystemToLE(v); Write((uint8_t*)&v, 4); } - inline void WriteDouble(double v) { v = Alg::ByteUtil::SystemToLE(v); Write((uint8_t*)&v, 8); } - // Writing primitive types - Big Endian - inline void WriteUByteBE(uint8_t v) { PWrite8((uint8_t)Alg::ByteUtil::SystemToBE(v)); } - inline void WriteSByteBE(int8_t v) { PWrite8((uint8_t)Alg::ByteUtil::SystemToBE(v)); } - inline void WriteUInt8BE(uint16_t v) { PWrite8((uint8_t)Alg::ByteUtil::SystemToBE(v)); } - inline void WriteSInt8BE(int16_t v) { PWrite8((uint8_t)Alg::ByteUtil::SystemToBE(v)); } - inline void WriteUInt16BE(uint16_t v) { PWrite16((uint16_t)Alg::ByteUtil::SystemToBE(v)); } - inline void WriteSInt16BE(uint16_t v) { PWrite16((uint16_t)Alg::ByteUtil::SystemToBE(v)); } - inline void WriteUInt32BE(uint32_t v) { PWrite32((uint32_t)Alg::ByteUtil::SystemToBE(v)); } - inline void WriteSInt32BE(uint32_t v) { PWrite32((uint32_t)Alg::ByteUtil::SystemToBE(v)); } - inline void WriteUInt64BE(uint64_t v) { PWrite64((uint64_t)Alg::ByteUtil::SystemToBE(v)); } - inline void WriteSInt64BE(uint64_t v) { PWrite64((uint64_t)Alg::ByteUtil::SystemToBE(v)); } - inline void WriteFloatBE(float v) { v = Alg::ByteUtil::SystemToBE(v); Write((uint8_t*)&v, 4); } - inline void WriteDoubleBE(double v) { v = Alg::ByteUtil::SystemToBE(v); Write((uint8_t*)&v, 8); } - - // Reading primitive types - Little Endian - inline uint8_t ReadUByte() { return (uint8_t)Alg::ByteUtil::LEToSystem(PRead8()); } - inline int8_t ReadSByte() { return (int8_t)Alg::ByteUtil::LEToSystem(PRead8()); } - inline uint8_t ReadUInt8() { return (uint8_t)Alg::ByteUtil::LEToSystem(PRead8()); } - inline int8_t ReadSInt8() { return (int8_t)Alg::ByteUtil::LEToSystem(PRead8()); } - inline uint16_t ReadUInt16() { return (uint16_t)Alg::ByteUtil::LEToSystem(PRead16()); } - inline int16_t ReadSInt16() { return (int16_t)Alg::ByteUtil::LEToSystem(PRead16()); } - inline uint32_t ReadUInt32() { return (uint32_t)Alg::ByteUtil::LEToSystem(PRead32()); } - inline int32_t ReadSInt32() { return (int32_t)Alg::ByteUtil::LEToSystem(PRead32()); } - inline uint64_t ReadUInt64() { return (uint64_t)Alg::ByteUtil::LEToSystem(PRead64()); } - inline int64_t ReadSInt64() { return (int64_t)Alg::ByteUtil::LEToSystem(PRead64()); } - inline float ReadFloat() { float v = 0.0f; Read((uint8_t*)&v, 4); return Alg::ByteUtil::LEToSystem(v); } - inline double ReadDouble() { double v = 0.0; Read((uint8_t*)&v, 8); return Alg::ByteUtil::LEToSystem(v); } - // Reading primitive types - Big Endian - inline uint8_t ReadUByteBE() { return (uint8_t)Alg::ByteUtil::BEToSystem(PRead8()); } - inline int8_t ReadSByteBE() { return (int8_t)Alg::ByteUtil::BEToSystem(PRead8()); } - inline uint8_t ReadUInt8BE() { return (uint8_t)Alg::ByteUtil::BEToSystem(PRead8()); } - inline int8_t ReadSInt8BE() { return (int8_t)Alg::ByteUtil::BEToSystem(PRead8()); } - inline uint16_t ReadUInt16BE() { return (uint16_t)Alg::ByteUtil::BEToSystem(PRead16()); } - inline int16_t ReadSInt16BE() { return (int16_t)Alg::ByteUtil::BEToSystem(PRead16()); } - inline uint32_t ReadUInt32BE() { return (uint32_t)Alg::ByteUtil::BEToSystem(PRead32()); } - inline int32_t ReadSInt32BE() { return (int32_t)Alg::ByteUtil::BEToSystem(PRead32()); } - inline uint64_t ReadUInt64BE() { return (uint64_t)Alg::ByteUtil::BEToSystem(PRead64()); } - inline int64_t ReadSInt64BE() { return (int64_t)Alg::ByteUtil::BEToSystem(PRead64()); } - inline float ReadFloatBE() { float v = 0.0f; Read((uint8_t*)&v, 4); return Alg::ByteUtil::BEToSystem(v); } - inline double ReadDoubleBE() { double v = 0.0; Read((uint8_t*)&v, 8); return Alg::ByteUtil::BEToSystem(v); } -}; - - -// *** Delegated File - -class DelegatedFile : public File -{ -protected: - // Delegating file pointer - Ptr<File> pFile; - - // Hidden default constructor - DelegatedFile() : pFile(0) { } - DelegatedFile(const DelegatedFile &source) : File() { OVR_UNUSED(source); } -public: - // Constructors - DelegatedFile(File *pfile) : pFile(pfile) { } - - // ** Location Information - virtual const char* GetFilePath() { return pFile->GetFilePath(); } - - // ** File Information - virtual bool IsValid() { return pFile && pFile->IsValid(); } - virtual bool IsWritable() { return pFile->IsWritable(); } -// virtual bool IsRecoverable() { return pFile->IsRecoverable(); } - - virtual int Tell() { return pFile->Tell(); } - virtual int64_t LTell() { return pFile->LTell(); } - - virtual int GetLength() { return pFile->GetLength(); } - virtual int64_t LGetLength() { return pFile->LGetLength(); } - - //virtual bool Stat(FileStats *pfs) { return pFile->Stat(pfs); } - - virtual int GetErrorCode() { return pFile->GetErrorCode(); } - - // ** Stream implementation & I/O - virtual int Write(const uint8_t *pbuffer, int numBytes) { return pFile->Write(pbuffer,numBytes); } - virtual int Read(uint8_t *pbuffer, int numBytes) { return pFile->Read(pbuffer,numBytes); } - - virtual int SkipBytes(int numBytes) { return pFile->SkipBytes(numBytes); } - - virtual int BytesAvailable() { return pFile->BytesAvailable(); } - - virtual bool Flush() { return pFile->Flush(); } - - // Seeking - virtual int Seek(int offset, int origin=Seek_Set) { return pFile->Seek(offset,origin); } - virtual int64_t LSeek(int64_t offset, int origin=Seek_Set) { return pFile->LSeek(offset,origin); } - - virtual int CopyFromStream(File *pstream, int byteSize) { return pFile->CopyFromStream(pstream,byteSize); } - - // Closing the file - virtual bool Close() { return pFile->Close(); } -}; - - -//----------------------------------------------------------------------------------- -// ***** Buffered File - -// This file class adds buffering to an existing file -// Buffered file never fails by itself; if there's not -// enough memory for buffer, no buffer's used - -class BufferedFile : public DelegatedFile -{ -protected: - enum BufferModeType - { - NoBuffer, - ReadBuffer, - WriteBuffer - }; - - // Buffer & the mode it's in - uint8_t* pBuffer; - BufferModeType BufferMode; - // Position in buffer - unsigned Pos; - // Data in buffer if reading - unsigned DataSize; - // Underlying file position - uint64_t FilePos; - - // Initializes buffering to a certain mode - bool SetBufferMode(BufferModeType mode); - // Flushes buffer - // WriteBuffer - write data to disk, ReadBuffer - reset buffer & fix file position - void FlushBuffer(); - // Loads data into ReadBuffer - // WARNING: Right now LoadBuffer() assumes the buffer's empty - void LoadBuffer(); - - // Hidden constructor - BufferedFile(); - BufferedFile(const BufferedFile &) : DelegatedFile(), pBuffer(NULL), BufferMode(NoBuffer), Pos(0), DataSize(0), FilePos(0) { } - -public: - - // Constructor - // - takes another file as source - BufferedFile(File *pfile); - ~BufferedFile(); - - - // ** Overridden functions - - // We override all the functions that can possibly - // require buffer mode switch, flush, or extra calculations - virtual int Tell(); - virtual int64_t LTell(); - - virtual int GetLength(); - virtual int64_t LGetLength(); - -// virtual bool Stat(GFileStats *pfs); - - virtual int Write(const uint8_t *pbufer, int numBytes); - virtual int Read(uint8_t *pbufer, int numBytes); - - virtual int SkipBytes(int numBytes); - - virtual int BytesAvailable(); - - virtual bool Flush(); - - virtual int Seek(int offset, int origin=Seek_Set); - virtual int64_t LSeek(int64_t offset, int origin=Seek_Set); - - virtual int CopyFromStream(File *pstream, int byteSize); - - virtual bool Close(); -}; - - -//----------------------------------------------------------------------------------- -// ***** Memory File - -class MemoryFile : public File -{ -public: - - const char* GetFilePath() { return FilePath.ToCStr(); } - - bool IsValid() { return Valid; } - bool IsWritable() { return false; } - - bool Flush() { return true; } - int GetErrorCode() { return 0; } - - int Tell() { return FileIndex; } - int64_t LTell() { return (int64_t) FileIndex; } - - int GetLength() { return FileSize; } - int64_t LGetLength() { return (int64_t) FileSize; } - - bool Close() - { - Valid = false; - return false; - } - - int CopyFromStream(File *pstream, int byteSize) - { OVR_UNUSED2(pstream, byteSize); - return 0; - } - - int Write(const uint8_t *pbuffer, int numBytes) - { OVR_UNUSED2(pbuffer, numBytes); - return 0; - } - - int Read(uint8_t *pbufer, int numBytes) - { - if (FileIndex + numBytes > FileSize) - { - numBytes = FileSize - FileIndex; - } - - if (numBytes > 0) - { - ::memcpy (pbufer, &FileData [FileIndex], numBytes); - - FileIndex += numBytes; - } - - return numBytes; - } - - int SkipBytes(int numBytes) - { - if (FileIndex + numBytes > FileSize) - { - numBytes = FileSize - FileIndex; - } - - FileIndex += numBytes; - - return numBytes; - } - - int BytesAvailable() - { - return (FileSize - FileIndex); - } - - int Seek(int offset, int origin = Seek_Set) - { - switch (origin) - { - case Seek_Set : FileIndex = offset; break; - case Seek_Cur : FileIndex += offset; break; - case Seek_End : FileIndex = FileSize - offset; break; - } - - return FileIndex; - } - - int64_t LSeek(int64_t offset, int origin = Seek_Set) - { - return (int64_t) Seek((int) offset, origin); - } - -public: - - MemoryFile (const String& fileName, const uint8_t *pBuffer, int buffSize) - : FilePath(fileName) - { - FileData = pBuffer; - FileSize = buffSize; - FileIndex = 0; - Valid = (!fileName.IsEmpty() && pBuffer && buffSize > 0) ? true : false; - } - - // pfileName should be encoded as UTF-8 to support international file names. - MemoryFile (const char* pfileName, const uint8_t *pBuffer, int buffSize) - : FilePath(pfileName) - { - FileData = pBuffer; - FileSize = buffSize; - FileIndex = 0; - Valid = (pfileName && pBuffer && buffSize > 0) ? true : false; - } -private: - - String FilePath; - const uint8_t *FileData; - int FileSize; - int FileIndex; - bool Valid; -}; - - -// ***** Global path helpers - -// Find trailing short filename in a path. -const char* OVR_CDECL GetShortFilename(const char* purl); - -} // OVR - -#endif diff --git a/LibOVR/Src/Kernel/OVR_FileFILE.cpp b/LibOVR/Src/Kernel/OVR_FileFILE.cpp deleted file mode 100644 index 9b2123f..0000000 --- a/LibOVR/Src/Kernel/OVR_FileFILE.cpp +++ /dev/null @@ -1,609 +0,0 @@ -/************************************************************************** - -Filename : OVR_FileFILE.cpp -Content : File wrapper class implementation (Win32) - -Created : April 5, 1999 -Authors : Michael Antonov - -Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); -you may not use the Oculus VR Rift SDK except in compliance with the License, -which is provided at the time of installation or download, or which -otherwise accompanies this software in either electronic or hard copy form. - -You may obtain a copy of the License at - -http://www.oculusvr.com/licenses/LICENSE-3.2 - -Unless required by applicable law or agreed to in writing, the Oculus VR SDK -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -**************************************************************************/ - -#define GFILE_CXX - -#include "OVR_Types.h" -#include "OVR_Log.h" - -// Standard C library (Captain Obvious guarantees!) -#include <stdio.h> -#ifndef OVR_OS_WINCE -#include <sys/stat.h> -#endif - -#include "OVR_SysFile.h" - -#ifndef OVR_OS_WINCE -#include <errno.h> -#endif - -namespace OVR { - -// ***** File interface - -// ***** FILEFile - C streams file - -static int SFerror () -{ - if (errno == ENOENT) - return FileConstants::Error_FileNotFound; - else if (errno == EACCES || errno == EPERM) - return FileConstants::Error_Access; - else if (errno == ENOSPC) - return FileConstants::Error_DiskFull; - else - return FileConstants::Error_IOError; -}; - -#if defined(OVR_OS_WIN32) -#define WIN32_LEAN_AND_MEAN -#include "windows.h" -// A simple helper class to disable/enable system error mode, if necessary -// Disabling happens conditionally only if a drive name is involved -class SysErrorModeDisabler -{ - BOOL Disabled; - UINT OldMode; -public: - SysErrorModeDisabler(const char* pfileName) - { - if (pfileName && (pfileName[0]!=0) && pfileName[1]==':') - { - Disabled = TRUE; - OldMode = ::SetErrorMode(SEM_FAILCRITICALERRORS); - } - else - { - Disabled = 0; - OldMode = 0; - } - } - - ~SysErrorModeDisabler() - { - if (Disabled) - ::SetErrorMode(OldMode); - } -}; -#else -class SysErrorModeDisabler -{ -public: - SysErrorModeDisabler(const char* pfileName) { OVR_UNUSED(pfileName); } -}; -#endif // OVR_OS_WIN32 - - -// This macro enables verification of I/O results after seeks against a pre-loaded -// full file buffer copy. This is generally not necessary, but can been used to debug -// memory corruptions; we've seen this fail due to EAX2/DirectSound corrupting memory -// under FMOD with XP64 (32-bit) and Realtek HA Audio driver. -//#define GFILE_VERIFY_SEEK_ERRORS - - -// This is the simplest possible file implementation, it wraps around the descriptor -// This file is delegated to by SysFile. - -class FILEFile : public File -{ -protected: - - // Allocated filename - String FileName; - - // File handle & open mode - bool Opened; - FILE* fs; - int OpenFlags; - // Error code for last request - int ErrorCode; - - int LastOp; - -#ifdef OVR_FILE_VERIFY_SEEK_ERRORS - uint8_t* pFileTestBuffer; - unsigned FileTestLength; - unsigned TestPos; // File pointer position during tests. -#endif - -public: - - FILEFile() : - FileName(), - Opened(false), - fs(NULL), - OpenFlags(0), - ErrorCode(0), - LastOp(0) - #ifdef OVR_FILE_VERIFY_SEEK_ERRORS - ,pFileTestBuffer(NULL) - ,FileTestLength(0) - ,TestPos(0) - #endif - { - } - - // Initialize file by opening it - FILEFile(const String& fileName, int flags, int Mode); - - // The 'pfileName' should be encoded as UTF-8 to support international file names. - FILEFile(const char* pfileName, int flags, int Mode); - - ~FILEFile() - { - if (Opened) - Close(); - } - - virtual const char* GetFilePath(); - - // ** File Information - virtual bool IsValid(); - virtual bool IsWritable(); - - // Return position / file size - virtual int Tell(); - virtual int64_t LTell(); - virtual int GetLength(); - virtual int64_t LGetLength(); - -// virtual bool Stat(FileStats *pfs); - virtual int GetErrorCode(); - - // ** Stream implementation & I/O - virtual int Write(const uint8_t *pbuffer, int numBytes); - virtual int Read(uint8_t *pbuffer, int numBytes); - virtual int SkipBytes(int numBytes); - virtual int BytesAvailable(); - virtual bool Flush(); - virtual int Seek(int offset, int origin); - virtual int64_t LSeek(int64_t offset, int origin); - - virtual int CopyFromStream(File *pStream, int byteSize); - virtual bool Close(); -private: - void init(); -}; - - -// Initialize file by opening it -FILEFile::FILEFile(const String& fileName, int flags, int mode) - : FileName(fileName), OpenFlags(flags) -{ - OVR_UNUSED(mode); - init(); -} - -// The 'pfileName' should be encoded as UTF-8 to support international file names. -FILEFile::FILEFile(const char* pfileName, int flags, int mode) - : FileName(pfileName), OpenFlags(flags) -{ - OVR_UNUSED(mode); - init(); -} - -void FILEFile::init() -{ - // Open mode for file's open - const char *omode = "rb"; - - if (OpenFlags & Open_Truncate) - { - if (OpenFlags & Open_Read) - omode = "w+b"; - else - omode = "wb"; - } - else if (OpenFlags & Open_Create) - { - if (OpenFlags & Open_Read) - omode = "a+b"; - else - omode = "ab"; - } - else if (OpenFlags & Open_Write) - omode = "r+b"; - -#if defined(OVR_OS_MS) - SysErrorModeDisabler disabler(FileName.ToCStr()); -#endif - -#if defined(OVR_CC_MSVC) && (OVR_CC_MSVC >= 1400) - wchar_t womode[16]; - wchar_t *pwFileName = (wchar_t*)OVR_ALLOC((UTF8Util::GetLength(FileName.ToCStr())+1) * sizeof(wchar_t)); - UTF8Util::DecodeString(pwFileName, FileName.ToCStr()); - OVR_ASSERT(strlen(omode) < sizeof(womode)/sizeof(womode[0])); - UTF8Util::DecodeString(womode, omode); - _wfopen_s(&fs, pwFileName, womode); - OVR_FREE(pwFileName); -#else - fs = fopen(FileName.ToCStr(), omode); -#endif - if (fs) - rewind (fs); - Opened = (fs != NULL); - // Set error code - if (!Opened) - ErrorCode = SFerror(); - else - { - // If we are testing file seek correctness, pre-load the entire file so - // that we can do comparison tests later. -#ifdef OVR_FILE_VERIFY_SEEK_ERRORS - TestPos = 0; - fseek(fs, 0, SEEK_END); - FileTestLength = ftell(fs); - fseek(fs, 0, SEEK_SET); - pFileTestBuffer = (uint8_t*)OVR_ALLOC(FileTestLength); - if (pFileTestBuffer) - { - OVR_ASSERT(FileTestLength == (unsigned)Read(pFileTestBuffer, FileTestLength)); - Seek(0, Seek_Set); - } -#endif - - ErrorCode = 0; - } - LastOp = 0; -} - - -const char* FILEFile::GetFilePath() -{ - return FileName.ToCStr(); -} - - -// ** File Information -bool FILEFile::IsValid() -{ - return Opened; -} -bool FILEFile::IsWritable() -{ - return IsValid() && (OpenFlags&Open_Write); -} -/* -bool FILEFile::IsRecoverable() -{ - return IsValid() && ((OpenFlags&OVR_FO_SAFETRUNC) == OVR_FO_SAFETRUNC); -} -*/ - -// Return position / file size -int FILEFile::Tell() -{ - int pos = (int)ftell (fs); - if (pos < 0) - ErrorCode = SFerror(); - return pos; -} - -int64_t FILEFile::LTell() -{ - int64_t pos = ftell(fs); - if (pos < 0) - ErrorCode = SFerror(); - return pos; -} - -int FILEFile::GetLength() -{ - int pos = Tell(); - if (pos >= 0) - { - Seek (0, Seek_End); - int size = Tell(); - Seek (pos, Seek_Set); - return size; - } - return -1; -} -int64_t FILEFile::LGetLength() -{ - int64_t pos = LTell(); - if (pos >= 0) - { - LSeek (0, Seek_End); - int64_t size = LTell(); - LSeek (pos, Seek_Set); - return size; - } - return -1; -} - -int FILEFile::GetErrorCode() -{ - return ErrorCode; -} - -// ** Stream implementation & I/O -int FILEFile::Write(const uint8_t *pbuffer, int numBytes) -{ - if (LastOp && LastOp != Open_Write) - fflush(fs); - LastOp = Open_Write; - int written = (int) fwrite(pbuffer, 1, numBytes, fs); - if (written < numBytes) - ErrorCode = SFerror(); - -#ifdef OVR_FILE_VERIFY_SEEK_ERRORS - if (written > 0) - TestPos += written; -#endif - - return written; -} - -int FILEFile::Read(uint8_t *pbuffer, int numBytes) -{ - if (LastOp && LastOp != Open_Read) - fflush(fs); - LastOp = Open_Read; - int read = (int) fread(pbuffer, 1, numBytes, fs); - if (read < numBytes) - ErrorCode = SFerror(); - -#ifdef OVR_FILE_VERIFY_SEEK_ERRORS - if (read > 0) - { - // Read-in data must match our pre-loaded buffer data! - uint8_t* pcompareBuffer = pFileTestBuffer + TestPos; - for (int i=0; i< read; i++) - { - OVR_ASSERT(pcompareBuffer[i] == pbuffer[i]); - } - - //OVR_ASSERT(!memcmp(pFileTestBuffer + TestPos, pbuffer, read)); - TestPos += read; - OVR_ASSERT(ftell(fs) == (int)TestPos); - } -#endif - - return read; -} - -// Seeks ahead to skip bytes -int FILEFile::SkipBytes(int numBytes) -{ - int64_t pos = LTell(); - int64_t newPos = LSeek(numBytes, Seek_Cur); - - // Return -1 for major error - if ((pos==-1) || (newPos==-1)) - { - return -1; - } - //ErrorCode = ((NewPos-Pos)<numBytes) ? errno : 0; - - return int (newPos-(int)pos); -} - -// Return # of bytes till EOF -int FILEFile::BytesAvailable() -{ - int64_t pos = LTell(); - int64_t endPos = LGetLength(); - - // Return -1 for major error - if ((pos==-1) || (endPos==-1)) - { - ErrorCode = SFerror(); - return 0; - } - else - ErrorCode = 0; - - return int (endPos-(int)pos); -} - -// Flush file contents -bool FILEFile::Flush() -{ - return !fflush(fs); -} - -int FILEFile::Seek(int offset, int origin) -{ - int newOrigin = 0; - switch(origin) - { - case Seek_Set: newOrigin = SEEK_SET; break; - case Seek_Cur: newOrigin = SEEK_CUR; break; - case Seek_End: newOrigin = SEEK_END; break; - } - - if (newOrigin == SEEK_SET && offset == Tell()) - return Tell(); - - if (fseek (fs, offset, newOrigin)) - { -#ifdef OVR_FILE_VERIFY_SEEK_ERRORS - OVR_ASSERT(0); -#endif - return -1; - } - -#ifdef OVR_FILE_VERIFY_SEEK_ERRORS - // Track file position after seeks for read verification later. - switch(origin) - { - case Seek_Set: TestPos = offset; break; - case Seek_Cur: TestPos += offset; break; - case Seek_End: TestPos = FileTestLength + offset; break; - } - OVR_ASSERT((int)TestPos == Tell()); -#endif - - return (int)Tell(); -} - -int64_t FILEFile::LSeek(int64_t offset, int origin) -{ - return Seek((int)offset,origin); -} - -int FILEFile::CopyFromStream(File *pstream, int byteSize) -{ - uint8_t* buff = new uint8_t[0x4000]; - int count = 0; - int szRequest, szRead, szWritten; - - while (byteSize) - { - szRequest = (byteSize > int(sizeof(buff))) ? int(sizeof(buff)) : byteSize; - - szRead = pstream->Read(buff, szRequest); - szWritten = 0; - if (szRead > 0) - szWritten = Write(buff, szRead); - - count += szWritten; - byteSize -= szWritten; - if (szWritten < szRequest) - break; - } - - delete[] buff; - - return count; -} - - -bool FILEFile::Close() -{ -#ifdef OVR_FILE_VERIFY_SEEK_ERRORS - if (pFileTestBuffer) - { - OVR_FREE(pFileTestBuffer); - pFileTestBuffer = 0; - FileTestLength = 0; - } -#endif - - bool closeRet = !fclose(fs); - - if (!closeRet) - { - ErrorCode = SFerror(); - return 0; - } - else - { - Opened = 0; - fs = 0; - ErrorCode = 0; - } - - // Handle safe truncate - /* - if ((OpenFlags & OVR_FO_SAFETRUNC) == OVR_FO_SAFETRUNC) - { - // Delete original file (if it existed) - DWORD oldAttributes = FileUtilWin32::GetFileAttributes(FileName); - if (oldAttributes!=0xFFFFFFFF) - if (!FileUtilWin32::DeleteFile(FileName)) - { - // Try to remove the readonly attribute - FileUtilWin32::SetFileAttributes(FileName, oldAttributes & (~FILE_ATTRIBUTE_READONLY) ); - // And delete the file again - if (!FileUtilWin32::DeleteFile(FileName)) - return 0; - } - - // Rename temp file to real filename - if (!FileUtilWin32::MoveFile(TempName, FileName)) - { - //ErrorCode = errno; - return 0; - } - } - */ - return 1; -} - -/* -bool FILEFile::CloseCancel() -{ - bool closeRet = (bool)::CloseHandle(fd); - - if (!closeRet) - { - //ErrorCode = errno; - return 0; - } - else - { - Opened = 0; - fd = INVALID_HANDLE_VALUE; - ErrorCode = 0; - } - - // Handle safe truncate (delete tmp file, leave original unchanged) - if ((OpenFlags&OVR_FO_SAFETRUNC) == OVR_FO_SAFETRUNC) - if (!FileUtilWin32::DeleteFile(TempName)) - { - //ErrorCode = errno; - return 0; - } - return 1; -} -*/ - -Ptr<File> FileFILEOpen(const String& path, int flags, int mode) -{ - Ptr<File> result = *new FILEFile(path, flags, mode); - return result; -} - -// Helper function: obtain file information time. -bool SysFile::GetFileStat(FileStat* pfileStat, const String& path) -{ -#if defined(OVR_OS_MS) - // 64-bit implementation on Windows. - struct __stat64 fileStat; - // Stat returns 0 for success. - wchar_t *pwpath = (wchar_t*)OVR_ALLOC((UTF8Util::GetLength(path.ToCStr())+1)*sizeof(wchar_t)); - UTF8Util::DecodeString(pwpath, path.ToCStr()); - - int ret = _wstat64(pwpath, &fileStat); - OVR_FREE(pwpath); - if (ret) return false; -#else - struct stat fileStat; - // Stat returns 0 for success. - if (stat(path, &fileStat) != 0) - return false; -#endif - pfileStat->AccessTime = fileStat.st_atime; - pfileStat->ModifyTime = fileStat.st_mtime; - pfileStat->FileSize = fileStat.st_size; - return true; -} - -} // Namespace OVR diff --git a/LibOVR/Src/Kernel/OVR_Hash.h b/LibOVR/Src/Kernel/OVR_Hash.h deleted file mode 100644 index 3316d1e..0000000 --- a/LibOVR/Src/Kernel/OVR_Hash.h +++ /dev/null @@ -1,1305 +0,0 @@ -/************************************************************************************ - -PublicHeader: None -Filename : OVR_Hash.h -Content : Template hash-table/set implementation -Created : September 19, 2012 -Notes : - -Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); -you may not use the Oculus VR Rift SDK except in compliance with the License, -which is provided at the time of installation or download, or which -otherwise accompanies this software in either electronic or hard copy form. - -You may obtain a copy of the License at - -http://www.oculusvr.com/licenses/LICENSE-3.2 - -Unless required by applicable law or agreed to in writing, the Oculus VR SDK -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -************************************************************************************/ - -#ifndef OVR_Hash_h -#define OVR_Hash_h - -#include "OVR_ContainerAllocator.h" -#include "OVR_Alg.h" - -// 'new' operator is redefined/used in this file. -#undef new - -namespace OVR { - -//----------------------------------------------------------------------------------- -// ***** Hash Table Implementation - -// HastSet and Hash. -// -// Hash table, linear probing, internal chaining. One interesting/nice thing -// about this implementation is that the table itself is a flat chunk of memory -// containing no pointers, only relative indices. If the key and value types -// of the Hash contain no pointers, then the Hash can be serialized using raw IO. -// -// Never shrinks, unless you explicitly Clear() it. Expands on -// demand, though. For best results, if you know roughly how big your -// table will be, default it to that size when you create it. -// -// Key usability feature: -// -// 1. Allows node hash values to either be cached or not. -// -// 2. Allows for alternative keys with methods such as GetAlt(). Handy -// if you need to search nodes by their components; no need to create -// temporary nodes. -// - - -// *** Hash functors: -// -// IdentityHash - use when the key is already a good hash -// HFixedSizeHash - general hash based on object's in-memory representation. - - -// Hash is just the input value; can use this for integer-indexed hash tables. -template<class C> -class IdentityHash -{ -public: - size_t operator()(const C& data) const - { return (size_t) data; } -}; - -// Computes a hash of an object's representation. -template<class C> -class FixedSizeHash -{ -public: - // Alternative: "sdbm" hash function, suggested at same web page - // above, http::/www.cs.yorku.ca/~oz/hash.html - // This is somewhat slower then Bernstein, but it works way better than the above - // hash function for hashing large numbers of 32-bit ints. - static OVR_FORCE_INLINE size_t SDBM_Hash(const void* data_in, size_t size, size_t seed = 5381) - { - const uint8_t* data = (const uint8_t*) data_in; - size_t h = seed; - while (size-- > 0) - { - #ifndef __clang_analyzer__ // It mistakenly thinks data is garbage. - h = (h << 16) + (h << 6) - h + (size_t)data[size]; - #endif - } - return h; - } - - size_t operator()(const C& data) const - { - const unsigned char* p = (const unsigned char*) &data; - const size_t size = sizeof(C); - - return SDBM_Hash(p, size); - } -}; - - - -// *** HashsetEntry Entry types. - -// Compact hash table Entry type that re-computes hash keys during hash traversal. -// Good to use if the hash function is cheap or the hash value is already cached in C. -template<class C, class HashF> -class HashsetEntry -{ -public: - // Internal chaining for collisions. - intptr_t NextInChain; - C Value; - - HashsetEntry() - : NextInChain(-2) { } - HashsetEntry(const HashsetEntry& e) - : NextInChain(e.NextInChain), Value(e.Value) { } - HashsetEntry(const C& key, intptr_t next) - : NextInChain(next), Value(key) { } - - bool IsEmpty() const { return NextInChain == -2; } - bool IsEndOfChain() const { return NextInChain == -1; } - - // Cached hash value access - can be optimized bu storing hash locally. - // Mask value only needs to be used if SetCachedHash is not implemented. - size_t GetCachedHash(size_t maskValue) const { return HashF()(Value) & maskValue; } - void SetCachedHash(size_t) {} - - void Clear() - { - Value.~C(); // placement delete - NextInChain = -2; - } - // Free is only used from dtor of hash; Clear is used during regular operations: - // assignment, hash reallocations, value reassignments, so on. - void Free() { Clear(); } -}; - -// Hash table Entry type that caches the Entry hash value for nodes, so that it -// does not need to be re-computed during access. -template<class C, class HashF> -class HashsetCachedEntry -{ -public: - // Internal chaining for collisions. - intptr_t NextInChain; - size_t HashValue; - C Value; - - HashsetCachedEntry() - : NextInChain(-2) { } - HashsetCachedEntry(const HashsetCachedEntry& e) - : NextInChain(e.NextInChain), HashValue(e.HashValue), Value(e.Value) { } - HashsetCachedEntry(const C& key, intptr_t next) - : NextInChain(next), Value(key) { } - - bool IsEmpty() const { return NextInChain == -2; } - bool IsEndOfChain() const { return NextInChain == -1; } - - // Cached hash value access - can be optimized bu storing hash locally. - // Mask value only needs to be used if SetCachedHash is not implemented. - size_t GetCachedHash(size_t maskValue) const { OVR_UNUSED(maskValue); return HashValue; } - void SetCachedHash(size_t hashValue) { HashValue = hashValue; } - - void Clear() - { - Value.~C(); - NextInChain = -2; - } - // Free is only used from dtor of hash; Clear is used during regular operations: - // assignment, hash reallocations, value reassignments, so on. - void Free() { Clear(); } -}; - - -//----------------------------------------------------------------------------------- -// *** HashSet implementation - relies on either cached or regular entries. -// -// Use: Entry = HashsetCachedEntry<C, HashF> if hashes are expensive to -// compute and thus need caching in entries. -// Entry = HashsetEntry<C, HashF> if hashes are already externally cached. -// -template<class C, class HashF = FixedSizeHash<C>, - class AltHashF = HashF, - class Allocator = ContainerAllocator<C>, - class Entry = HashsetCachedEntry<C, HashF> > -class HashSetBase -{ - enum { HashMinSize = 8 }; - -public: - OVR_MEMORY_REDEFINE_NEW(HashSetBase) - - typedef HashSetBase<C, HashF, AltHashF, Allocator, Entry> SelfType; - - HashSetBase() : pTable(NULL) { } - HashSetBase(int sizeHint) : pTable(NULL) { SetCapacity(this, sizeHint); } - HashSetBase(const SelfType& src) : pTable(NULL) { Assign(this, src); } - - ~HashSetBase() - { - if (pTable) - { - // Delete the entries. - for (size_t i = 0, n = pTable->SizeMask; i <= n; i++) - { - Entry* e = &E(i); - if (!e->IsEmpty()) - e->Free(); - } - - Allocator::Free(pTable); - pTable = NULL; - } - } - - - void Assign(const SelfType& src) - { - Clear(); - if (src.IsEmpty() == false) - { - SetCapacity(src.GetSize()); - - for (ConstIterator it = src.Begin(); it != src.End(); ++it) - { - Add(*it); - } - } - } - - - // Remove all entries from the HashSet table. - void Clear() - { - if (pTable) - { - // Delete the entries. - for (size_t i = 0, n = pTable->SizeMask; i <= n; i++) - { - Entry* e = &E(i); - if (!e->IsEmpty()) - e->Clear(); - } - - Allocator::Free(pTable); - pTable = NULL; - } - } - - // Returns true if the HashSet is empty. - bool IsEmpty() const - { - return pTable == NULL || pTable->EntryCount == 0; - } - - - // Set a new or existing value under the key, to the value. - // Pass a different class of 'key' so that assignment reference object - // can be passed instead of the actual object. - template<class CRef> - void Set(const CRef& key) - { - size_t hashValue = HashF()(key); - intptr_t index = (intptr_t)-1; - - if (pTable != NULL) - index = findIndexCore(key, hashValue & pTable->SizeMask); - - if (index >= 0) - { - E(index).Value = key; - } - else - { - // Entry under key doesn't exist. - add(key, hashValue); - } - } - - template<class CRef> - inline void Add(const CRef& key) - { - size_t hashValue = HashF()(key); - add(key, hashValue); - } - - // Remove by alternative key. - template<class K> - void RemoveAlt(const K& key) - { - if (pTable == NULL) - return; - - size_t hashValue = AltHashF()(key); - intptr_t index = hashValue & pTable->SizeMask; - - Entry* e = &E(index); - - // If empty node or occupied by collider, we have nothing to remove. - if (e->IsEmpty() || (e->GetCachedHash(pTable->SizeMask) != (size_t)index)) - return; - - // Save index - intptr_t naturalIndex = index; - intptr_t prevIndex = -1; - - while ((e->GetCachedHash(pTable->SizeMask) != (size_t)naturalIndex) || !(e->Value == key)) - { - // Keep looking through the chain. - prevIndex = index; - index = e->NextInChain; - if (index == -1) - return; // End of chain, item not found - e = &E(index); - } - - // Found it - our item is at index - if (naturalIndex == index) - { - // If we have a follower, move it to us - if (!e->IsEndOfChain()) - { - Entry* enext = &E(e->NextInChain); - e->Clear(); - new (e) Entry(*enext); - // Point us to the follower's cell that will be cleared - e = enext; - } - } - else - { - // We are not at natural index, so deal with the prev items next index - E(prevIndex).NextInChain = e->NextInChain; - } - - // Clear us, of the follower cell that was moved. - e->Clear(); - pTable->EntryCount --; - // Should we check the size to condense hash? ... - } - - // Remove by main key. - template<class CRef> - void Remove(const CRef& key) - { - RemoveAlt(key); - } - - // Retrieve the pointer to a value under the given key. - // - If there's no value under the key, then return NULL. - // - If there is a value, return the pointer. - template<class K> - C* Get(const K& key) - { - intptr_t index = findIndex(key); - if (index >= 0) - return &E(index).Value; - return 0; - } - - template<class K> - const C* Get(const K& key) const - { - intptr_t index = findIndex(key); - if (index >= 0) - return &E(index).Value; - return 0; - } - - // Alternative key versions of Get. Used by Hash. - template<class K> - const C* GetAlt(const K& key) const - { - intptr_t index = findIndexAlt(key); - if (index >= 0) - return &E(index).Value; - return 0; - } - - template<class K> - C* GetAlt(const K& key) - { - intptr_t index = findIndexAlt(key); - if (index >= 0) - return &E(index).Value; - return 0; - } - - template<class K> - bool GetAlt(const K& key, C* pval) const - { - intptr_t index = findIndexAlt(key); - if (index >= 0) - { - if (pval) - *pval = E(index).Value; - return true; - } - return false; - } - - - size_t GetSize() const - { - return pTable == NULL ? 0 : (size_t)pTable->EntryCount; - } - int GetSizeI() const { return (int)GetSize(); } - - - // Resize the HashSet table to fit one more Entry. Often this - // doesn't involve any action. - void CheckExpand() - { - if (pTable == NULL) - { - // Initial creation of table. Make a minimum-sized table. - setRawCapacity(HashMinSize); - } - else if (pTable->EntryCount * 5 > (pTable->SizeMask + 1) * 4) - { - // pTable is more than 5/4 ths full. Expand. - setRawCapacity((pTable->SizeMask + 1) * 2); - } - } - - // Hint the bucket count to >= n. - void Resize(size_t n) - { - // Not really sure what this means in relation to - // STLport's hash_map... they say they "increase the - // bucket count to at least n" -- but does that mean - // their real capacity after Resize(n) is more like - // n*2 (since they do linked-list chaining within - // buckets?). - SetCapacity(n); - } - - // Size the HashSet so that it can comfortably contain the given - // number of elements. If the HashSet already contains more - // elements than newSize, then this may be a no-op. - void SetCapacity(size_t newSize) - { - size_t newRawSize = (newSize * 5) / 4; - if (newRawSize <= GetSize()) - return; - setRawCapacity(newRawSize); - } - - // Disable inappropriate 'operator ->' warning on MSVC6. -#ifdef OVR_CC_MSVC -#if (OVR_CC_MSVC < 1300) -# pragma warning(disable : 4284) -#endif -#endif - - // Iterator API, like STL. - struct ConstIterator - { - const C& operator * () const - { - OVR_ASSERT(Index >= 0 && Index <= (intptr_t)pHash->pTable->SizeMask); - return pHash->E(Index).Value; - } - - const C* operator -> () const - { - OVR_ASSERT(Index >= 0 && Index <= (intptr_t)pHash->pTable->SizeMask); - return &pHash->E(Index).Value; - } - - void operator ++ () - { - // Find next non-empty Entry. - if (Index <= (intptr_t)pHash->pTable->SizeMask) - { - Index++; - while ((size_t)Index <= pHash->pTable->SizeMask && - pHash->E(Index).IsEmpty()) - { - Index++; - } - } - } - - bool operator == (const ConstIterator& it) const - { - if (IsEnd() && it.IsEnd()) - { - return true; - } - else - { - return (pHash == it.pHash) && (Index == it.Index); - } - } - - bool operator != (const ConstIterator& it) const - { - return ! (*this == it); - } - - - bool IsEnd() const - { - return (pHash == NULL) || - (pHash->pTable == NULL) || - (Index > (intptr_t)pHash->pTable->SizeMask); - } - - ConstIterator() - : pHash(NULL), Index(0) - { } - - public: - // Constructor was intentionally made public to allow create - // iterator with arbitrary index. - ConstIterator(const SelfType* h, intptr_t index) - : pHash(h), Index(index) - { } - - const SelfType* GetContainer() const - { - return pHash; - } - intptr_t GetIndex() const - { - return Index; - } - - protected: - friend class HashSetBase<C, HashF, AltHashF, Allocator, Entry>; - - const SelfType* pHash; - intptr_t Index; - }; - - friend struct ConstIterator; - - - // Non-const Iterator; Get most of it from ConstIterator. - struct Iterator : public ConstIterator - { - // Allow non-const access to entries. - C& operator*() const - { - OVR_ASSERT((ConstIterator::pHash) && ConstIterator::pHash->pTable && (ConstIterator::Index >= 0) && (ConstIterator::Index <= (intptr_t)ConstIterator::pHash->pTable->SizeMask)); - return const_cast<SelfType*>(ConstIterator::pHash)->E(ConstIterator::Index).Value; - } - - C* operator->() const - { - return &(operator*()); - } - - Iterator() - : ConstIterator(NULL, 0) - { } - - // Removes current element from Hash - void Remove() - { - RemoveAlt(operator*()); - } - - template <class K> - void RemoveAlt(const K& key) - { - SelfType* phash = const_cast<SelfType*>(ConstIterator::pHash); - //Entry* ee = &phash->E(ConstIterator::Index); - //const C& key = ee->Value; - - size_t hashValue = AltHashF()(key); - intptr_t index = hashValue & phash->pTable->SizeMask; - - Entry* e = &phash->E(index); - - // If empty node or occupied by collider, we have nothing to remove. - if (e->IsEmpty() || (e->GetCachedHash(phash->pTable->SizeMask) != (size_t)index)) - return; - - // Save index - intptr_t naturalIndex = index; - intptr_t prevIndex = -1; - - while ((e->GetCachedHash(phash->pTable->SizeMask) != (size_t)naturalIndex) || !(e->Value == key)) - { - // Keep looking through the chain. - prevIndex = index; - index = e->NextInChain; - if (index == -1) - return; // End of chain, item not found - e = &phash->E(index); - } - - if (index == (intptr_t)ConstIterator::Index) - { - // Found it - our item is at index - if (naturalIndex == index) - { - // If we have a follower, move it to us - if (!e->IsEndOfChain()) - { - Entry* enext = &phash->E(e->NextInChain); - e->Clear(); - new (e) Entry(*enext); - // Point us to the follower's cell that will be cleared - e = enext; - --ConstIterator::Index; - } - } - else - { - // We are not at natural index, so deal with the prev items next index - phash->E(prevIndex).NextInChain = e->NextInChain; - } - - // Clear us, of the follower cell that was moved. - e->Clear(); - phash->pTable->EntryCount --; - } - else - OVR_ASSERT(0); //? - } - - private: - friend class HashSetBase<C, HashF, AltHashF, Allocator, Entry>; - - Iterator(SelfType* h, intptr_t i0) - : ConstIterator(h, i0) - { } - }; - - friend struct Iterator; - - Iterator Begin() - { - if (pTable == 0) - return Iterator(NULL, 0); - - // Scan till we hit the First valid Entry. - size_t i0 = 0; - while (i0 <= pTable->SizeMask && E(i0).IsEmpty()) - { - i0++; - } - return Iterator(this, i0); - } - Iterator End() { return Iterator(NULL, 0); } - - ConstIterator Begin() const { return const_cast<SelfType*>(this)->Begin(); } - ConstIterator End() const { return const_cast<SelfType*>(this)->End(); } - - template<class K> - Iterator Find(const K& key) - { - intptr_t index = findIndex(key); - if (index >= 0) - return Iterator(this, index); - return Iterator(NULL, 0); - } - - template<class K> - Iterator FindAlt(const K& key) - { - intptr_t index = findIndexAlt(key); - if (index >= 0) - return Iterator(this, index); - return Iterator(NULL, 0); - } - - template<class K> - ConstIterator Find(const K& key) const { return const_cast<SelfType*>(this)->Find(key); } - - template<class K> - ConstIterator FindAlt(const K& key) const { return const_cast<SelfType*>(this)->FindAlt(key); } - -private: - // Find the index of the matching Entry. If no match, then return -1. - template<class K> - intptr_t findIndex(const K& key) const - { - if (pTable == NULL) - return -1; - size_t hashValue = HashF()(key) & pTable->SizeMask; - return findIndexCore(key, hashValue); - } - - template<class K> - intptr_t findIndexAlt(const K& key) const - { - if (pTable == NULL) - return -1; - size_t hashValue = AltHashF()(key) & pTable->SizeMask; - return findIndexCore(key, hashValue); - } - - // Find the index of the matching Entry. If no match, then return -1. - template<class K> - intptr_t findIndexCore(const K& key, size_t hashValue) const - { - // Table must exist. - OVR_ASSERT(pTable != 0); - // Hash key must be 'and-ed' by the caller. - OVR_ASSERT((hashValue & ~pTable->SizeMask) == 0); - - size_t index = hashValue; - const Entry* e = &E(index); - - // If empty or occupied by a collider, not found. - if (e->IsEmpty() || (e->GetCachedHash(pTable->SizeMask) != index)) - return -1; - - while(1) - { - OVR_ASSERT(e->GetCachedHash(pTable->SizeMask) == hashValue); - - if (e->GetCachedHash(pTable->SizeMask) == hashValue && e->Value == key) - { - // Found it. - return index; - } - // Values can not be equal at this point. - // That would mean that the hash key for the same value differs. - OVR_ASSERT(!(e->Value == key)); - - // Keep looking through the chain. - index = e->NextInChain; - if (index == (size_t)-1) - break; // end of chain - - e = &E(index); - OVR_ASSERT(!e->IsEmpty()); - } - return -1; - } - - - // Add a new value to the HashSet table, under the specified key. - template<class CRef> - void add(const CRef& key, size_t hashValue) - { - CheckExpand(); - hashValue &= pTable->SizeMask; - - pTable->EntryCount++; - - intptr_t index = hashValue; - Entry* naturalEntry = &(E(index)); - - if (naturalEntry->IsEmpty()) - { - // Put the new Entry in. - new (naturalEntry) Entry(key, -1); - } - else - { - // Find a blank spot. - intptr_t blankIndex = index; - do { - blankIndex = (blankIndex + 1) & pTable->SizeMask; - } while(!E(blankIndex).IsEmpty()); - - Entry* blankEntry = &E(blankIndex); - - if (naturalEntry->GetCachedHash(pTable->SizeMask) == (size_t)index) - { - // Collision. Link into this chain. - - // Move existing list head. - new (blankEntry) Entry(*naturalEntry); // placement new, copy ctor - - // Put the new info in the natural Entry. - naturalEntry->Value = key; - naturalEntry->NextInChain = blankIndex; - } - else - { - // Existing Entry does not naturally - // belong in this slot. Existing - // Entry must be moved. - - // Find natural location of collided element (i.e. root of chain) - intptr_t collidedIndex = naturalEntry->GetCachedHash(pTable->SizeMask); - OVR_ASSERT(collidedIndex >= 0 && collidedIndex <= (intptr_t)pTable->SizeMask); - for (;;) - { - Entry* e = &E(collidedIndex); - if (e->NextInChain == index) - { - // Here's where we need to splice. - new (blankEntry) Entry(*naturalEntry); - e->NextInChain = blankIndex; - break; - } - collidedIndex = e->NextInChain; - OVR_ASSERT(collidedIndex >= 0 && collidedIndex <= (intptr_t)pTable->SizeMask); - } - - // Put the new data in the natural Entry. - naturalEntry->Value = key; - naturalEntry->NextInChain = -1; - } - } - - // Record hash value: has effect only if cached node is used. - naturalEntry->SetCachedHash(hashValue); - } - - // Index access helpers. - Entry& E(size_t index) - { - // Must have pTable and access needs to be within bounds. - OVR_ASSERT(index <= pTable->SizeMask); - return *(((Entry*) (pTable + 1)) + index); - } - const Entry& E(size_t index) const - { - OVR_ASSERT(index <= pTable->SizeMask); - return *(((Entry*) (pTable + 1)) + index); - } - - - // Resize the HashSet table to the given size (Rehash the - // contents of the current table). The arg is the number of - // HashSet table entries, not the number of elements we should - // actually contain (which will be less than this). - void setRawCapacity(size_t newSize) - { - if (newSize == 0) - { - // Special case. - Clear(); - return; - } - - // Minimum size; don't incur rehashing cost when expanding - // very small tables. Not that we perform this check before - // 'log2f' call to avoid fp exception with newSize == 1. - if (newSize < HashMinSize) - newSize = HashMinSize; - else - { - // Force newSize to be a power of two. - int bits = Alg::UpperBit(newSize-1) + 1; // Chop( Log2f((float)(newSize-1)) + 1); - OVR_ASSERT((size_t(1) << bits) >= newSize); - newSize = size_t(1) << bits; - } - - SelfType newHash; - newHash.pTable = (TableType*) - Allocator::Alloc( - sizeof(TableType) + sizeof(Entry) * newSize); - // Need to do something on alloc failure! - OVR_ASSERT(newHash.pTable); - - newHash.pTable->EntryCount = 0; - newHash.pTable->SizeMask = newSize - 1; - size_t i, n; - - // Mark all entries as empty. - for (i = 0; i < newSize; i++) - newHash.E(i).NextInChain = -2; - - // Copy stuff to newHash - if (pTable) - { - for (i = 0, n = pTable->SizeMask; i <= n; i++) - { - Entry* e = &E(i); - if (e->IsEmpty() == false) - { - // Insert old Entry into new HashSet. - newHash.Add(e->Value); - // placement delete of old element - e->Clear(); - } - } - - // Delete our old data buffer. - Allocator::Free(pTable); - } - - // Steal newHash's data. - pTable = newHash.pTable; - newHash.pTable = NULL; - } - - struct TableType - { - size_t EntryCount; - size_t SizeMask; - // Entry array follows this structure - // in memory. - }; - TableType* pTable; -}; - - - -//----------------------------------------------------------------------------------- -template<class C, class HashF = FixedSizeHash<C>, - class AltHashF = HashF, - class Allocator = ContainerAllocator<C>, - class Entry = HashsetCachedEntry<C, HashF> > -class HashSet : public HashSetBase<C, HashF, AltHashF, Allocator, Entry> -{ -public: - typedef HashSetBase<C, HashF, AltHashF, Allocator, Entry> BaseType; - typedef HashSet<C, HashF, AltHashF, Allocator, Entry> SelfType; - - HashSet() { } - HashSet(int sizeHint) : BaseType(sizeHint) { } - HashSet(const SelfType& src) : BaseType(src) { } - ~HashSet() { } - - void operator = (const SelfType& src) { BaseType::Assign(src); } - - // Set a new or existing value under the key, to the value. - // Pass a different class of 'key' so that assignment reference object - // can be passed instead of the actual object. - template<class CRef> - void Set(const CRef& key) - { - BaseType::Set(key); - } - - template<class CRef> - inline void Add(const CRef& key) - { - BaseType::Add(key); - } - - // Hint the bucket count to >= n. - void Resize(size_t n) - { - BaseType::SetCapacity(n); - } - - // Size the HashSet so that it can comfortably contain the given - // number of elements. If the HashSet already contains more - // elements than newSize, then this may be a no-op. - void SetCapacity(size_t newSize) - { - BaseType::SetCapacity(newSize); - } - -}; - -// HashSet with uncached hash code; declared for convenience. -template<class C, class HashF = FixedSizeHash<C>, - class AltHashF = HashF, - class Allocator = ContainerAllocator<C> > -class HashSetUncached : public HashSet<C, HashF, AltHashF, Allocator, HashsetEntry<C, HashF> > -{ -public: - - typedef HashSetUncached<C, HashF, AltHashF, Allocator> SelfType; - typedef HashSet<C, HashF, AltHashF, Allocator, HashsetEntry<C, HashF> > BaseType; - - // Delegated constructors. - HashSetUncached() { } - HashSetUncached(int sizeHint) : BaseType(sizeHint) { } - HashSetUncached(const SelfType& src) : BaseType(src) { } - ~HashSetUncached() { } - - void operator = (const SelfType& src) - { - BaseType::operator = (src); - } -}; - - -//----------------------------------------------------------------------------------- -// ***** Hash hash table implementation - -// Node for Hash - necessary so that Hash can delegate its implementation -// to HashSet. -template<class C, class U, class HashF> -struct HashNode -{ - typedef HashNode<C, U, HashF> SelfType; - typedef C FirstType; - typedef U SecondType; - - C First; - U Second; - - // NodeRef is used to allow passing of elements into HashSet - // without using a temporary object. - struct NodeRef - { - const C* pFirst; - const U* pSecond; - - NodeRef(const C& f, const U& s) : pFirst(&f), pSecond(&s) { } - NodeRef(const NodeRef& src) : pFirst(src.pFirst), pSecond(src.pSecond) { } - - // Enable computation of ghash_node_hashf. - inline size_t GetHash() const { return HashF()(*pFirst); } - // Necessary conversion to allow HashNode::operator == to work. - operator const C& () const { return *pFirst; } - }; - - // Note: No default constructor is necessary. - HashNode(const HashNode& src) : First(src.First), Second(src.Second) { } - HashNode(const NodeRef& src) : First(*src.pFirst), Second(*src.pSecond) { } - void operator = (const NodeRef& src) { First = *src.pFirst; Second = *src.pSecond; } - - template<class K> - bool operator == (const K& src) const { return (First == src); } - - template<class K> - static size_t CalcHash(const K& data) { return HashF()(data); } - inline size_t GetHash() const { return HashF()(First); } - - // Hash functors used with this node. A separate functor is used for alternative - // key lookup so that it does not need to access the '.First' element. - struct NodeHashF - { - template<class K> - size_t operator()(const K& data) const { return data.GetHash(); } - }; - struct NodeAltHashF - { - template<class K> - size_t operator()(const K& data) const { return HashNode<C,U,HashF>::CalcHash(data); } - }; -}; - - - -// **** Extra hashset_entry types to allow NodeRef construction. - -// The big difference between the below types and the ones used in hash_set is that -// these allow initializing the node with 'typename C::NodeRef& keyRef', which -// is critical to avoid temporary node allocation on stack when using placement new. - -// Compact hash table Entry type that re-computes hash keys during hash traversal. -// Good to use if the hash function is cheap or the hash value is already cached in C. -template<class C, class HashF> -class HashsetNodeEntry -{ -public: - // Internal chaining for collisions. - intptr_t NextInChain; - C Value; - - HashsetNodeEntry() - : NextInChain(-2) { } - HashsetNodeEntry(const HashsetNodeEntry& e) - : NextInChain(e.NextInChain), Value(e.Value) { } - HashsetNodeEntry(const C& key, intptr_t next) - : NextInChain(next), Value(key) { } - HashsetNodeEntry(const typename C::NodeRef& keyRef, intptr_t next) - : NextInChain(next), Value(keyRef) { } - - bool IsEmpty() const { return NextInChain == -2; } - bool IsEndOfChain() const { return NextInChain == -1; } - size_t GetCachedHash(size_t maskValue) const { return HashF()(Value) & maskValue; } - void SetCachedHash(size_t hashValue) { OVR_UNUSED(hashValue); } - - void Clear() - { - Value.~C(); // placement delete - NextInChain = -2; - } - // Free is only used from dtor of hash; Clear is used during regular operations: - // assignment, hash reallocations, value reassignments, so on. - void Free() { Clear(); } -}; - -// Hash table Entry type that caches the Entry hash value for nodes, so that it -// does not need to be re-computed during access. -template<class C, class HashF> -class HashsetCachedNodeEntry -{ -public: - // Internal chaining for collisions. - intptr_t NextInChain; - size_t HashValue; - C Value; - - HashsetCachedNodeEntry() - : NextInChain(-2) { } - HashsetCachedNodeEntry(const HashsetCachedNodeEntry& e) - : NextInChain(e.NextInChain), HashValue(e.HashValue), Value(e.Value) { } - HashsetCachedNodeEntry(const C& key, intptr_t next) - : NextInChain(next), Value(key) { } - HashsetCachedNodeEntry(const typename C::NodeRef& keyRef, intptr_t next) - : NextInChain(next), Value(keyRef) { } - - bool IsEmpty() const { return NextInChain == -2; } - bool IsEndOfChain() const { return NextInChain == -1; } - size_t GetCachedHash(size_t maskValue) const { OVR_UNUSED(maskValue); return HashValue; } - void SetCachedHash(size_t hashValue) { HashValue = hashValue; } - - void Clear() - { - Value.~C(); - NextInChain = -2; - } - // Free is only used from dtor of hash; Clear is used during regular operations: - // assignment, hash reallocations, value reassignments, so on. - void Free() { Clear(); } -}; - - -//----------------------------------------------------------------------------------- -template<class C, class U, - class HashF = FixedSizeHash<C>, - class Allocator = ContainerAllocator<C>, - class HashNode = OVR::HashNode<C,U,HashF>, - class Entry = HashsetCachedNodeEntry<HashNode, typename HashNode::NodeHashF>, - class Container = HashSet<HashNode, typename HashNode::NodeHashF, - typename HashNode::NodeAltHashF, Allocator, - Entry> > -class Hash -{ -public: - OVR_MEMORY_REDEFINE_NEW(Hash) - - // Types used for hash_set. - typedef U ValueType; - typedef Hash<C, U, HashF, Allocator, HashNode, Entry, Container> SelfType; - - // Actual hash table itself, implemented as hash_set. - Container mHash; - -public: - Hash() { } - Hash(int sizeHint) : mHash(sizeHint) { } - Hash(const SelfType& src) : mHash(src.mHash) { } - ~Hash() { } - - void operator = (const SelfType& src) { mHash = src.mHash; } - - // Remove all entries from the Hash table. - inline void Clear() { mHash.Clear(); } - // Returns true if the Hash is empty. - inline bool IsEmpty() const { return mHash.IsEmpty(); } - - // Access (set). - inline void Set(const C& key, const U& value) - { - typename HashNode::NodeRef e(key, value); - mHash.Set(e); - } - inline void Add(const C& key, const U& value) - { - typename HashNode::NodeRef e(key, value); - mHash.Add(e); - } - - // Removes an element by clearing its Entry. - inline void Remove(const C& key) - { - mHash.RemoveAlt(key); - } - template<class K> - inline void RemoveAlt(const K& key) - { - mHash.RemoveAlt(key); - } - - // Retrieve the value under the given key. - // - If there's no value under the key, then return false and leave *pvalue alone. - // - If there is a value, return true, and Set *Pvalue to the Entry's value. - // - If value == NULL, return true or false according to the presence of the key. - bool Get(const C& key, U* pvalue) const - { - const HashNode* p = mHash.GetAlt(key); - if (p) - { - if (pvalue) - *pvalue = p->Second; - return true; - } - return false; - } - - template<class K> - bool GetAlt(const K& key, U* pvalue) const - { - const HashNode* p = mHash.GetAlt(key); - if (p) - { - if (pvalue) - *pvalue = p->Second; - return true; - } - return false; - } - - // Retrieve the pointer to a value under the given key. - // - If there's no value under the key, then return NULL. - // - If there is a value, return the pointer. - inline U* Get(const C& key) - { - HashNode* p = mHash.GetAlt(key); - return p ? &p->Second : 0; - } - inline const U* Get(const C& key) const - { - const HashNode* p = mHash.GetAlt(key); - return p ? &p->Second : 0; - } - - template<class K> - inline U* GetAlt(const K& key) - { - HashNode* p = mHash.GetAlt(key); - return p ? &p->Second : 0; - } - template<class K> - inline const U* GetAlt(const K& key) const - { - const HashNode* p = mHash.GetAlt(key); - return p ? &p->Second : 0; - } - - // Sizing methods - delegate to Hash. - inline size_t GetSize() const { return mHash.GetSize(); } - inline int GetSizeI() const { return (int)GetSize(); } - inline void Resize(size_t n) { mHash.Resize(n); } - inline void SetCapacity(size_t newSize) { mHash.SetCapacity(newSize); } - - // Iterator API, like STL. - typedef typename Container::ConstIterator ConstIterator; - typedef typename Container::Iterator Iterator; - - inline Iterator Begin() { return mHash.Begin(); } - inline Iterator End() { return mHash.End(); } - inline ConstIterator Begin() const { return mHash.Begin(); } - inline ConstIterator End() const { return mHash.End(); } - - Iterator Find(const C& key) { return mHash.FindAlt(key); } - ConstIterator Find(const C& key) const { return mHash.FindAlt(key); } - - template<class K> - Iterator FindAlt(const K& key) { return mHash.FindAlt(key); } - template<class K> - ConstIterator FindAlt(const K& key) const { return mHash.FindAlt(key); } -}; - - - -// Hash with uncached hash code; declared for convenience. -template<class C, class U, class HashF = FixedSizeHash<C>, class Allocator = ContainerAllocator<C> > -class HashUncached - : public Hash<C, U, HashF, Allocator, HashNode<C,U,HashF>, - HashsetNodeEntry<HashNode<C,U,HashF>, typename HashNode<C,U,HashF>::NodeHashF> > -{ -public: - typedef HashUncached<C, U, HashF, Allocator> SelfType; - typedef Hash<C, U, HashF, Allocator, HashNode<C,U,HashF>, - HashsetNodeEntry<HashNode<C,U,HashF>, - typename HashNode<C,U,HashF>::NodeHashF> > BaseType; - - // Delegated constructors. - HashUncached() { } - HashUncached(int sizeHint) : BaseType(sizeHint) { } - HashUncached(const SelfType& src) : BaseType(src) { } - ~HashUncached() { } - void operator = (const SelfType& src) { BaseType::operator = (src); } -}; - - - -// And identity hash in which keys serve as hash value. Can be uncached, -// since hash computation is assumed cheap. -template<class C, class U, class Allocator = ContainerAllocator<C>, class HashF = IdentityHash<C> > -class HashIdentity - : public HashUncached<C, U, HashF, Allocator> -{ -public: - typedef HashIdentity<C, U, Allocator, HashF> SelfType; - typedef HashUncached<C, U, HashF, Allocator> BaseType; - - // Delegated constructors. - HashIdentity() { } - HashIdentity(int sizeHint) : BaseType(sizeHint) { } - HashIdentity(const SelfType& src) : BaseType(src) { } - ~HashIdentity() { } - void operator = (const SelfType& src) { BaseType::operator = (src); } -}; - - -} // OVR - - -#ifdef OVR_DEFINE_NEW -#define new OVR_DEFINE_NEW -#endif - -#endif diff --git a/LibOVR/Src/Kernel/OVR_KeyCodes.h b/LibOVR/Src/Kernel/OVR_KeyCodes.h deleted file mode 100644 index 8ecdc8b..0000000 --- a/LibOVR/Src/Kernel/OVR_KeyCodes.h +++ /dev/null @@ -1,251 +0,0 @@ -/************************************************************************************ - -PublicHeader: OVR_Kernel.h -Filename : OVR_KeyCodes.h -Content : Common keyboard constants -Created : September 19, 2012 - -Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); -you may not use the Oculus VR Rift SDK except in compliance with the License, -which is provided at the time of installation or download, or which -otherwise accompanies this software in either electronic or hard copy form. - -You may obtain a copy of the License at - -http://www.oculusvr.com/licenses/LICENSE-3.2 - -Unless required by applicable law or agreed to in writing, the Oculus VR SDK -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -************************************************************************************/ - -#ifndef OVR_KeyCodes_h -#define OVR_KeyCodes_h - -namespace OVR { - -//----------------------------------------------------------------------------------- -// ***** KeyCode - -// KeyCode enumeration defines platform-independent keyboard key constants. -// Note that Key_A through Key_Z are mapped to capital ascii constants. - -enum KeyCode -{ - // Key_None indicates that no key was specified. - Key_None = 0, - - // A through Z and numbers 0 through 9. - Key_A = 65, - Key_B, - Key_C, - Key_D, - Key_E, - Key_F, - Key_G, - Key_H, - Key_I, - Key_J, - Key_K, - Key_L, - Key_M, - Key_N, - Key_O, - Key_P, - Key_Q, - Key_R, - Key_S, - Key_T, - Key_U, - Key_V, - Key_W, - Key_X, - Key_Y, - Key_Z, - Key_Num0 = 48, - Key_Num1, - Key_Num2, - Key_Num3, - Key_Num4, - Key_Num5, - Key_Num6, - Key_Num7, - Key_Num8, - Key_Num9, - - // Numeric keypad. - Key_KP_0 = 0xa0, - Key_KP_1, - Key_KP_2, - Key_KP_3, - Key_KP_4, - Key_KP_5, - Key_KP_6, - Key_KP_7, - Key_KP_8, - Key_KP_9, - Key_KP_Multiply, - Key_KP_Add, - Key_KP_Enter, - Key_KP_Subtract, - Key_KP_Decimal, - Key_KP_Divide, - - // Function keys. - Key_F1 = 0xb0, - Key_F2, - Key_F3, - Key_F4, - Key_F5, - Key_F6, - Key_F7, - Key_F8, - Key_F9, - Key_F10, - Key_F11, - Key_F12, - Key_F13, - Key_F14, - Key_F15, - - // Other keys. - Key_Backspace = 8, - Key_Tab, - Key_Clear = 12, - Key_Return, - Key_Shift = 16, - Key_Control, - Key_Alt, - Key_Pause, - Key_CapsLock = 20, // Toggle - Key_Escape = 27, - Key_Space = 32, - Key_Quote = 39, - Key_PageUp = 0xc0, - Key_PageDown, - Key_End, - Key_Home, - Key_Left, - Key_Up, - Key_Right, - Key_Down, - Key_Insert, - Key_Delete, - Key_Help, - - Key_Comma = 44, - Key_Minus, - Key_Slash = 47, - Key_Period, - Key_NumLock = 144, // Toggle - Key_ScrollLock = 145, // Toggle - - Key_Semicolon = 59, - Key_Equal = 61, - Key_Backtick = 96, // ` and tilda~ when shifted (US keyboard) - Key_BracketLeft = 91, - Key_Backslash, - Key_BracketRight, - - Key_OEM_AX = 0xE1, // 'AX' key on Japanese AX keyboard - Key_OEM_102 = 0xE2, // "<>" or "\|" on RT 102-key keyboard. - Key_ICO_HELP = 0xE3, // Help key on ICO - Key_ICO_00 = 0xE4, // 00 key on ICO - - Key_Meta, - - // Total number of keys. - Key_CodeCount -}; - - -//----------------------------------------------------------------------------------- - -class KeyModifiers -{ -public: - enum - { - Key_ShiftPressed = 0x01, - Key_CtrlPressed = 0x02, - Key_AltPressed = 0x04, - Key_MetaPressed = 0x08, - Key_CapsToggled = 0x10, - Key_NumToggled = 0x20, - Key_ScrollToggled = 0x40, - - Initialized_Bit = 0x80, - Initialized_Mask = 0xFF - }; - unsigned char States; - - KeyModifiers() : States(0) { } - KeyModifiers(unsigned char st) : States((unsigned char)(st | Initialized_Bit)) { } - - void Reset() { States = 0; } - - bool IsShiftPressed() const { return (States & Key_ShiftPressed) != 0; } - bool IsCtrlPressed() const { return (States & Key_CtrlPressed) != 0; } - bool IsAltPressed() const { return (States & Key_AltPressed) != 0; } - bool IsMetaPressed() const { return (States & Key_MetaPressed) != 0; } - bool IsCapsToggled() const { return (States & Key_CapsToggled) != 0; } - bool IsNumToggled() const { return (States & Key_NumToggled) != 0; } - bool IsScrollToggled() const{ return (States & Key_ScrollToggled) != 0; } - - void SetShiftPressed(bool v = true) { (v) ? States |= Key_ShiftPressed : States &= ~Key_ShiftPressed; } - void SetCtrlPressed(bool v = true) { (v) ? States |= Key_CtrlPressed : States &= ~Key_CtrlPressed; } - void SetAltPressed(bool v = true) { (v) ? States |= Key_AltPressed : States &= ~Key_AltPressed; } - void SetMetaPressed(bool v = true) { (v) ? States |= Key_MetaPressed : States &= ~Key_MetaPressed; } - void SetCapsToggled(bool v = true) { (v) ? States |= Key_CapsToggled : States &= ~Key_CapsToggled; } - void SetNumToggled(bool v = true) { (v) ? States |= Key_NumToggled : States &= ~Key_NumToggled; } - void SetScrollToggled(bool v = true) { (v) ? States |= Key_ScrollToggled: States &= ~Key_ScrollToggled; } - - bool IsInitialized() const { return (States & Initialized_Mask) != 0; } -}; - - -//----------------------------------------------------------------------------------- - -/* -enum PadKeyCode -{ - Pad_None, // Indicates absence of key code. - Pad_Back, - Pad_Start, - Pad_A, - Pad_B, - Pad_X, - Pad_Y, - Pad_R1, // RightShoulder; - Pad_L1, // LeftShoulder; - Pad_R2, // RightTrigger; - Pad_L2, // LeftTrigger; - Pad_Up, - Pad_Down, - Pad_Right, - Pad_Left, - Pad_Plus, - Pad_Minus, - Pad_1, - Pad_2, - Pad_H, - Pad_C, - Pad_Z, - Pad_O, - Pad_T, - Pad_S, - Pad_Select, - Pad_Home, - Pad_RT, // RightThumb; - Pad_LT // LeftThumb; -}; -*/ - -} // OVR - -#endif diff --git a/LibOVR/Src/Kernel/OVR_List.h b/LibOVR/Src/Kernel/OVR_List.h deleted file mode 100644 index 7e90af3..0000000 --- a/LibOVR/Src/Kernel/OVR_List.h +++ /dev/null @@ -1,342 +0,0 @@ -/************************************************************************************ - -PublicHeader: OVR -Filename : OVR_List.h -Content : Template implementation for doubly-connected linked List -Created : September 19, 2012 -Notes : - -Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); -you may not use the Oculus VR Rift SDK except in compliance with the License, -which is provided at the time of installation or download, or which -otherwise accompanies this software in either electronic or hard copy form. - -You may obtain a copy of the License at - -http://www.oculusvr.com/licenses/LICENSE-3.2 - -Unless required by applicable law or agreed to in writing, the Oculus VR SDK -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -************************************************************************************/ - -#ifndef OVR_List_h -#define OVR_List_h - -#include "OVR_Types.h" - -namespace OVR { - -//----------------------------------------------------------------------------------- -// ***** ListNode -// -// Base class for the elements of the intrusive linked list. -// To store elements in the List do: -// -// struct MyData : ListNode<MyData> -// { -// . . . -// }; - -template<class T> -struct ListNode -{ - union { - T* pPrev; - void* pVoidPrev; - }; - union { - T* pNext; - void* pVoidNext; - }; - - ListNode() - { - pPrev = NULL; - pNext = NULL; - } - - void RemoveNode() - { - pPrev->pNext = pNext; - pNext->pPrev = pPrev; - } - - // Removes us from the list and inserts pnew there instead. - void ReplaceNodeWith(T* pnew) - { - pPrev->pNext = pnew; - pNext->pPrev = pnew; - pnew->pPrev = pPrev; - pnew->pNext = pNext; - } - - // Inserts the argument linked list node after us in the list. - void InsertNodeAfter(T* p) - { - p->pPrev = pNext->pPrev; // this - p->pNext = pNext; - pNext->pPrev = p; - pNext = p; - } - // Inserts the argument linked list node before us in the list. - void InsertNodeBefore(T* p) - { - p->pNext = pNext->pPrev; // this - p->pPrev = pPrev; - pPrev->pNext = p; - pPrev = p; - } - - void Alloc_MoveTo(ListNode<T>* pdest) - { - pdest->pNext = pNext; - pdest->pPrev = pPrev; - pPrev->pNext = (T*)pdest; - pNext->pPrev = (T*)pdest; - } -}; - - -//------------------------------------------------------------------------ -// ***** List -// -// Doubly linked intrusive list. -// The data type must be derived from ListNode. -// -// Adding: PushFront(), PushBack(). -// Removing: Remove() - the element must be in the list! -// Moving: BringToFront(), SendToBack() - the element must be in the list! -// -// Iterating: -// MyData* data = MyList.GetFirst(); -// while (!MyList.IsNull(data)) -// { -// . . . -// data = MyList.GetNext(data); -// } -// -// Removing: -// MyData* data = MyList.GetFirst(); -// while (!MyList.IsNull(data)) -// { -// MyData* next = MyList.GetNext(data); -// if (ToBeRemoved(data)) -// MyList.Remove(data); -// data = next; -// } -// - -// List<> represents a doubly-linked list of T, where each T must derive -// from ListNode<B>. B specifies the base class that was directly -// derived from ListNode, and is only necessary if there is an intermediate -// inheritance chain. - -template<class T, class B = T> class List -{ -public: - typedef T ValueType; - - List() - { - Root.pNext = Root.pPrev = (ValueType*)&Root; - } - - void Clear() - { - Root.pNext = Root.pPrev = (ValueType*)&Root; - } - - const ValueType* GetFirst() const { return (const ValueType*)Root.pNext; } - const ValueType* GetLast () const { return (const ValueType*)Root.pPrev; } - ValueType* GetFirst() { return (ValueType*)Root.pNext; } - ValueType* GetLast () { return (ValueType*)Root.pPrev; } - - // Determine if list is empty (i.e.) points to itself. - // Go through void* access to avoid issues with strict-aliasing optimizing out the - // access after RemoveNode(), etc. - bool IsEmpty() const { return Root.pVoidNext == (const T*)(const B*)&Root; } - bool IsFirst(const ValueType* p) const { return p == Root.pNext; } - bool IsLast (const ValueType* p) const { return p == Root.pPrev; } - bool IsNull (const ValueType* p) const { return p == (const T*)(const B*)&Root; } - - inline static const ValueType* GetPrev(const ValueType* p) { return (const ValueType*)p->pPrev; } - inline static const ValueType* GetNext(const ValueType* p) { return (const ValueType*)p->pNext; } - inline static ValueType* GetPrev( ValueType* p) { return (ValueType*)p->pPrev; } - inline static ValueType* GetNext( ValueType* p) { return (ValueType*)p->pNext; } - - void PushFront(ValueType* p) - { - p->pNext = Root.pNext; - p->pPrev = (ValueType*)&Root; - Root.pNext->pPrev = p; - Root.pNext = p; - } - - void PushBack(ValueType* p) - { - p->pPrev = Root.pPrev; - p->pNext = (ValueType*)&Root; - Root.pPrev->pNext = p; - Root.pPrev = p; - } - - static void Remove(ValueType* p) - { - p->pPrev->pNext = p->pNext; - p->pNext->pPrev = p->pPrev; - } - - void BringToFront(ValueType* p) - { - Remove(p); - PushFront(p); - } - - void SendToBack(ValueType* p) - { - Remove(p); - PushBack(p); - } - - // Appends the contents of the argument list to the front of this list; - // items are removed from the argument list. - void PushListToFront(List<T>& src) - { - if (!src.IsEmpty()) - { - ValueType* pfirst = src.GetFirst(); - ValueType* plast = src.GetLast(); - src.Clear(); - plast->pNext = Root.pNext; - pfirst->pPrev = (ValueType*)&Root; - Root.pNext->pPrev = plast; - Root.pNext = pfirst; - } - } - - void PushListToBack(List<T>& src) - { - if (!src.IsEmpty()) - { - ValueType* pfirst = src.GetFirst(); - ValueType* plast = src.GetLast(); - src.Clear(); - plast->pNext = (ValueType*)&Root; - pfirst->pPrev = Root.pPrev; - Root.pPrev->pNext = pfirst; - Root.pPrev = plast; - } - } - - // Removes all source list items after (and including) the 'pfirst' node from the - // source list and adds them to out list. - void PushFollowingListItemsToFront(List<T>& src, ValueType *pfirst) - { - if (pfirst != &src.Root) - { - ValueType *plast = src.Root.pPrev; - - // Remove list remainder from source. - pfirst->pPrev->pNext = (ValueType*)&src.Root; - src.Root.pPrev = pfirst->pPrev; - // Add the rest of the items to list. - plast->pNext = Root.pNext; - pfirst->pPrev = (ValueType*)&Root; - Root.pNext->pPrev = plast; - Root.pNext = pfirst; - } - } - - // Removes all source list items up to but NOT including the 'pend' node from the - // source list and adds them to out list. - void PushPrecedingListItemsToFront(List<T>& src, ValueType *ptail) - { - if (src.GetFirst() != ptail) - { - ValueType *pfirst = src.Root.pNext; - ValueType *plast = ptail->pPrev; - - // Remove list remainder from source. - ptail->pPrev = (ValueType*)&src.Root; - src.Root.pNext = ptail; - - // Add the rest of the items to list. - plast->pNext = Root.pNext; - pfirst->pPrev = (ValueType*)&Root; - Root.pNext->pPrev = plast; - Root.pNext = pfirst; - } - } - - - // Removes a range of source list items starting at 'pfirst' and up to, but not including 'pend', - // and adds them to out list. Note that source items MUST already be in the list. - void PushListItemsToFront(ValueType *pfirst, ValueType *pend) - { - if (pfirst != pend) - { - ValueType *plast = pend->pPrev; - - // Remove list remainder from source. - pfirst->pPrev->pNext = pend; - pend->pPrev = pfirst->pPrev; - // Add the rest of the items to list. - plast->pNext = Root.pNext; - pfirst->pPrev = (ValueType*)&Root; - Root.pNext->pPrev = plast; - Root.pNext = pfirst; - } - } - - - void Alloc_MoveTo(List<T>* pdest) - { - if (IsEmpty()) - pdest->Clear(); - else - { - pdest->Root.pNext = Root.pNext; - pdest->Root.pPrev = Root.pPrev; - - Root.pNext->pPrev = (ValueType*)&pdest->Root; - Root.pPrev->pNext = (ValueType*)&pdest->Root; - } - } - - -private: - // Copying is prohibited - List(const List<T>&); - const List<T>& operator = (const List<T>&); - - ListNode<B> Root; -}; - - -//------------------------------------------------------------------------ -// ***** FreeListElements -// -// Remove all elements in the list and free them in the allocator - -template<class List, class Allocator> -void FreeListElements(List& list, Allocator& allocator) -{ - typename List::ValueType* self = list.GetFirst(); - while(!list.IsNull(self)) - { - typename List::ValueType* next = list.GetNext(self); - allocator.Free(self); - self = next; - } - list.Clear(); -} - -} // OVR - -#endif diff --git a/LibOVR/Src/Kernel/OVR_Lockless.cpp b/LibOVR/Src/Kernel/OVR_Lockless.cpp deleted file mode 100644 index 6a5ec6b..0000000 --- a/LibOVR/Src/Kernel/OVR_Lockless.cpp +++ /dev/null @@ -1,225 +0,0 @@ -/************************************************************************************ - -Filename : OVR_Lockless.cpp -Content : Test logic for lock-less classes -Created : December 27, 2013 -Authors : Michael Antonov - -Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); -you may not use the Oculus VR Rift SDK except in compliance with the License, -which is provided at the time of installation or download, or which -otherwise accompanies this software in either electronic or hard copy form. - -You may obtain a copy of the License at - -http://www.oculusvr.com/licenses/LICENSE-3.2 - -Unless required by applicable law or agreed to in writing, the Oculus VR SDK -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -*************************************************************************************/ - -#include "OVR_Lockless.h" - -#ifdef OVR_LOCKLESS_TEST - -#include "OVR_Threads.h" -#include "OVR_Timer.h" -#include "OVR_Log.h" - -namespace OVR { namespace LocklessTest { - - -const int TestIterations = 10000000; - -// Use volatile dummies to force compiler to do spinning. -volatile int Dummy1; -int Unused1[32]; -volatile int Dummy2; -int Unused2[32]; -volatile int Dummy3; -int Unused3[32]; - - -// Data block out of 20 consecutive integers, should be internally consistent. -struct TestData -{ - enum { ItemCount = 20 }; - - int Data[ItemCount]; - - - void Set(int val) - { - for (int i=0; i<ItemCount; i++) - { - Data[i] = val*100 + i; - } - } - - int ReadAndCheckConsistency(int prevValue) const - { - int val = Data[0]; - - for (int i=1; i<ItemCount; i++) - { - - if (Data[i] != (val + i)) - { - // Only complain once per same-value entry - if (prevValue != val / 100) - { - LogText("LocklessTest Fail - corruption at %d inside block %d\n", - i, val/100); - // OVR_ASSERT(Data[i] == val + i); - } - break; - } - } - - return val / 100; - } -}; - - - -volatile bool FirstItemWritten = false; -LocklessUpdater<TestData, TestData> TestDataUpdater; - -// Use this lock to verify that testing algorithm is otherwise correct... -Lock TestLock; - - -//------------------------------------------------------------------------------------- - -// Consumer thread reads values from TestDataUpdater and -// ensures that each one is internally consistent. - -class Consumer : public Thread -{ - virtual int Run() - { - LogText("LocklessTest::Consumer::Run started.\n"); - - while (!FirstItemWritten) - { - // spin until producer wrote first value... - } - - TestData d; - int oldValue = 0; - int newValue; - - do - { - { - //Lock::Locker scope(&TestLock); - d = TestDataUpdater.GetState(); - } - - newValue = d.ReadAndCheckConsistency(oldValue); - - // Values should increase or stay the same! - if (newValue < oldValue) - { - LogText("LocklessTest Fail - %d after %d; delta = %d\n", - newValue, oldValue, newValue - oldValue); - // OVR_ASSERT(0); - } - - - if (oldValue != newValue) - { - oldValue = newValue; - - if (oldValue % (TestIterations/30) == 0) - { - LogText("LocklessTest::Consumer - %5.2f%% done\n", - 100.0f * (float)oldValue/(float)TestIterations); - } - } - - // Spin a while - for (int j = 0; j< 300; j++) - { - Dummy3 = j; - } - - - } while (oldValue < (TestIterations * 99 / 100)); - - LogText("LocklessTest::Consumer::Run exiting.\n"); - return 0; - } - -}; - - -//------------------------------------------------------------------------------------- - -class Producer : public Thread -{ - - virtual int Run() - { - LogText("LocklessTest::Producer::Run started.\n"); - - for (int testVal = 0; testVal < TestIterations; testVal++) - { - TestData d; - d.Set(testVal); - - { - //Lock::Locker scope(&TestLock); - TestDataUpdater.SetState(d); - } - - FirstItemWritten = true; - - // Spin a bit - for(int j = 0; j < 1000; j++) - { - Dummy2 = j; - } - - if (testVal % (TestIterations/30) == 0) - { - LogText("LocklessTest::Producer - %5.2f%% done\n", - 100.0f * (float)testVal/(float)TestIterations); - } - } - - LogText("LocklessTest::Producer::Run exiting.\n"); - return 0; - } -}; - - -} // namespace LocklessTest - - - -void StartLocklessTest() -{ - // These threads will release themselves once done - Ptr<LocklessTest::Producer> producerThread = *new LocklessTest::Producer; - Ptr<LocklessTest::Consumer> consumerThread = *new LocklessTest::Consumer; - - producerThread->Start(); - consumerThread->Start(); - - while (!producerThread->IsFinished() && consumerThread->IsFinished()) - { - Thread::MSleep(500); - } -} - - -} // namespace OVR - -#endif // OVR_LOCKLESS_TEST diff --git a/LibOVR/Src/Kernel/OVR_Lockless.h b/LibOVR/Src/Kernel/OVR_Lockless.h deleted file mode 100644 index 4d5b87e..0000000 --- a/LibOVR/Src/Kernel/OVR_Lockless.h +++ /dev/null @@ -1,117 +0,0 @@ -/************************************************************************************ - -PublicHeader: OVR_Kernel.h -Filename : OVR_Lockless.h -Content : Lock-less classes for producer/consumer communication -Created : November 9, 2013 -Authors : John Carmack - -Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); -you may not use the Oculus VR Rift SDK except in compliance with the License, -which is provided at the time of installation or download, or which -otherwise accompanies this software in either electronic or hard copy form. - -You may obtain a copy of the License at - -http://www.oculusvr.com/licenses/LICENSE-3.2 - -Unless required by applicable law or agreed to in writing, the Oculus VR SDK -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -*************************************************************************************/ - -#ifndef OVR_Lockless_h -#define OVR_Lockless_h - -#include "OVR_Atomic.h" - -// Define this to compile-in Lockless test logic -//#define OVR_LOCKLESS_TEST - -namespace OVR { - - -// ***** LocklessUpdater - -// For single producer cases where you only care about the most recent update, not -// necessarily getting every one that happens (vsync timing, SensorFusion updates). -// -// This is multiple consumer safe, but is currently only used with a single consumer. -// -// The SlotType can be the same as T, but should probably be a larger fixed size. -// This allows for forward compatibility when the updater is shared between processes. - -// FIXME: ExchangeAdd_Sync() should be replaced with a portable read-only primitive, -// so that the lockless pose state can be read-only on remote processes and to reduce -// false sharing between processes and improve performance. - -template<class T, class SlotType> -class LocklessUpdater -{ -public: - LocklessUpdater() : UpdateBegin( 0 ), UpdateEnd( 0 ) - { - OVR_COMPILER_ASSERT(sizeof(T) <= sizeof(SlotType)); - } - - T GetState() const - { - // Copy the state out, then retry with the alternate slot - // if we determine that our copy may have been partially - // stepped on by a new update. - T state; - int begin, end, final; - - for(;;) - { - // We are adding 0, only using these as atomic memory barriers, so it - // is ok to cast off the const, allowing GetState() to remain const. - end = UpdateEnd.Load_Acquire(); - state = Slots[ end & 1 ]; - begin = UpdateBegin.Load_Acquire(); - if ( begin == end ) { - break; - } - - // The producer is potentially blocked while only having partially - // written the update, so copy out the other slot. - state = Slots[ (begin & 1) ^ 1 ]; - final = UpdateBegin.Load_Acquire(); - if ( final == begin ) { - break; - } - - // The producer completed the last update and started a new one before - // we got it copied out, so try fetching the current buffer again. - } - return state; - } - - void SetState( const T& state ) - { - const int slot = UpdateBegin.ExchangeAdd_Sync(1) & 1; - // Write to (slot ^ 1) because ExchangeAdd returns 'previous' value before add. - Slots[slot ^ 1] = state; - UpdateEnd.ExchangeAdd_Sync(1); - } - - AtomicInt<int> UpdateBegin; - AtomicInt<int> UpdateEnd; - SlotType Slots[2]; -}; - - -#ifdef OVR_LOCKLESS_TEST -void StartLocklessTest(); -#endif - - -} // namespace OVR - -#endif // OVR_Lockless_h - diff --git a/LibOVR/Src/Kernel/OVR_Log.cpp b/LibOVR/Src/Kernel/OVR_Log.cpp deleted file mode 100644 index 2631879..0000000 --- a/LibOVR/Src/Kernel/OVR_Log.cpp +++ /dev/null @@ -1,432 +0,0 @@ -/************************************************************************************ - -Filename : OVR_Log.cpp -Content : Logging support -Created : September 19, 2012 -Notes : - -Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); -you may not use the Oculus VR Rift SDK except in compliance with the License, -which is provided at the time of installation or download, or which -otherwise accompanies this software in either electronic or hard copy form. - -You may obtain a copy of the License at - -http://www.oculusvr.com/licenses/LICENSE-3.2 - -Unless required by applicable law or agreed to in writing, the Oculus VR SDK -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -************************************************************************************/ - -#include "OVR_Log.h" -#include "OVR_Std.h" -#include <stdarg.h> -#include <stdio.h> -#include <time.h> -#include "../Kernel/OVR_System.h" -#include "../Kernel/OVR_DebugHelp.h" -#include "../Util/Util_SystemGUI.h" - -#if defined(OVR_OS_MS) && !defined(OVR_OS_MS_MOBILE) -#define WIN32_LEAN_AND_MEAN -#include <windows.h> -#elif defined(OVR_OS_ANDROID) -#include <android/log.h> -#elif defined(OVR_OS_LINUX) || defined(OVR_OS_MAC) || defined(OVR_OS_UNIX) -#include <syslog.h> -#endif - - -class LogSubject : public OVR::SystemSingletonBase<LogSubject> -{ - static bool isShuttingDown; - -public: - - LogSubject(){ - isShuttingDown = false; - // Must be at end of function - PushDestroyCallbacks(); - } - - virtual ~LogSubject(){} // Required because we use delete this below. - - virtual void OnThreadDestroy() - { - isShuttingDown = true; - } - - virtual void OnSystemDestroy() - { - delete this; - } - - static bool IsValid() { - return isShuttingDown == false; - } - - OVR::Lock logSubjectLock; - OVR::ObserverScope<OVR::Log::LogHandler> logSubject; -}; - -bool LogSubject::isShuttingDown; - -OVR_DEFINE_SINGLETON(LogSubject); - -namespace OVR { - - // Global Log pointer. - Log* volatile OVR_GlobalLog = 0; - -//----------------------------------------------------------------------------------- -// ***** Log Implementation - -Log::Log(unsigned logMask) : - LoggingMask(logMask) -{ -#ifdef OVR_OS_WIN32 - hEventSource = RegisterEventSourceA(NULL, "OculusVR"); - OVR_ASSERT(hEventSource != NULL); -#endif -} - -Log::~Log() -{ -#ifdef OVR_OS_WIN32 - if (hEventSource) - { - DeregisterEventSource(hEventSource); - } -#endif - - // Clear out global log - if (this == OVR_GlobalLog) - { - // TBD: perhaps we should ASSERT if this happens before system shutdown? - OVR_GlobalLog = 0; - } -} -void Log::AddLogObserver(ObserverScope<LogHandler> *logObserver) -{ - if (OVR::System::IsInitialized() && LogSubject::GetInstance()->IsValid()) - { - Lock::Locker locker(&LogSubject::GetInstance()->logSubjectLock); - logObserver->GetPtr()->Observe(LogSubject::GetInstance()->logSubject); - } -} -void Log::LogMessageVargInt(LogMessageType messageType, const char* fmt, va_list argList) -{ - if (OVR::System::IsInitialized() && LogSubject::GetInstance()->IsValid()) - { - // Invoke subject - char buffer[MaxLogBufferMessageSize]; - char* pBuffer = buffer; - char* pAllocated = NULL; - - #if !defined(OVR_CC_MSVC) // Non-Microsoft compilers require you to save a copy of the va_list. - va_list argListSaved; - va_copy(argListSaved, argList); - #endif - - int result = FormatLog(pBuffer, MaxLogBufferMessageSize, Log_Text, fmt, argList); - - if(result >= MaxLogBufferMessageSize) // If there was insufficient capacity... - { - pAllocated = (char*)OVR_ALLOC(result + 1); // We assume C++ exceptions are disabled. FormatLog will handle the case that pAllocated is NULL. - pBuffer = pAllocated; - - #if !defined(OVR_CC_MSVC) - va_end(argList); // The caller owns argList and will call va_end on it. - va_copy(argList, argListSaved); - #endif - - FormatLog(pBuffer, (size_t)result + 1, Log_Text, fmt, argList); - } - - Lock::Locker locker(&LogSubject::GetInstance()->logSubjectLock); - LogSubject::GetInstance()->logSubject.GetPtr()->Call(pBuffer, messageType); - - delete[] pAllocated; - } -} - -void Log::LogMessageVarg(LogMessageType messageType, const char* fmt, va_list argList) -{ - if ((messageType & LoggingMask) == 0) - return; -#ifndef OVR_BUILD_DEBUG - if (IsDebugMessage(messageType)) - return; -#endif - - char buffer[MaxLogBufferMessageSize]; - char* pBuffer = buffer; - char* pAllocated = NULL; - - #if !defined(OVR_CC_MSVC) // Non-Microsoft compilers require you to save a copy of the va_list. - va_list argListSaved; - va_copy(argListSaved, argList); - #endif - - int result = FormatLog(pBuffer, MaxLogBufferMessageSize, messageType, fmt, argList); - - if(result >= MaxLogBufferMessageSize) // If there was insufficient capacity... - { - pAllocated = (char*)OVR_ALLOC(result + 1); // We assume C++ exceptions are disabled. FormatLog will handle the case that pAllocated is NULL. - pBuffer = pAllocated; - - #if !defined(OVR_CC_MSVC) - va_end(argList); // The caller owns argList and will call va_end on it. - va_copy(argList, argListSaved); - #endif - - FormatLog(pBuffer, (size_t)result + 1, messageType, fmt, argList); - } - - DefaultLogOutput(pBuffer, messageType, result); - delete[] pAllocated; -} - -void OVR::Log::LogMessage(LogMessageType messageType, const char* pfmt, ...) -{ - va_list argList; - va_start(argList, pfmt); - LogMessageVarg(messageType, pfmt, argList); - va_end(argList); -} - - -// Return behavior is the same as ISO C vsnprintf: returns the required strlen of buffer (which will -// be >= bufferSize if bufferSize is insufficient) or returns a negative value because the input was bad. -int Log::FormatLog(char* buffer, size_t bufferSize, LogMessageType messageType, - const char* fmt, va_list argList) -{ - OVR_ASSERT(buffer && (bufferSize >= 10)); // Need to be able to at least print "Assert: \n" to it. - if(!buffer || (bufferSize < 10)) - return -1; - - int addNewline = 1; - int prefixLength = 0; - - switch(messageType) - { - case Log_Error: OVR_strcpy(buffer, bufferSize, "Error: "); prefixLength = 7; break; - case Log_Debug: OVR_strcpy(buffer, bufferSize, "Debug: "); prefixLength = 7; break; - case Log_Assert: OVR_strcpy(buffer, bufferSize, "Assert: "); prefixLength = 8; break; - case Log_Text: buffer[0] = 0; addNewline = 0; break; - case Log_DebugText: buffer[0] = 0; addNewline = 0; break; - default: buffer[0] = 0; addNewline = 0; break; - } - - char* buffer2 = buffer + prefixLength; - size_t size2 = bufferSize - (size_t)prefixLength; - int messageLength = OVR_vsnprintf(buffer2, size2, fmt, argList); - - if (addNewline) - { - if (messageLength < 0) // If there was a format error... - { - // To consider: append <format error> to the buffer here. - buffer2[0] = '\n'; // We are guaranteed to have capacity for this. - buffer2[1] = '\0'; - } - else - { - // If the printed string used all of the capacity or required more than the capacity, - // Chop the output by one character so we can append the \n safely. - int messageEnd = (messageLength >= (int)(size2 - 1)) ? (int)(size2 - 2) : messageLength; - buffer2[messageEnd + 0] = '\n'; - buffer2[messageEnd + 1] = '\0'; - } - } - - if (messageLength >= 0) // If the format was OK... - return prefixLength + messageLength + addNewline; // Return the required strlen of buffer. - - return messageLength; // Else we cannot know what the required strlen is and return the error to the caller. -} - -void Log::DefaultLogOutput(const char* formattedText, LogMessageType messageType, int bufferSize) -{ - bool debug = IsDebugMessage(messageType); - OVR_UNUSED(bufferSize); - -#if defined(OVR_OS_WIN32) - // Under Win32, output regular messages to console if it exists; debug window otherwise. - static DWORD dummyMode; - static bool hasConsole = (GetStdHandle(STD_OUTPUT_HANDLE) != INVALID_HANDLE_VALUE) && - (GetConsoleMode(GetStdHandle(STD_OUTPUT_HANDLE), &dummyMode)); - - if (!hasConsole || debug) - { - ::OutputDebugStringA(formattedText); - } - - fputs(formattedText, stdout); - -#elif defined(OVR_OS_MS) // Any other Microsoft OSs - - ::OutputDebugStringA(formattedText); - -#elif defined(OVR_OS_ANDROID) - // To do: use bufferSize to deal with the case that Android has a limited output length. - __android_log_write(ANDROID_LOG_INFO, "OVR", formattedText); - -#else - fputs(formattedText, stdout); - -#endif - - if (messageType == Log_Error) - { -#if defined(OVR_OS_WIN32) - if (!ReportEventA(hEventSource, EVENTLOG_ERROR_TYPE, 0, 0, NULL, 1, 0, &formattedText, NULL)) - { - OVR_ASSERT(false); - } -#elif defined(OVR_OS_MS) // Any other Microsoft OSs - // TBD -#elif defined(OVR_OS_ANDROID) - // TBD -#elif defined(OVR_OS_MAC) || defined(OVR_OS_LINUX) - syslog(LOG_ERR, "%s", formattedText); -#else - // TBD -#endif - } - - // Just in case. - OVR_UNUSED2(formattedText, debug); -} - - -//static -void Log::SetGlobalLog(Log *log) -{ - OVR_GlobalLog = log; -} -//static -Log* Log::GetGlobalLog() -{ -// No global log by default? -// if (!OVR_GlobalLog) -// OVR_GlobalLog = GetDefaultLog(); - return OVR_GlobalLog; -} - -//static -Log* Log::GetDefaultLog() -{ - // Create default log pointer statically so that it can be used - // even during startup. - static Log defaultLog; - return &defaultLog; -} - - -//----------------------------------------------------------------------------------- -// ***** Global Logging functions - -#if !defined(OVR_CC_MSVC) -// The reason for va_copy is because you can't use va_start twice on Linux -#define OVR_LOG_FUNCTION_IMPL(Name) \ - void Log##Name(const char* fmt, ...) \ - { \ - if (OVR_GlobalLog) \ - { \ - va_list argList1; \ - va_start(argList1, fmt); \ - va_list argList2; \ - va_copy(argList2, argList1); \ - OVR_GlobalLog->LogMessageVargInt(Log_##Name, fmt, argList2); \ - va_end(argList2); \ - OVR_GlobalLog->LogMessageVarg(Log_##Name, fmt, argList1); \ - va_end(argList1); \ - } \ - } -#else -#define OVR_LOG_FUNCTION_IMPL(Name) \ - void Log##Name(const char* fmt, ...) \ - { \ - if (OVR_GlobalLog) \ - { \ - va_list argList1; \ - va_start(argList1, fmt); \ - OVR_GlobalLog->LogMessageVargInt(Log_##Name, fmt, argList1); \ - OVR_GlobalLog->LogMessageVarg(Log_##Name, fmt, argList1); \ - va_end(argList1); \ - } \ - } -#endif // #if !defined(OVR_OS_WIN32) - -OVR_LOG_FUNCTION_IMPL(Text) -OVR_LOG_FUNCTION_IMPL(Error) - -#ifdef OVR_BUILD_DEBUG -OVR_LOG_FUNCTION_IMPL(DebugText) -OVR_LOG_FUNCTION_IMPL(Debug) -OVR_LOG_FUNCTION_IMPL(Assert) -#endif - - - -// Assertion handler support -// To consider: Move this to an OVR_Types.cpp or OVR_Assert.cpp source file. - -static OVRAssertionHandler sOVRAssertionHandler = OVR::DefaultAssertionHandler; -static intptr_t sOVRAssertionHandlerUserParameter = 0; - -OVRAssertionHandler GetAssertionHandler(intptr_t* userParameter) -{ - if(userParameter) - *userParameter = sOVRAssertionHandlerUserParameter; - return sOVRAssertionHandler; -} - -void SetAssertionHandler(OVRAssertionHandler assertionHandler, intptr_t userParameter) -{ - sOVRAssertionHandler = assertionHandler; - sOVRAssertionHandlerUserParameter = userParameter; -} - -intptr_t DefaultAssertionHandler(intptr_t /*userParameter*/, const char* title, const char* message) -{ - if(OVRIsDebuggerPresent()) - { - OVR_DEBUG_BREAK; - } - else - { - #if defined(OVR_BUILD_DEBUG) - // Print a stack trace of all threads. - OVR::String s; - OVR::String threadListOutput; - static OVR::SymbolLookup symbolLookup; - - s = "Failure: "; - s += message; - - if(symbolLookup.Initialize() && symbolLookup.ReportThreadCallstack(threadListOutput, 4)) // This '4' is there to skip our internal handling and retrieve starting at the assertion location (our caller) only. - { - s += "\r\n\r\n"; - s += threadListOutput; - } - - OVR::Util::DisplayMessageBox(title, s.ToCStr()); - #else - OVR::Util::DisplayMessageBox(title, message); - #endif - } - - return 0; -} - - - -} // OVR diff --git a/LibOVR/Src/Kernel/OVR_Log.h b/LibOVR/Src/Kernel/OVR_Log.h deleted file mode 100644 index 5982395..0000000 --- a/LibOVR/Src/Kernel/OVR_Log.h +++ /dev/null @@ -1,227 +0,0 @@ -/************************************************************************************ - -PublicHeader: OVR -Filename : OVR_Log.h -Content : Logging support -Created : September 19, 2012 -Notes : - -Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); -you may not use the Oculus VR Rift SDK except in compliance with the License, -which is provided at the time of installation or download, or which -otherwise accompanies this software in either electronic or hard copy form. - -You may obtain a copy of the License at - -http://www.oculusvr.com/licenses/LICENSE-3.2 - -Unless required by applicable law or agreed to in writing, the Oculus VR SDK -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -************************************************************************************/ - -#ifndef OVR_Log_h -#define OVR_Log_h - -#include "OVR_Types.h" -#include "../Kernel/OVR_Delegates.h" -#include "../Kernel//OVR_Observer.h" -#include <stdarg.h> - -namespace OVR { - -//----------------------------------------------------------------------------------- -// ***** Logging Constants - -// LogMaskConstants defined bit mask constants that describe what log messages -// should be displayed. -enum LogMaskConstants -{ - LogMask_Regular = 0x100, - LogMask_Debug = 0x200, - LogMask_None = 0, - LogMask_All = LogMask_Regular|LogMask_Debug -}; - - -// LogMessageType describes the type of the log message, controls when it is -// displayed and what prefix/suffix is given to it. Messages are subdivided into -// regular and debug logging types. Debug logging is only generated in debug builds. -// -// Log_Text - General output text displayed without prefix or new-line. -// Used in OVR libraries for general log flow messages -// such as "Device Initialized". -// -// Log_Error - Error message output with "Error: %s\n", intended for -// application/sample-level use only, in cases where an expected -// operation failed. OVR libraries should not use this internally, -// reporting status codes instead. -// -// Log_DebugText - Message without prefix or new lines; output in Debug build only. -// -// Log_Debug - Debug-build only message, formatted with "Debug: %s\n". -// Intended to comment on incorrect API usage that doesn't lead -// to crashes but can be avoided with proper use. -// There is no Debug Error on purpose, since real errors should -// be handled by API user. -// -// Log_Assert - Debug-build only message, formatted with "Assert: %s\n". -// Intended for severe unrecoverable conditions in library -// source code. Generated though OVR_ASSERT_MSG(c, "Text"). - -enum LogMessageType -{ - // General Logging - Log_Text = LogMask_Regular | 0, - Log_Error = LogMask_Regular | 1, // "Error: %s\n". - - // Debug-only messages (not generated in release build) - Log_DebugText = LogMask_Debug | 0, - Log_Debug = LogMask_Debug | 1, // "Debug: %s\n". - Log_Assert = LogMask_Debug | 2, // "Assert: %s\n". -}; - - -// LOG_VAARG_ATTRIBUTE macro, enforces printf-style fromatting for message types -#ifdef __GNUC__ -# define OVR_LOG_VAARG_ATTRIBUTE(a,b) __attribute__((format (printf, a, b))) -#else -# define OVR_LOG_VAARG_ATTRIBUTE(a,b) -#endif - -//----------------------------------------------------------------------------------- -// ***** Log - -// Log defines a base class interface that can be implemented to catch both -// debug and runtime messages. -// Debug logging can be overridden by calling Log::SetGlobalLog. - -class Log -{ - friend class System; - -#ifdef OVR_OS_WIN32 - void* hEventSource; -#endif - -public: - Log(unsigned logMask = LogMask_Debug); - virtual ~Log(); - - typedef Delegate2<void, const char*, LogMessageType> LogHandler; - - // The following is deprecated, as there is no longer a max log buffer message size. - enum { MaxLogBufferMessageSize = 4096 }; - - unsigned GetLoggingMask() const { return LoggingMask; } - void SetLoggingMask(unsigned logMask) { LoggingMask = logMask; } - - // Internal - // Invokes observers, then calls LogMessageVarg() - static void LogMessageVargInt(LogMessageType messageType, const char* fmt, va_list argList); - - // This virtual function receives all the messages, - // developers should override this function in order to do custom logging - virtual void LogMessageVarg(LogMessageType messageType, const char* fmt, va_list argList); - - static void AddLogObserver(ObserverScope<LogHandler> *logObserver); - - // Call the logging function with specific message type, with no type filtering. - void LogMessage(LogMessageType messageType, - const char* fmt, ...) OVR_LOG_VAARG_ATTRIBUTE(3,4); - - - // Helper used by LogMessageVarg to format the log message, writing the resulting - // string into buffer. It formats text based on fmt and appends prefix/new line - // based on LogMessageType. Return behavior is the same as ISO C vsnprintf: returns the - // required strlen of buffer (which will be >= bufferSize if bufferSize is insufficient) - // or returns a negative value because the input was bad. - static int FormatLog(char* buffer, size_t bufferSize, LogMessageType messageType, - const char* fmt, va_list argList); - - // Default log output implementation used by by LogMessageVarg. - // Debug flag may be used to re-direct output on some platforms, but doesn't - // necessarily disable it in release builds; that is the job of the called. - void DefaultLogOutput(const char* textBuffer, LogMessageType messageType, int bufferSize = -1); - - // Determines if the specified message type is for debugging only. - static bool IsDebugMessage(LogMessageType messageType) - { - return (messageType & LogMask_Debug) != 0; - } - - // *** Global APIs - - // Global Log registration APIs. - // - Global log is used for OVR_DEBUG messages. Set global log to null (0) - // to disable all logging. - static void SetGlobalLog(Log *log); - static Log* GetGlobalLog(); - - // Returns default log singleton instance. - static Log* GetDefaultLog(); - - // Applies logMask to the default log and returns a pointer to it. - // By default, only Debug logging is enabled, so to avoid SDK generating console - // messages in user app (those are always disabled in release build, - // even if the flag is set). This function is useful in System constructor. - static Log* ConfigureDefaultLog(unsigned logMask = LogMask_Debug) - { - Log* log = GetDefaultLog(); - log->SetLoggingMask(logMask); - return log; - } - -private: - // Logging mask described by LogMaskConstants. - unsigned LoggingMask; -}; - - -//----------------------------------------------------------------------------------- -// ***** Global Logging Functions and Debug Macros - -// These functions will output text to global log with semantics described by -// their LogMessageType. -void LogText(const char* fmt, ...) OVR_LOG_VAARG_ATTRIBUTE(1,2); -void LogError(const char* fmt, ...) OVR_LOG_VAARG_ATTRIBUTE(1,2); - -#ifdef OVR_BUILD_DEBUG - - // Debug build only logging. - void LogDebugText(const char* fmt, ...) OVR_LOG_VAARG_ATTRIBUTE(1,2); - void LogDebug(const char* fmt, ...) OVR_LOG_VAARG_ATTRIBUTE(1,2); - void LogAssert(const char* fmt, ...) OVR_LOG_VAARG_ATTRIBUTE(1,2); - - // Macro to do debug logging, printf-style. - // An extra set of set of parenthesis must be used around arguments, - // as in: OVR_DEBUG_LOG(("Value %d", 2)). - #define OVR_DEBUG_LOG(args) do { OVR::LogDebug args; } while(0) - #define OVR_DEBUG_LOG_TEXT(args) do { OVR::LogDebugText args; } while(0) - - // Conditional logging. It logs when the condition 'c' is true. - #define OVR_DEBUG_LOG_COND(c, args) do { if ((c)) { OVR::LogDebug args; } } while(0) - #define OVR_DEBUG_LOG_TEXT_COND(c, args) do { if ((c)) { OVR::LogDebugText args; } } while(0) - - // Conditional logging & asserting. It asserts/logs when the condition 'c' is NOT true. - #define OVR_ASSERT_LOG(c, args) do { if (!(c)) { OVR::LogAssert args; OVR_DEBUG_BREAK; } } while(0) - -#else - - // If not in debug build, macros do nothing. - #define OVR_DEBUG_LOG(args) ((void)0) - #define OVR_DEBUG_LOG_TEXT(args) ((void)0) - #define OVR_DEBUG_LOG_COND(c, args) ((void)0) - #define OVR_DEBUG_LOG_TEXT_COND(args) ((void)0) - #define OVR_ASSERT_LOG(c, args) ((void)0) - -#endif - -} // OVR - -#endif diff --git a/LibOVR/Src/Kernel/OVR_Math.cpp b/LibOVR/Src/Kernel/OVR_Math.cpp deleted file mode 100644 index 52977ed..0000000 --- a/LibOVR/Src/Kernel/OVR_Math.cpp +++ /dev/null @@ -1,58 +0,0 @@ -/************************************************************************************ - -Filename : OVR_Math.h -Content : Implementation of 3D primitives such as vectors, matrices. -Created : September 4, 2012 -Authors : Andrew Reisse, Michael Antonov, Anna Yershova - -Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); -you may not use the Oculus VR Rift SDK except in compliance with the License, -which is provided at the time of installation or download, or which -otherwise accompanies this software in either electronic or hard copy form. - -You may obtain a copy of the License at - -http://www.oculusvr.com/licenses/LICENSE-3.2 - -Unless required by applicable law or agreed to in writing, the Oculus VR SDK -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -*************************************************************************************/ - -#include "OVR_Math.h" -#include "OVR_Log.h" - -#include <float.h> - - -namespace OVR { - - -//------------------------------------------------------------------------------------- -// ***** Constants - -template<> -const Vector3<float> Vector3<float>::ZERO = Vector3<float>(); - -template<> -const Vector3<double> Vector3<double>::ZERO = Vector3<double>(); - -template<> -const Matrix4<float> Matrix4<float>::IdentityValue = Matrix4<float>(1.0f, 0.0f, 0.0f, 0.0f, - 0.0f, 1.0f, 0.0f, 0.0f, - 0.0f, 0.0f, 1.0f, 0.0f, - 0.0f, 0.0f, 0.0f, 1.0f); - -template<> -const Matrix4<double> Matrix4<double>::IdentityValue = Matrix4<double>(1.0, 0.0, 0.0, 0.0, - 0.0, 1.0, 0.0, 0.0, - 0.0, 0.0, 1.0, 0.0, - 0.0, 0.0, 0.0, 1.0); - - -} // Namespace OVR diff --git a/LibOVR/Src/Kernel/OVR_Math.h b/LibOVR/Src/Kernel/OVR_Math.h deleted file mode 100644 index c187cda..0000000 --- a/LibOVR/Src/Kernel/OVR_Math.h +++ /dev/null @@ -1,2791 +0,0 @@ -/************************************************************************************ - -PublicHeader: OVR_Kernel.h -Filename : OVR_Math.h -Content : Implementation of 3D primitives such as vectors, matrices. -Created : September 4, 2012 -Authors : Andrew Reisse, Michael Antonov, Steve LaValle, - Anna Yershova, Max Katsev, Dov Katz - -Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); -you may not use the Oculus VR Rift SDK except in compliance with the License, -which is provided at the time of installation or download, or which -otherwise accompanies this software in either electronic or hard copy form. - -You may obtain a copy of the License at - -http://www.oculusvr.com/licenses/LICENSE-3.2 - -Unless required by applicable law or agreed to in writing, the Oculus VR SDK -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -*************************************************************************************/ - -#ifndef OVR_Math_h -#define OVR_Math_h - -#include <assert.h> -#include <stdlib.h> -#include <math.h> - -#include "OVR_Types.h" -#include "OVR_RefCount.h" -#include "OVR_Std.h" -#include "OVR_Alg.h" - - -namespace OVR { - -//------------------------------------------------------------------------------------- -// ***** Constants for 3D world/axis definitions. - -// Definitions of axes for coordinate and rotation conversions. -enum Axis -{ - Axis_X = 0, Axis_Y = 1, Axis_Z = 2 -}; - -// RotateDirection describes the rotation direction around an axis, interpreted as follows: -// CW - Clockwise while looking "down" from positive axis towards the origin. -// CCW - Counter-clockwise while looking from the positive axis towards the origin, -// which is in the negative axis direction. -// CCW is the default for the RHS coordinate system. Oculus standard RHS coordinate -// system defines Y up, X right, and Z back (pointing out from the screen). In this -// system Rotate_CCW around Z will specifies counter-clockwise rotation in XY plane. -enum RotateDirection -{ - Rotate_CCW = 1, - Rotate_CW = -1 -}; - -// Constants for right handed and left handed coordinate systems -enum HandedSystem -{ - Handed_R = 1, Handed_L = -1 -}; - -// AxisDirection describes which way the coordinate axis points. Used by WorldAxes. -enum AxisDirection -{ - Axis_Up = 2, - Axis_Down = -2, - Axis_Right = 1, - Axis_Left = -1, - Axis_In = 3, - Axis_Out = -3 -}; - -struct WorldAxes -{ - AxisDirection XAxis, YAxis, ZAxis; - - WorldAxes(AxisDirection x, AxisDirection y, AxisDirection z) - : XAxis(x), YAxis(y), ZAxis(z) - { OVR_ASSERT(abs(x) != abs(y) && abs(y) != abs(z) && abs(z) != abs(x));} -}; - -} // namespace OVR - - -//------------------------------------------------------------------------------------// -// ***** C Compatibility Types - -// These declarations are used to support conversion between C types used in -// LibOVR C interfaces and their C++ versions. As an example, they allow passing -// Vector3f into a function that expects ovrVector3f. - -typedef struct ovrQuatf_ ovrQuatf; -typedef struct ovrQuatd_ ovrQuatd; -typedef struct ovrSizei_ ovrSizei; -typedef struct ovrSizef_ ovrSizef; -typedef struct ovrRecti_ ovrRecti; -typedef struct ovrVector2i_ ovrVector2i; -typedef struct ovrVector2f_ ovrVector2f; -typedef struct ovrVector3f_ ovrVector3f; -typedef struct ovrVector3d_ ovrVector3d; -typedef struct ovrMatrix3d_ ovrMatrix3d; -typedef struct ovrMatrix4f_ ovrMatrix4f; -typedef struct ovrPosef_ ovrPosef; -typedef struct ovrPosed_ ovrPosed; -typedef struct ovrPoseStatef_ ovrPoseStatef; -typedef struct ovrPoseStated_ ovrPoseStated; - -namespace OVR { - -// Forward-declare our templates. -template<class T> class Quat; -template<class T> class Size; -template<class T> class Rect; -template<class T> class Vector2; -template<class T> class Vector3; -template<class T> class Matrix3; -template<class T> class Matrix4; -template<class T> class Pose; -template<class T> class PoseState; - -// CompatibleTypes::Type is used to lookup a compatible C-version of a C++ class. -template<class C> -struct CompatibleTypes -{ - // Declaration here seems necessary for MSVC; specializations are - // used instead. - typedef struct {} Type; -}; - -// Specializations providing CompatibleTypes::Type value. -template<> struct CompatibleTypes<Quat<float> > { typedef ovrQuatf Type; }; -template<> struct CompatibleTypes<Quat<double> > { typedef ovrQuatd Type; }; -template<> struct CompatibleTypes<Matrix3<double> > { typedef ovrMatrix3d Type; }; -template<> struct CompatibleTypes<Matrix4<float> > { typedef ovrMatrix4f Type; }; -template<> struct CompatibleTypes<Size<int> > { typedef ovrSizei Type; }; -template<> struct CompatibleTypes<Size<float> > { typedef ovrSizef Type; }; -template<> struct CompatibleTypes<Rect<int> > { typedef ovrRecti Type; }; -template<> struct CompatibleTypes<Vector2<int> > { typedef ovrVector2i Type; }; -template<> struct CompatibleTypes<Vector2<float> > { typedef ovrVector2f Type; }; -template<> struct CompatibleTypes<Vector3<float> > { typedef ovrVector3f Type; }; -template<> struct CompatibleTypes<Vector3<double> > { typedef ovrVector3d Type; }; - -template<> struct CompatibleTypes<Pose<float> > { typedef ovrPosef Type; }; -template<> struct CompatibleTypes<Pose<double> > { typedef ovrPosed Type; }; - -//------------------------------------------------------------------------------------// -// ***** Math -// -// Math class contains constants and functions. This class is a template specialized -// per type, with Math<float> and Math<double> being distinct. -template<class Type> -class Math -{ -public: - // By default, support explicit conversion to float. This allows Vector2<int> to - // compile, for example. - typedef float OtherFloatType; -}; - - -#define MATH_FLOAT_PI (3.1415926f) -#define MATH_FLOAT_TWOPI (2.0f *MATH_FLOAT_PI) -#define MATH_FLOAT_PIOVER2 (0.5f *MATH_FLOAT_PI) -#define MATH_FLOAT_PIOVER4 (0.25f*MATH_FLOAT_PI) -#define MATH_FLOAT_E (2.7182818f) -#define MATH_FLOAT_MAXVALUE (FLT_MAX) -#define MATH_FLOAT MINPOSITIVEVALUE (FLT_MIN) -#define MATH_FLOAT_RADTODEGREEFACTOR (360.0f / MATH_FLOAT_TWOPI) -#define MATH_FLOAT_DEGREETORADFACTOR (MATH_FLOAT_TWOPI / 360.0f) -#define MATH_FLOAT_TOLERANCE (0.00001f) -#define MATH_FLOAT_SINGULARITYRADIUS (0.0000001f) // Use for Gimbal lock numerical problems - -#define MATH_DOUBLE_PI (3.14159265358979) -#define MATH_DOUBLE_TWOPI (2.0f *MATH_DOUBLE_PI) -#define MATH_DOUBLE_PIOVER2 (0.5f *MATH_DOUBLE_PI) -#define MATH_DOUBLE_PIOVER4 (0.25f*MATH_DOUBLE_PI) -#define MATH_DOUBLE_E (2.71828182845905) -#define MATH_DOUBLE_MAXVALUE (DBL_MAX) -#define MATH_DOUBLE MINPOSITIVEVALUE (DBL_MIN) -#define MATH_DOUBLE_RADTODEGREEFACTOR (360.0f / MATH_DOUBLE_TWOPI) -#define MATH_DOUBLE_DEGREETORADFACTOR (MATH_DOUBLE_TWOPI / 360.0f) -#define MATH_DOUBLE_TOLERANCE (0.00001) -#define MATH_DOUBLE_SINGULARITYRADIUS (0.000000000001) // Use for Gimbal lock numerical problems - - - - -// Single-precision Math constants class. -template<> -class Math<float> -{ -public: - typedef double OtherFloatType; -}; - -// Double-precision Math constants class. -template<> -class Math<double> -{ -public: - typedef float OtherFloatType; -}; - - -typedef Math<float> Mathf; -typedef Math<double> Mathd; - -// Conversion functions between degrees and radians -template<class T> -T RadToDegree(T rads) { return rads * ((T)MATH_DOUBLE_RADTODEGREEFACTOR); } -template<class T> -T DegreeToRad(T rads) { return rads * ((T)MATH_DOUBLE_DEGREETORADFACTOR); } - -// Numerically stable acos function -template<class T> -T Acos(T val) { - if (val > T(1)) return T(0); - else if (val < T(-1)) return ((T)MATH_DOUBLE_PI); - else return acos(val); -}; - -// Numerically stable asin function -template<class T> -T Asin(T val) { - if (val > T(1)) return ((T)MATH_DOUBLE_PIOVER2); - else if (val < T(-1)) return ((T)MATH_DOUBLE_PIOVER2) * T(3); - else return asin(val); -}; - -#ifdef OVR_CC_MSVC -inline int isnan(double x) { return _isnan(x); }; -#endif - -template<class T> -class Quat; - - -//------------------------------------------------------------------------------------- -// ***** Vector2<> - -// Vector2f (Vector2d) represents a 2-dimensional vector or point in space, -// consisting of coordinates x and y - -template<class T> -class Vector2 -{ -public: - T x, y; - - Vector2() : x(0), y(0) { } - Vector2(T x_, T y_) : x(x_), y(y_) { } - explicit Vector2(T s) : x(s), y(s) { } - explicit Vector2(const Vector2<typename Math<T>::OtherFloatType> &src) - : x((T)src.x), y((T)src.y) { } - - - // C-interop support. - typedef typename CompatibleTypes<Vector2<T> >::Type CompatibleType; - - Vector2(const CompatibleType& s) : x(s.x), y(s.y) { } - - operator const CompatibleType& () const - { - static_assert(sizeof(Vector2<T>) == sizeof(CompatibleType), "sizeof(Vector2<T>) failure"); - return reinterpret_cast<const CompatibleType&>(*this); - } - - - bool operator== (const Vector2& b) const { return x == b.x && y == b.y; } - bool operator!= (const Vector2& b) const { return x != b.x || y != b.y; } - - Vector2 operator+ (const Vector2& b) const { return Vector2(x + b.x, y + b.y); } - Vector2& operator+= (const Vector2& b) { x += b.x; y += b.y; return *this; } - Vector2 operator- (const Vector2& b) const { return Vector2(x - b.x, y - b.y); } - Vector2& operator-= (const Vector2& b) { x -= b.x; y -= b.y; return *this; } - Vector2 operator- () const { return Vector2(-x, -y); } - - // Scalar multiplication/division scales vector. - Vector2 operator* (T s) const { return Vector2(x*s, y*s); } - Vector2& operator*= (T s) { x *= s; y *= s; return *this; } - - Vector2 operator/ (T s) const { T rcp = T(1)/s; - return Vector2(x*rcp, y*rcp); } - Vector2& operator/= (T s) { T rcp = T(1)/s; - x *= rcp; y *= rcp; - return *this; } - - static Vector2 Min(const Vector2& a, const Vector2& b) { return Vector2((a.x < b.x) ? a.x : b.x, - (a.y < b.y) ? a.y : b.y); } - static Vector2 Max(const Vector2& a, const Vector2& b) { return Vector2((a.x > b.x) ? a.x : b.x, - (a.y > b.y) ? a.y : b.y); } - - // Compare two vectors for equality with tolerance. Returns true if vectors match withing tolerance. - bool Compare(const Vector2&b, T tolerance = ((T)MATH_DOUBLE_TOLERANCE)) - { - return (fabs(b.x-x) < tolerance) && (fabs(b.y-y) < tolerance); - } - - // Access element by index - T& operator[] (int idx) - { - OVR_ASSERT(0 <= idx && idx < 2); - return *(&x + idx); - } - const T& operator[] (int idx) const - { - OVR_ASSERT(0 <= idx && idx < 2); - return *(&x + idx); - } - - // Entry-wise product of two vectors - Vector2 EntrywiseMultiply(const Vector2& b) const { return Vector2(x * b.x, y * b.y);} - - - // Multiply and divide operators do entry-wise math. Used Dot() for dot product. - Vector2 operator* (const Vector2& b) const { return Vector2(x * b.x, y * b.y); } - Vector2 operator/ (const Vector2& b) const { return Vector2(x / b.x, y / b.y); } - - // Dot product - // Used to calculate angle q between two vectors among other things, - // as (A dot B) = |a||b|cos(q). - T Dot(const Vector2& b) const { return x*b.x + y*b.y; } - - // Returns the angle from this vector to b, in radians. - T Angle(const Vector2& b) const - { - T div = LengthSq()*b.LengthSq(); - OVR_ASSERT(div != T(0)); - T result = Acos((this->Dot(b))/sqrt(div)); - return result; - } - - // Return Length of the vector squared. - T LengthSq() const { return (x * x + y * y); } - - // Return vector length. - T Length() const { return sqrt(LengthSq()); } - - // Returns squared distance between two points represented by vectors. - T DistanceSq(const Vector2& b) const { return (*this - b).LengthSq(); } - - // Returns distance between two points represented by vectors. - T Distance(const Vector2& b) const { return (*this - b).Length(); } - - // Determine if this a unit vector. - bool IsNormalized() const { return fabs(LengthSq() - T(1)) < ((T)MATH_DOUBLE_TOLERANCE); } - - // Normalize, convention vector length to 1. - void Normalize() - { - T l = Length(); - OVR_ASSERT(l != T(0)); - *this /= l; - } - // Returns normalized (unit) version of the vector without modifying itself. - Vector2 Normalized() const - { - T l = Length(); - OVR_ASSERT(l != T(0)); - return *this / l; - } - - // Linearly interpolates from this vector to another. - // Factor should be between 0.0 and 1.0, with 0 giving full value to this. - Vector2 Lerp(const Vector2& b, T f) const { return *this*(T(1) - f) + b*f; } - - // Projects this vector onto the argument; in other words, - // A.Project(B) returns projection of vector A onto B. - Vector2 ProjectTo(const Vector2& b) const - { - T l2 = b.LengthSq(); - OVR_ASSERT(l2 != T(0)); - return b * ( Dot(b) / l2 ); - } -}; - - -typedef Vector2<float> Vector2f; -typedef Vector2<double> Vector2d; -typedef Vector2<int> Vector2i; - -typedef Vector2<float> Point2f; -typedef Vector2<double> Point2d; -typedef Vector2<int> Point2i; - -//------------------------------------------------------------------------------------- -// ***** Vector3<> - 3D vector of {x, y, z} - -// -// Vector3f (Vector3d) represents a 3-dimensional vector or point in space, -// consisting of coordinates x, y and z. - -template<class T> -class Vector3 -{ -public: - T x, y, z; - - // FIXME: default initialization of a vector class can be very expensive in a full-blown - // application. A few hundred thousand vector constructions is not unlikely and can add - // up to milliseconds of time on processors like the PS3 PPU. - Vector3() : x(0), y(0), z(0) { } - Vector3(T x_, T y_, T z_ = 0) : x(x_), y(y_), z(z_) { } - explicit Vector3(T s) : x(s), y(s), z(s) { } - explicit Vector3(const Vector3<typename Math<T>::OtherFloatType> &src) - : x((T)src.x), y((T)src.y), z((T)src.z) { } - - static const Vector3 ZERO; - - // C-interop support. - typedef typename CompatibleTypes<Vector3<T> >::Type CompatibleType; - - Vector3(const CompatibleType& s) : x(s.x), y(s.y), z(s.z) { } - - operator const CompatibleType& () const - { - static_assert(sizeof(Vector3<T>) == sizeof(CompatibleType), "sizeof(Vector3<T>) failure"); - return reinterpret_cast<const CompatibleType&>(*this); - } - - bool operator== (const Vector3& b) const { return x == b.x && y == b.y && z == b.z; } - bool operator!= (const Vector3& b) const { return x != b.x || y != b.y || z != b.z; } - - Vector3 operator+ (const Vector3& b) const { return Vector3(x + b.x, y + b.y, z + b.z); } - Vector3& operator+= (const Vector3& b) { x += b.x; y += b.y; z += b.z; return *this; } - Vector3 operator- (const Vector3& b) const { return Vector3(x - b.x, y - b.y, z - b.z); } - Vector3& operator-= (const Vector3& b) { x -= b.x; y -= b.y; z -= b.z; return *this; } - Vector3 operator- () const { return Vector3(-x, -y, -z); } - - // Scalar multiplication/division scales vector. - Vector3 operator* (T s) const { return Vector3(x*s, y*s, z*s); } - Vector3& operator*= (T s) { x *= s; y *= s; z *= s; return *this; } - - Vector3 operator/ (T s) const { T rcp = T(1)/s; - return Vector3(x*rcp, y*rcp, z*rcp); } - Vector3& operator/= (T s) { T rcp = T(1)/s; - x *= rcp; y *= rcp; z *= rcp; - return *this; } - - static Vector3 Min(const Vector3& a, const Vector3& b) - { - return Vector3((a.x < b.x) ? a.x : b.x, - (a.y < b.y) ? a.y : b.y, - (a.z < b.z) ? a.z : b.z); - } - static Vector3 Max(const Vector3& a, const Vector3& b) - { - return Vector3((a.x > b.x) ? a.x : b.x, - (a.y > b.y) ? a.y : b.y, - (a.z > b.z) ? a.z : b.z); - } - - // Compare two vectors for equality with tolerance. Returns true if vectors match withing tolerance. - bool Compare(const Vector3&b, T tolerance = ((T)MATH_DOUBLE_TOLERANCE)) - { - return (fabs(b.x-x) < tolerance) && - (fabs(b.y-y) < tolerance) && - (fabs(b.z-z) < tolerance); - } - - T& operator[] (int idx) - { - OVR_ASSERT(0 <= idx && idx < 3); - return *(&x + idx); - } - - const T& operator[] (int idx) const - { - OVR_ASSERT(0 <= idx && idx < 3); - return *(&x + idx); - } - - // Entrywise product of two vectors - Vector3 EntrywiseMultiply(const Vector3& b) const { return Vector3(x * b.x, - y * b.y, - z * b.z);} - - // Multiply and divide operators do entry-wise math - Vector3 operator* (const Vector3& b) const { return Vector3(x * b.x, - y * b.y, - z * b.z); } - - Vector3 operator/ (const Vector3& b) const { return Vector3(x / b.x, - y / b.y, - z / b.z); } - - - // Dot product - // Used to calculate angle q between two vectors among other things, - // as (A dot B) = |a||b|cos(q). - T Dot(const Vector3& b) const { return x*b.x + y*b.y + z*b.z; } - - // Compute cross product, which generates a normal vector. - // Direction vector can be determined by right-hand rule: Pointing index finder in - // direction a and middle finger in direction b, thumb will point in a.Cross(b). - Vector3 Cross(const Vector3& b) const { return Vector3(y*b.z - z*b.y, - z*b.x - x*b.z, - x*b.y - y*b.x); } - - // Returns the angle from this vector to b, in radians. - T Angle(const Vector3& b) const - { - T div = LengthSq()*b.LengthSq(); - OVR_ASSERT(div != T(0)); - T result = Acos((this->Dot(b))/sqrt(div)); - return result; - } - - // Return Length of the vector squared. - T LengthSq() const { return (x * x + y * y + z * z); } - - // Return vector length. - T Length() const { return sqrt(LengthSq()); } - - // Returns squared distance between two points represented by vectors. - T DistanceSq(Vector3 const& b) const { return (*this - b).LengthSq(); } - - // Returns distance between two points represented by vectors. - T Distance(Vector3 const& b) const { return (*this - b).Length(); } - - // Determine if this a unit vector. - bool IsNormalized() const { return fabs(LengthSq() - T(1)) < ((T)MATH_DOUBLE_TOLERANCE); } - - // Normalize, convention vector length to 1. - void Normalize() - { - T l = Length(); - OVR_ASSERT(l != T(0)); - *this /= l; - } - - // Returns normalized (unit) version of the vector without modifying itself. - Vector3 Normalized() const - { - T l = Length(); - OVR_ASSERT(l != T(0)); - return *this / l; - } - - // Linearly interpolates from this vector to another. - // Factor should be between 0.0 and 1.0, with 0 giving full value to this. - Vector3 Lerp(const Vector3& b, T f) const { return *this*(T(1) - f) + b*f; } - - // Projects this vector onto the argument; in other words, - // A.Project(B) returns projection of vector A onto B. - Vector3 ProjectTo(const Vector3& b) const - { - T l2 = b.LengthSq(); - OVR_ASSERT(l2 != T(0)); - return b * ( Dot(b) / l2 ); - } - - // Projects this vector onto a plane defined by a normal vector - Vector3 ProjectToPlane(const Vector3& normal) const { return *this - this->ProjectTo(normal); } -}; - -typedef Vector3<float> Vector3f; -typedef Vector3<double> Vector3d; -typedef Vector3<int32_t> Vector3i; - -static_assert((sizeof(Vector3f) == 3*sizeof(float)), "sizeof(Vector3f) failure"); -static_assert((sizeof(Vector3d) == 3*sizeof(double)), "sizeof(Vector3d) failure"); -static_assert((sizeof(Vector3i) == 3*sizeof(int32_t)), "sizeof(Vector3i) failure"); - -typedef Vector3<float> Point3f; -typedef Vector3<double> Point3d; -typedef Vector3<int32_t> Point3i; - - -//------------------------------------------------------------------------------------- -// ***** Vector4<> - 4D vector of {x, y, z, w} - -// -// Vector4f (Vector4d) represents a 3-dimensional vector or point in space, -// consisting of coordinates x, y, z and w. - -template<class T> -class Vector4 -{ -public: - T x, y, z, w; - - // FIXME: default initialization of a vector class can be very expensive in a full-blown - // application. A few hundred thousand vector constructions is not unlikely and can add - // up to milliseconds of time on processors like the PS3 PPU. - Vector4() : x(0), y(0), z(0), w(0) { } - Vector4(T x_, T y_, T z_, T w_) : x(x_), y(y_), z(z_), w(w_) { } - explicit Vector4(T s) : x(s), y(s), z(s), w(s) { } - explicit Vector4(const Vector3<T>& v, const float w_=1) : x(v.x), y(v.y), z(v.z), w(w_) { } - explicit Vector4(const Vector4<typename Math<T>::OtherFloatType> &src) - : x((T)src.x), y((T)src.y), z((T)src.z), w((T)src.w) { } - - static const Vector4 ZERO; - - // C-interop support. - typedef typename CompatibleTypes< Vector4<T> >::Type CompatibleType; - - Vector4(const CompatibleType& s) : x(s.x), y(s.y), z(s.z), w(s.w) { } - - operator const CompatibleType& () const - { - static_assert(sizeof(Vector4<T>) == sizeof(CompatibleType), "sizeof(Vector4<T>) failure"); - return reinterpret_cast<const CompatibleType&>(*this); - } - - Vector4& operator= (const Vector3<T>& other) { x=other.x; y=other.y; z=other.z; w=1; return *this; } - bool operator== (const Vector4& b) const { return x == b.x && y == b.y && z == b.z && w == b.w; } - bool operator!= (const Vector4& b) const { return x != b.x || y != b.y || z != b.z || w != b.w; } - - Vector4 operator+ (const Vector4& b) const { return Vector4(x + b.x, y + b.y, z + b.z, w + b.w); } - Vector4& operator+= (const Vector4& b) { x += b.x; y += b.y; z += b.z; w += b.w; return *this; } - Vector4 operator- (const Vector4& b) const { return Vector4(x - b.x, y - b.y, z - b.z, w - b.w); } - Vector4& operator-= (const Vector4& b) { x -= b.x; y -= b.y; z -= b.z; w -= b.w; return *this; } - Vector4 operator- () const { return Vector4(-x, -y, -z, -w); } - - // Scalar multiplication/division scales vector. - Vector4 operator* (T s) const { return Vector4(x*s, y*s, z*s, w*s); } - Vector4& operator*= (T s) { x *= s; y *= s; z *= s; w *= s;return *this; } - - Vector4 operator/ (T s) const { T rcp = T(1)/s; - return Vector4(x*rcp, y*rcp, z*rcp, w*rcp); } - Vector4& operator/= (T s) { T rcp = T(1)/s; - x *= rcp; y *= rcp; z *= rcp; w *= rcp; - return *this; } - - static Vector4 Min(const Vector4& a, const Vector4& b) - { - return Vector4((a.x < b.x) ? a.x : b.x, - (a.y < b.y) ? a.y : b.y, - (a.z < b.z) ? a.z : b.z, - (a.w < b.w) ? a.w : b.w); - } - static Vector4 Max(const Vector4& a, const Vector4& b) - { - return Vector4((a.x > b.x) ? a.x : b.x, - (a.y > b.y) ? a.y : b.y, - (a.z > b.z) ? a.z : b.z, - (a.w > b.w) ? a.w : b.w); - } - - // Compare two vectors for equality with tolerance. Returns true if vectors match withing tolerance. - bool Compare(const Vector4&b, T tolerance = ((T)MATH_DOUBLE_TOLERANCE)) - { - return (fabs(b.x-x) < tolerance) && - (fabs(b.y-y) < tolerance) && - (fabs(b.z-z) < tolerance) && - (fabs(b.w-w) < tolerance); - } - - T& operator[] (int idx) - { - OVR_ASSERT(0 <= idx && idx < 4); - return *(&x + idx); - } - - const T& operator[] (int idx) const - { - OVR_ASSERT(0 <= idx && idx < 4); - return *(&x + idx); - } - - // Entry wise product of two vectors - Vector4 EntrywiseMultiply(const Vector4& b) const { return Vector4(x * b.x, - y * b.y, - z * b.z);} - - // Multiply and divide operators do entry-wise math - Vector4 operator* (const Vector4& b) const { return Vector4(x * b.x, - y * b.y, - z * b.z, - w * b.w); } - - Vector4 operator/ (const Vector4& b) const { return Vector4(x / b.x, - y / b.y, - z / b.z, - w / b.w); } - - - // Dot product - T Dot(const Vector4& b) const { return x*b.x + y*b.y + z*b.z + w*b.w; } - - // Return Length of the vector squared. - T LengthSq() const { return (x * x + y * y + z * z + w * w); } - - // Return vector length. - T Length() const { return sqrt(LengthSq()); } - - // Determine if this a unit vector. - bool IsNormalized() const { return fabs(LengthSq() - T(1)) < Math<T>::Tolerance; } - - // Normalize, convention vector length to 1. - void Normalize() - { - T l = Length(); - OVR_ASSERT(l != T(0)); - *this /= l; - } - - // Returns normalized (unit) version of the vector without modifying itself. - Vector4 Normalized() const - { - T l = Length(); - OVR_ASSERT(l != T(0)); - return *this / l; - } -}; - -typedef Vector4<float> Vector4f; -typedef Vector4<double> Vector4d; -typedef Vector4<int> Vector4i; - - -//------------------------------------------------------------------------------------- -// ***** Bounds3 - -// Bounds class used to describe a 3D axis aligned bounding box. - -template<class T> -class Bounds3 -{ -public: - Vector3<T> b[2]; - - Bounds3() - { - } - - Bounds3( const Vector3<T> & mins, const Vector3<T> & maxs ) -{ - b[0] = mins; - b[1] = maxs; - } - - void Clear() - { - b[0].x = b[0].y = b[0].z = Math<T>::MaxValue; - b[1].x = b[1].y = b[1].z = -Math<T>::MaxValue; - } - - void AddPoint( const Vector3<T> & v ) - { - b[0].x = Alg::Min( b[0].x, v.x ); - b[0].y = Alg::Min( b[0].y, v.y ); - b[0].z = Alg::Min( b[0].z, v.z ); - b[1].x = Alg::Max( b[1].x, v.x ); - b[1].y = Alg::Max( b[1].y, v.y ); - b[1].z = Alg::Max( b[1].z, v.z ); - } - - const Vector3<T> & GetMins() const { return b[0]; } - const Vector3<T> & GetMaxs() const { return b[1]; } - - Vector3<T> & GetMins() { return b[0]; } - Vector3<T> & GetMaxs() { return b[1]; } -}; - -typedef Bounds3<float> Bounds3f; -typedef Bounds3<double> Bounds3d; - - -//------------------------------------------------------------------------------------- -// ***** Size - -// Size class represents 2D size with Width, Height components. -// Used to describe distentions of render targets, etc. - -template<class T> -class Size -{ -public: - T w, h; - - Size() : w(0), h(0) { } - Size(T w_, T h_) : w(w_), h(h_) { } - explicit Size(T s) : w(s), h(s) { } - explicit Size(const Size<typename Math<T>::OtherFloatType> &src) - : w((T)src.w), h((T)src.h) { } - - // C-interop support. - typedef typename CompatibleTypes<Size<T> >::Type CompatibleType; - - Size(const CompatibleType& s) : w(s.w), h(s.h) { } - - operator const CompatibleType& () const - { - static_assert(sizeof(Size<T>) == sizeof(CompatibleType), "sizeof(Size<T>) failure"); - return reinterpret_cast<const CompatibleType&>(*this); - } - - bool operator== (const Size& b) const { return w == b.w && h == b.h; } - bool operator!= (const Size& b) const { return w != b.w || h != b.h; } - - Size operator+ (const Size& b) const { return Size(w + b.w, h + b.h); } - Size& operator+= (const Size& b) { w += b.w; h += b.h; return *this; } - Size operator- (const Size& b) const { return Size(w - b.w, h - b.h); } - Size& operator-= (const Size& b) { w -= b.w; h -= b.h; return *this; } - Size operator- () const { return Size(-w, -h); } - Size operator* (const Size& b) const { return Size(w * b.w, h * b.h); } - Size& operator*= (const Size& b) { w *= b.w; h *= b.h; return *this; } - Size operator/ (const Size& b) const { return Size(w / b.w, h / b.h); } - Size& operator/= (const Size& b) { w /= b.w; h /= b.h; return *this; } - - // Scalar multiplication/division scales both components. - Size operator* (T s) const { return Size(w*s, h*s); } - Size& operator*= (T s) { w *= s; h *= s; return *this; } - Size operator/ (T s) const { return Size(w/s, h/s); } - Size& operator/= (T s) { w /= s; h /= s; return *this; } - - static Size Min(const Size& a, const Size& b) { return Size((a.w < b.w) ? a.w : b.w, - (a.h < b.h) ? a.h : b.h); } - static Size Max(const Size& a, const Size& b) { return Size((a.w > b.w) ? a.w : b.w, - (a.h > b.h) ? a.h : b.h); } - - T Area() const { return w * h; } - - inline Vector2<T> ToVector() const { return Vector2<T>(w, h); } -}; - - -typedef Size<int> Sizei; -typedef Size<unsigned> Sizeu; -typedef Size<float> Sizef; -typedef Size<double> Sized; - - - -//----------------------------------------------------------------------------------- -// ***** Rect - -// Rect describes a rectangular area for rendering, that includes position and size. -template<class T> -class Rect -{ -public: - T x, y; - T w, h; - - Rect() { } - Rect(T x1, T y1, T w1, T h1) : x(x1), y(y1), w(w1), h(h1) { } - Rect(const Vector2<T>& pos, const Size<T>& sz) : x(pos.x), y(pos.y), w(sz.w), h(sz.h) { } - Rect(const Size<T>& sz) : x(0), y(0), w(sz.w), h(sz.h) { } - - // C-interop support. - typedef typename CompatibleTypes<Rect<T> >::Type CompatibleType; - - Rect(const CompatibleType& s) : x(s.Pos.x), y(s.Pos.y), w(s.Size.w), h(s.Size.h) { } - - operator const CompatibleType& () const - { - static_assert(sizeof(Rect<T>) == sizeof(CompatibleType), "sizeof(Rect<T>) failure"); - return reinterpret_cast<const CompatibleType&>(*this); - } - - Vector2<T> GetPos() const { return Vector2<T>(x, y); } - Size<T> GetSize() const { return Size<T>(w, h); } - void SetPos(const Vector2<T>& pos) { x = pos.x; y = pos.y; } - void SetSize(const Size<T>& sz) { w = sz.w; h = sz.h; } - - bool operator == (const Rect& vp) const - { return (x == vp.x) && (y == vp.y) && (w == vp.w) && (h == vp.h); } - bool operator != (const Rect& vp) const - { return !operator == (vp); } -}; - -typedef Rect<int> Recti; - - -//-------------------------------------------------------------------------------------// -// ***** Quat -// -// Quatf represents a quaternion class used for rotations. -// -// Quaternion multiplications are done in right-to-left order, to match the -// behavior of matrices. - - -template<class T> -class Quat -{ -public: - // w + Xi + Yj + Zk - T x, y, z, w; - - Quat() : x(0), y(0), z(0), w(1) { } - Quat(T x_, T y_, T z_, T w_) : x(x_), y(y_), z(z_), w(w_) { } - explicit Quat(const Quat<typename Math<T>::OtherFloatType> &src) - : x((T)src.x), y((T)src.y), z((T)src.z), w((T)src.w) { } - - typedef typename CompatibleTypes<Quat<T> >::Type CompatibleType; - - // C-interop support. - Quat(const CompatibleType& s) : x(s.x), y(s.y), z(s.z), w(s.w) { } - - operator CompatibleType () const - { - CompatibleType result; - result.x = x; - result.y = y; - result.z = z; - result.w = w; - return result; - } - - // Constructs quaternion for rotation around the axis by an angle. - Quat(const Vector3<T>& axis, T angle) - { - // Make sure we don't divide by zero. - if (axis.LengthSq() == 0) - { - // Assert if the axis is zero, but the angle isn't - OVR_ASSERT(angle == 0); - x = 0; y = 0; z = 0; w = 1; - return; - } - - Vector3<T> unitAxis = axis.Normalized(); - T sinHalfAngle = sin(angle * T(0.5)); - - w = cos(angle * T(0.5)); - x = unitAxis.x * sinHalfAngle; - y = unitAxis.y * sinHalfAngle; - z = unitAxis.z * sinHalfAngle; - } - - // Constructs quaternion for rotation around one of the coordinate axis by an angle. - Quat(Axis A, T angle, RotateDirection d = Rotate_CCW, HandedSystem s = Handed_R) - { - T sinHalfAngle = s * d *sin(angle * T(0.5)); - T v[3]; - v[0] = v[1] = v[2] = T(0); - v[A] = sinHalfAngle; - - w = cos(angle * T(0.5)); - x = v[0]; - y = v[1]; - z = v[2]; - } - - // Compute axis and angle from quaternion - void GetAxisAngle(Vector3<T>* axis, T* angle) const - { - if ( x*x + y*y + z*z > ((T)MATH_DOUBLE_TOLERANCE) * ((T)MATH_DOUBLE_TOLERANCE) ) { - *axis = Vector3<T>(x, y, z).Normalized(); - *angle = 2 * Acos(w); - if (*angle > ((T)MATH_DOUBLE_PI)) // Reduce the magnitude of the angle, if necessary - { - *angle = ((T)MATH_DOUBLE_TWOPI) - *angle; - *axis = *axis * (-1); - } - } - else - { - *axis = Vector3<T>(1, 0, 0); - *angle= 0; - } - } - - // Constructs the quaternion from a rotation matrix - explicit Quat(const Matrix4<T>& m) - { - T trace = m.M[0][0] + m.M[1][1] + m.M[2][2]; - - // In almost all cases, the first part is executed. - // However, if the trace is not positive, the other - // cases arise. - if (trace > T(0)) - { - T s = sqrt(trace + T(1)) * T(2); // s=4*qw - w = T(0.25) * s; - x = (m.M[2][1] - m.M[1][2]) / s; - y = (m.M[0][2] - m.M[2][0]) / s; - z = (m.M[1][0] - m.M[0][1]) / s; - } - else if ((m.M[0][0] > m.M[1][1])&&(m.M[0][0] > m.M[2][2])) - { - T s = sqrt(T(1) + m.M[0][0] - m.M[1][1] - m.M[2][2]) * T(2); - w = (m.M[2][1] - m.M[1][2]) / s; - x = T(0.25) * s; - y = (m.M[0][1] + m.M[1][0]) / s; - z = (m.M[2][0] + m.M[0][2]) / s; - } - else if (m.M[1][1] > m.M[2][2]) - { - T s = sqrt(T(1) + m.M[1][1] - m.M[0][0] - m.M[2][2]) * T(2); // S=4*qy - w = (m.M[0][2] - m.M[2][0]) / s; - x = (m.M[0][1] + m.M[1][0]) / s; - y = T(0.25) * s; - z = (m.M[1][2] + m.M[2][1]) / s; - } - else - { - T s = sqrt(T(1) + m.M[2][2] - m.M[0][0] - m.M[1][1]) * T(2); // S=4*qz - w = (m.M[1][0] - m.M[0][1]) / s; - x = (m.M[0][2] + m.M[2][0]) / s; - y = (m.M[1][2] + m.M[2][1]) / s; - z = T(0.25) * s; - } - } - - // Constructs the quaternion from a rotation matrix - explicit Quat(const Matrix3<T>& m) - { - T trace = m.M[0][0] + m.M[1][1] + m.M[2][2]; - - // In almost all cases, the first part is executed. - // However, if the trace is not positive, the other - // cases arise. - if (trace > T(0)) - { - T s = sqrt(trace + T(1)) * T(2); // s=4*qw - w = T(0.25) * s; - x = (m.M[2][1] - m.M[1][2]) / s; - y = (m.M[0][2] - m.M[2][0]) / s; - z = (m.M[1][0] - m.M[0][1]) / s; - } - else if ((m.M[0][0] > m.M[1][1])&&(m.M[0][0] > m.M[2][2])) - { - T s = sqrt(T(1) + m.M[0][0] - m.M[1][1] - m.M[2][2]) * T(2); - w = (m.M[2][1] - m.M[1][2]) / s; - x = T(0.25) * s; - y = (m.M[0][1] + m.M[1][0]) / s; - z = (m.M[2][0] + m.M[0][2]) / s; - } - else if (m.M[1][1] > m.M[2][2]) - { - T s = sqrt(T(1) + m.M[1][1] - m.M[0][0] - m.M[2][2]) * T(2); // S=4*qy - w = (m.M[0][2] - m.M[2][0]) / s; - x = (m.M[0][1] + m.M[1][0]) / s; - y = T(0.25) * s; - z = (m.M[1][2] + m.M[2][1]) / s; - } - else - { - T s = sqrt(T(1) + m.M[2][2] - m.M[0][0] - m.M[1][1]) * T(2); // S=4*qz - w = (m.M[1][0] - m.M[0][1]) / s; - x = (m.M[0][2] + m.M[2][0]) / s; - y = (m.M[1][2] + m.M[2][1]) / s; - z = T(0.25) * s; - } - } - - bool operator== (const Quat& b) const { return x == b.x && y == b.y && z == b.z && w == b.w; } - bool operator!= (const Quat& b) const { return x != b.x || y != b.y || z != b.z || w != b.w; } - - Quat operator+ (const Quat& b) const { return Quat(x + b.x, y + b.y, z + b.z, w + b.w); } - Quat& operator+= (const Quat& b) { w += b.w; x += b.x; y += b.y; z += b.z; return *this; } - Quat operator- (const Quat& b) const { return Quat(x - b.x, y - b.y, z - b.z, w - b.w); } - Quat& operator-= (const Quat& b) { w -= b.w; x -= b.x; y -= b.y; z -= b.z; return *this; } - - Quat operator* (T s) const { return Quat(x * s, y * s, z * s, w * s); } - Quat& operator*= (T s) { w *= s; x *= s; y *= s; z *= s; return *this; } - Quat operator/ (T s) const { T rcp = T(1)/s; return Quat(x * rcp, y * rcp, z * rcp, w *rcp); } - Quat& operator/= (T s) { T rcp = T(1)/s; w *= rcp; x *= rcp; y *= rcp; z *= rcp; return *this; } - - - // Get Imaginary part vector - Vector3<T> Imag() const { return Vector3<T>(x,y,z); } - - // Get quaternion length. - T Length() const { return sqrt(LengthSq()); } - - // Get quaternion length squared. - T LengthSq() const { return (x * x + y * y + z * z + w * w); } - - // Simple Euclidean distance in R^4 (not SLERP distance, but at least respects Haar measure) - T Distance(const Quat& q) const - { - T d1 = (*this - q).Length(); - T d2 = (*this + q).Length(); // Antipodal point check - return (d1 < d2) ? d1 : d2; - } - - T DistanceSq(const Quat& q) const - { - T d1 = (*this - q).LengthSq(); - T d2 = (*this + q).LengthSq(); // Antipodal point check - return (d1 < d2) ? d1 : d2; - } - - T Dot(const Quat& q) const - { - return x * q.x + y * q.y + z * q.z + w * q.w; - } - - // Angle between two quaternions in radians - T Angle(const Quat& q) const - { - return 2 * Acos(Alg::Abs(Dot(q))); - } - - // Normalize - bool IsNormalized() const { return fabs(LengthSq() - T(1)) < ((T)MATH_DOUBLE_TOLERANCE); } - - void Normalize() - { - T l = Length(); - OVR_ASSERT(l != T(0)); - *this /= l; - } - - Quat Normalized() const - { - T l = Length(); - OVR_ASSERT(l != T(0)); - return *this / l; - } - - // Returns conjugate of the quaternion. Produces inverse rotation if quaternion is normalized. - Quat Conj() const { return Quat(-x, -y, -z, w); } - - // Quaternion multiplication. Combines quaternion rotations, performing the one on the - // right hand side first. - Quat operator* (const Quat& b) const { return Quat(w * b.x + x * b.w + y * b.z - z * b.y, - w * b.y - x * b.z + y * b.w + z * b.x, - w * b.z + x * b.y - y * b.x + z * b.w, - w * b.w - x * b.x - y * b.y - z * b.z); } - - // - // this^p normalized; same as rotating by this p times. - Quat PowNormalized(T p) const - { - Vector3<T> v; - T a; - GetAxisAngle(&v, &a); - return Quat(v, a * p); - } - - // Normalized linear interpolation of quaternions - Quat Nlerp(const Quat& other, T a) - { - T sign = (Dot(other) >= 0) ? 1 : -1; - return (*this * sign * a + other * (1-a)).Normalized(); - } - - // Rotate transforms vector in a manner that matches Matrix rotations (counter-clockwise, - // assuming negative direction of the axis). Standard formula: q(t) * V * q(t)^-1. - Vector3<T> Rotate(const Vector3<T>& v) const - { - return ((*this * Quat<T>(v.x, v.y, v.z, T(0))) * Inverted()).Imag(); - } - - // Inversed quaternion rotates in the opposite direction. - Quat Inverted() const - { - return Quat(-x, -y, -z, w); - } - - // Sets this quaternion to the one rotates in the opposite direction. - void Invert() - { - *this = Quat(-x, -y, -z, w); - } - - // GetEulerAngles extracts Euler angles from the quaternion, in the specified order of - // axis rotations and the specified coordinate system. Right-handed coordinate system - // is the default, with CCW rotations while looking in the negative axis direction. - // Here a,b,c, are the Yaw/Pitch/Roll angles to be returned. - // rotation a around axis A1 - // is followed by rotation b around axis A2 - // is followed by rotation c around axis A3 - // rotations are CCW or CW (D) in LH or RH coordinate system (S) - template <Axis A1, Axis A2, Axis A3, RotateDirection D, HandedSystem S> - void GetEulerAngles(T *a, T *b, T *c) const - { - static_assert((A1 != A2) && (A2 != A3) && (A1 != A3), "(A1 != A2) && (A2 != A3) && (A1 != A3)"); - - T Q[3] = { x, y, z }; //Quaternion components x,y,z - - T ww = w*w; - T Q11 = Q[A1]*Q[A1]; - T Q22 = Q[A2]*Q[A2]; - T Q33 = Q[A3]*Q[A3]; - - T psign = T(-1); - // Determine whether even permutation - if (((A1 + 1) % 3 == A2) && ((A2 + 1) % 3 == A3)) - psign = T(1); - - T s2 = psign * T(2) * (psign*w*Q[A2] + Q[A1]*Q[A3]); - - if (s2 < T(-1) + ((T)MATH_DOUBLE_SINGULARITYRADIUS)) - { // South pole singularity - *a = T(0); - *b = -S*D*((T)MATH_DOUBLE_PIOVER2); - *c = S*D*atan2(T(2)*(psign*Q[A1]*Q[A2] + w*Q[A3]), - ww + Q22 - Q11 - Q33 ); - } - else if (s2 > T(1) - ((T)MATH_DOUBLE_SINGULARITYRADIUS)) - { // North pole singularity - *a = T(0); - *b = S*D*((T)MATH_DOUBLE_PIOVER2); - *c = S*D*atan2(T(2)*(psign*Q[A1]*Q[A2] + w*Q[A3]), - ww + Q22 - Q11 - Q33); - } - else - { - *a = -S*D*atan2(T(-2)*(w*Q[A1] - psign*Q[A2]*Q[A3]), - ww + Q33 - Q11 - Q22); - *b = S*D*asin(s2); - *c = S*D*atan2(T(2)*(w*Q[A3] - psign*Q[A1]*Q[A2]), - ww + Q11 - Q22 - Q33); - } - return; - } - - template <Axis A1, Axis A2, Axis A3, RotateDirection D> - void GetEulerAngles(T *a, T *b, T *c) const - { GetEulerAngles<A1, A2, A3, D, Handed_R>(a, b, c); } - - template <Axis A1, Axis A2, Axis A3> - void GetEulerAngles(T *a, T *b, T *c) const - { GetEulerAngles<A1, A2, A3, Rotate_CCW, Handed_R>(a, b, c); } - - // GetEulerAnglesABA extracts Euler angles from the quaternion, in the specified order of - // axis rotations and the specified coordinate system. Right-handed coordinate system - // is the default, with CCW rotations while looking in the negative axis direction. - // Here a,b,c, are the Yaw/Pitch/Roll angles to be returned. - // rotation a around axis A1 - // is followed by rotation b around axis A2 - // is followed by rotation c around axis A1 - // Rotations are CCW or CW (D) in LH or RH coordinate system (S) - template <Axis A1, Axis A2, RotateDirection D, HandedSystem S> - void GetEulerAnglesABA(T *a, T *b, T *c) const - { - static_assert(A1 != A2, "A1 != A2"); - - T Q[3] = {x, y, z}; // Quaternion components - - // Determine the missing axis that was not supplied - int m = 3 - A1 - A2; - - T ww = w*w; - T Q11 = Q[A1]*Q[A1]; - T Q22 = Q[A2]*Q[A2]; - T Qmm = Q[m]*Q[m]; - - T psign = T(-1); - if ((A1 + 1) % 3 == A2) // Determine whether even permutation - { - psign = T(1); - } - - T c2 = ww + Q11 - Q22 - Qmm; - if (c2 < T(-1) + Math<T>::SingularityRadius) - { // South pole singularity - *a = T(0); - *b = S*D*((T)MATH_DOUBLE_PI); - *c = S*D*atan2( T(2)*(w*Q[A1] - psign*Q[A2]*Q[m]), - ww + Q22 - Q11 - Qmm); - } - else if (c2 > T(1) - Math<T>::SingularityRadius) - { // North pole singularity - *a = T(0); - *b = T(0); - *c = S*D*atan2( T(2)*(w*Q[A1] - psign*Q[A2]*Q[m]), - ww + Q22 - Q11 - Qmm); - } - else - { - *a = S*D*atan2( psign*w*Q[m] + Q[A1]*Q[A2], - w*Q[A2] -psign*Q[A1]*Q[m]); - *b = S*D*acos(c2); - *c = S*D*atan2( -psign*w*Q[m] + Q[A1]*Q[A2], - w*Q[A2] + psign*Q[A1]*Q[m]); - } - return; - } -}; - -typedef Quat<float> Quatf; -typedef Quat<double> Quatd; - -static_assert((sizeof(Quatf) == 4*sizeof(float)), "sizeof(Quatf) failure"); -static_assert((sizeof(Quatd) == 4*sizeof(double)), "sizeof(Quatd) failure"); - -//------------------------------------------------------------------------------------- -// ***** Pose - -// Position and orientation combined. - -template<class T> -class Pose -{ -public: - typedef typename CompatibleTypes<Pose<T> >::Type CompatibleType; - - Pose() { } - Pose(const Quat<T>& orientation, const Vector3<T>& pos) - : Rotation(orientation), Translation(pos) { } - Pose(const Pose& s) - : Rotation(s.Rotation), Translation(s.Translation) { } - Pose(const CompatibleType& s) - : Rotation(s.Orientation), Translation(s.Position) { } - explicit Pose(const Pose<typename Math<T>::OtherFloatType> &s) - : Rotation(s.Rotation), Translation(s.Translation) { } - - operator typename CompatibleTypes<Pose<T> >::Type () const - { - typename CompatibleTypes<Pose<T> >::Type result; - result.Orientation = Rotation; - result.Position = Translation; - return result; - } - - Quat<T> Rotation; - Vector3<T> Translation; - - static_assert((sizeof(T) == sizeof(double) || sizeof(T) == sizeof(float)), "(sizeof(T) == sizeof(double) || sizeof(T) == sizeof(float))"); - - void ToArray(T* arr) const - { - T temp[7] = { Rotation.x, Rotation.y, Rotation.z, Rotation.w, Translation.x, Translation.y, Translation.z }; - for (int i = 0; i < 7; i++) arr[i] = temp[i]; - } - - static Pose<T> FromArray(const T* v) - { - Quat<T> rotation(v[0], v[1], v[2], v[3]); - Vector3<T> translation(v[4], v[5], v[6]); - return Pose<T>(rotation, translation); - } - - Vector3<T> Rotate(const Vector3<T>& v) const - { - return Rotation.Rotate(v); - } - - Vector3<T> Translate(const Vector3<T>& v) const - { - return v + Translation; - } - - Vector3<T> Apply(const Vector3<T>& v) const - { - return Translate(Rotate(v)); - } - - Pose operator*(const Pose& other) const - { - return Pose(Rotation * other.Rotation, Apply(other.Translation)); - } - - Pose Inverted() const - { - Quat<T> inv = Rotation.Inverted(); - return Pose(inv, inv.Rotate(-Translation)); - } -}; - -typedef Pose<float> Posef; -typedef Pose<double> Posed; - -static_assert((sizeof(Posed) == sizeof(Quatd) + sizeof(Vector3d)), "sizeof(Posed) failure"); -static_assert((sizeof(Posef) == sizeof(Quatf) + sizeof(Vector3f)), "sizeof(Posef) failure"); - - -//------------------------------------------------------------------------------------- -// ***** Matrix4 -// -// Matrix4 is a 4x4 matrix used for 3d transformations and projections. -// Translation stored in the last column. -// The matrix is stored in row-major order in memory, meaning that values -// of the first row are stored before the next one. -// -// The arrangement of the matrix is chosen to be in Right-Handed -// coordinate system and counterclockwise rotations when looking down -// the axis -// -// Transformation Order: -// - Transformations are applied from right to left, so the expression -// M1 * M2 * M3 * V means that the vector V is transformed by M3 first, -// followed by M2 and M1. -// -// Coordinate system: Right Handed -// -// Rotations: Counterclockwise when looking down the axis. All angles are in radians. -// -// | sx 01 02 tx | // First column (sx, 10, 20): Axis X basis vector. -// | 10 sy 12 ty | // Second column (01, sy, 21): Axis Y basis vector. -// | 20 21 sz tz | // Third columnt (02, 12, sz): Axis Z basis vector. -// | 30 31 32 33 | -// -// The basis vectors are first three columns. - -template<class T> -class Matrix4 -{ - static const Matrix4 IdentityValue; - -public: - T M[4][4]; - - enum NoInitType { NoInit }; - - // Construct with no memory initialization. - Matrix4(NoInitType) { } - - // By default, we construct identity matrix. - Matrix4() - { - SetIdentity(); - } - - Matrix4(T m11, T m12, T m13, T m14, - T m21, T m22, T m23, T m24, - T m31, T m32, T m33, T m34, - T m41, T m42, T m43, T m44) - { - M[0][0] = m11; M[0][1] = m12; M[0][2] = m13; M[0][3] = m14; - M[1][0] = m21; M[1][1] = m22; M[1][2] = m23; M[1][3] = m24; - M[2][0] = m31; M[2][1] = m32; M[2][2] = m33; M[2][3] = m34; - M[3][0] = m41; M[3][1] = m42; M[3][2] = m43; M[3][3] = m44; - } - - Matrix4(T m11, T m12, T m13, - T m21, T m22, T m23, - T m31, T m32, T m33) - { - M[0][0] = m11; M[0][1] = m12; M[0][2] = m13; M[0][3] = 0; - M[1][0] = m21; M[1][1] = m22; M[1][2] = m23; M[1][3] = 0; - M[2][0] = m31; M[2][1] = m32; M[2][2] = m33; M[2][3] = 0; - M[3][0] = 0; M[3][1] = 0; M[3][2] = 0; M[3][3] = 1; - } - - explicit Matrix4(const Quat<T>& q) - { - T ww = q.w*q.w; - T xx = q.x*q.x; - T yy = q.y*q.y; - T zz = q.z*q.z; - - M[0][0] = ww + xx - yy - zz; M[0][1] = 2 * (q.x*q.y - q.w*q.z); M[0][2] = 2 * (q.x*q.z + q.w*q.y); M[0][3] = 0; - M[1][0] = 2 * (q.x*q.y + q.w*q.z); M[1][1] = ww - xx + yy - zz; M[1][2] = 2 * (q.y*q.z - q.w*q.x); M[1][3] = 0; - M[2][0] = 2 * (q.x*q.z - q.w*q.y); M[2][1] = 2 * (q.y*q.z + q.w*q.x); M[2][2] = ww - xx - yy + zz; M[2][3] = 0; - M[3][0] = 0; M[3][1] = 0; M[3][2] = 0; M[3][3] = 1; - } - - explicit Matrix4(const Pose<T>& p) - { - Matrix4 result(p.Rotation); - result.SetTranslation(p.Translation); - *this = result; - } - - // C-interop support - explicit Matrix4(const Matrix4<typename Math<T>::OtherFloatType> &src) - { - for (int i = 0; i < 4; i++) - for (int j = 0; j < 4; j++) - M[i][j] = (T)src.M[i][j]; - } - - // C-interop support. - Matrix4(const typename CompatibleTypes<Matrix4<T> >::Type& s) - { - static_assert(sizeof(s) == sizeof(Matrix4), "sizeof(s) == sizeof(Matrix4)"); - memcpy(M, s.M, sizeof(M)); - } - - operator typename CompatibleTypes<Matrix4<T> >::Type () const - { - typename CompatibleTypes<Matrix4<T> >::Type result; - static_assert(sizeof(result) == sizeof(Matrix4), "sizeof(result) == sizeof(Matrix4)"); - memcpy(result.M, M, sizeof(M)); - return result; - } - - void ToString(char* dest, size_t destsize) const - { - size_t pos = 0; - for (int r=0; r<4; r++) - for (int c=0; c<4; c++) - pos += OVR_sprintf(dest+pos, destsize-pos, "%g ", M[r][c]); - } - - static Matrix4 FromString(const char* src) - { - Matrix4 result; - if (src) - { - for (int r=0; r<4; r++) - { - for (int c=0; c<4; c++) - { - result.M[r][c] = (T)atof(src); - while (src && *src != ' ') - { - src++; - } - while (src && *src == ' ') - { - src++; - } - } - } - } - return result; - } - - static const Matrix4& Identity() { return IdentityValue; } - - void SetIdentity() - { - M[0][0] = M[1][1] = M[2][2] = M[3][3] = 1; - M[0][1] = M[1][0] = M[2][3] = M[3][1] = 0; - M[0][2] = M[1][2] = M[2][0] = M[3][2] = 0; - M[0][3] = M[1][3] = M[2][1] = M[3][0] = 0; - } - - void SetXBasis(const Vector3f & v) - { - M[0][0] = v.x; - M[1][0] = v.y; - M[2][0] = v.z; - } - Vector3f GetXBasis() const - { - return Vector3f(M[0][0], M[1][0], M[2][0]); - } - - void SetYBasis(const Vector3f & v) - { - M[0][1] = v.x; - M[1][1] = v.y; - M[2][1] = v.z; - } - Vector3f GetYBasis() const - { - return Vector3f(M[0][1], M[1][1], M[2][1]); - } - - void SetZBasis(const Vector3f & v) - { - M[0][2] = v.x; - M[1][2] = v.y; - M[2][2] = v.z; - } - Vector3f GetZBasis() const - { - return Vector3f(M[0][2], M[1][2], M[2][2]); - } - - bool operator== (const Matrix4& b) const - { - bool isEqual = true; - for (int i = 0; i < 4; i++) - for (int j = 0; j < 4; j++) - isEqual &= (M[i][j] == b.M[i][j]); - - return isEqual; - } - - Matrix4 operator+ (const Matrix4& b) const - { - Matrix4 result(*this); - result += b; - return result; - } - - Matrix4& operator+= (const Matrix4& b) - { - for (int i = 0; i < 4; i++) - for (int j = 0; j < 4; j++) - M[i][j] += b.M[i][j]; - return *this; - } - - Matrix4 operator- (const Matrix4& b) const - { - Matrix4 result(*this); - result -= b; - return result; - } - - Matrix4& operator-= (const Matrix4& b) - { - for (int i = 0; i < 4; i++) - for (int j = 0; j < 4; j++) - M[i][j] -= b.M[i][j]; - return *this; - } - - // Multiplies two matrices into destination with minimum copying. - static Matrix4& Multiply(Matrix4* d, const Matrix4& a, const Matrix4& b) - { - OVR_ASSERT((d != &a) && (d != &b)); - int i = 0; - do { - d->M[i][0] = a.M[i][0] * b.M[0][0] + a.M[i][1] * b.M[1][0] + a.M[i][2] * b.M[2][0] + a.M[i][3] * b.M[3][0]; - d->M[i][1] = a.M[i][0] * b.M[0][1] + a.M[i][1] * b.M[1][1] + a.M[i][2] * b.M[2][1] + a.M[i][3] * b.M[3][1]; - d->M[i][2] = a.M[i][0] * b.M[0][2] + a.M[i][1] * b.M[1][2] + a.M[i][2] * b.M[2][2] + a.M[i][3] * b.M[3][2]; - d->M[i][3] = a.M[i][0] * b.M[0][3] + a.M[i][1] * b.M[1][3] + a.M[i][2] * b.M[2][3] + a.M[i][3] * b.M[3][3]; - } while((++i) < 4); - - return *d; - } - - Matrix4 operator* (const Matrix4& b) const - { - Matrix4 result(Matrix4::NoInit); - Multiply(&result, *this, b); - return result; - } - - Matrix4& operator*= (const Matrix4& b) - { - return Multiply(this, Matrix4(*this), b); - } - - Matrix4 operator* (T s) const - { - Matrix4 result(*this); - result *= s; - return result; - } - - Matrix4& operator*= (T s) - { - for (int i = 0; i < 4; i++) - for (int j = 0; j < 4; j++) - M[i][j] *= s; - return *this; - } - - - Matrix4 operator/ (T s) const - { - Matrix4 result(*this); - result /= s; - return result; - } - - Matrix4& operator/= (T s) - { - for (int i = 0; i < 4; i++) - for (int j = 0; j < 4; j++) - M[i][j] /= s; - return *this; - } - - Vector3<T> Transform(const Vector3<T>& v) const - { - const T rcpW = 1.0f / (M[3][0] * v.x + M[3][1] * v.y + M[3][2] * v.z + M[3][3]); - return Vector3<T>((M[0][0] * v.x + M[0][1] * v.y + M[0][2] * v.z + M[0][3]) * rcpW, - (M[1][0] * v.x + M[1][1] * v.y + M[1][2] * v.z + M[1][3]) * rcpW, - (M[2][0] * v.x + M[2][1] * v.y + M[2][2] * v.z + M[2][3]) * rcpW); - } - - Vector4<T> Transform(const Vector4<T>& v) const - { - return Vector4<T>(M[0][0] * v.x + M[0][1] * v.y + M[0][2] * v.z + M[0][3] * v.w, - M[1][0] * v.x + M[1][1] * v.y + M[1][2] * v.z + M[1][3] * v.w, - M[2][0] * v.x + M[2][1] * v.y + M[2][2] * v.z + M[2][3] * v.w, - M[3][0] * v.x + M[3][1] * v.y + M[3][2] * v.z + M[3][3] * v.w); - } - - Matrix4 Transposed() const - { - return Matrix4(M[0][0], M[1][0], M[2][0], M[3][0], - M[0][1], M[1][1], M[2][1], M[3][1], - M[0][2], M[1][2], M[2][2], M[3][2], - M[0][3], M[1][3], M[2][3], M[3][3]); - } - - void Transpose() - { - *this = Transposed(); - } - - - T SubDet (const size_t* rows, const size_t* cols) const - { - return M[rows[0]][cols[0]] * (M[rows[1]][cols[1]] * M[rows[2]][cols[2]] - M[rows[1]][cols[2]] * M[rows[2]][cols[1]]) - - M[rows[0]][cols[1]] * (M[rows[1]][cols[0]] * M[rows[2]][cols[2]] - M[rows[1]][cols[2]] * M[rows[2]][cols[0]]) - + M[rows[0]][cols[2]] * (M[rows[1]][cols[0]] * M[rows[2]][cols[1]] - M[rows[1]][cols[1]] * M[rows[2]][cols[0]]); - } - - T Cofactor(size_t I, size_t J) const - { - const size_t indices[4][3] = {{1,2,3},{0,2,3},{0,1,3},{0,1,2}}; - return ((I+J)&1) ? -SubDet(indices[I],indices[J]) : SubDet(indices[I],indices[J]); - } - - T Determinant() const - { - return M[0][0] * Cofactor(0,0) + M[0][1] * Cofactor(0,1) + M[0][2] * Cofactor(0,2) + M[0][3] * Cofactor(0,3); - } - - Matrix4 Adjugated() const - { - return Matrix4(Cofactor(0,0), Cofactor(1,0), Cofactor(2,0), Cofactor(3,0), - Cofactor(0,1), Cofactor(1,1), Cofactor(2,1), Cofactor(3,1), - Cofactor(0,2), Cofactor(1,2), Cofactor(2,2), Cofactor(3,2), - Cofactor(0,3), Cofactor(1,3), Cofactor(2,3), Cofactor(3,3)); - } - - Matrix4 Inverted() const - { - T det = Determinant(); - assert(det != 0); - return Adjugated() * (1.0f/det); - } - - void Invert() - { - *this = Inverted(); - } - - // This is more efficient than general inverse, but ONLY works - // correctly if it is a homogeneous transform matrix (rot + trans) - Matrix4 InvertedHomogeneousTransform() const - { - // Make the inverse rotation matrix - Matrix4 rinv = this->Transposed(); - rinv.M[3][0] = rinv.M[3][1] = rinv.M[3][2] = 0.0f; - // Make the inverse translation matrix - Vector3<T> tvinv(-M[0][3],-M[1][3],-M[2][3]); - Matrix4 tinv = Matrix4::Translation(tvinv); - return rinv * tinv; // "untranslate", then "unrotate" - } - - // This is more efficient than general inverse, but ONLY works - // correctly if it is a homogeneous transform matrix (rot + trans) - void InvertHomogeneousTransform() - { - *this = InvertedHomogeneousTransform(); - } - - // Matrix to Euler Angles conversion - // a,b,c, are the YawPitchRoll angles to be returned - // rotation a around axis A1 - // is followed by rotation b around axis A2 - // is followed by rotation c around axis A3 - // rotations are CCW or CW (D) in LH or RH coordinate system (S) - template <Axis A1, Axis A2, Axis A3, RotateDirection D, HandedSystem S> - void ToEulerAngles(T *a, T *b, T *c) const - { - static_assert((A1 != A2) && (A2 != A3) && (A1 != A3), "(A1 != A2) && (A2 != A3) && (A1 != A3)"); - - T psign = -1; - if (((A1 + 1) % 3 == A2) && ((A2 + 1) % 3 == A3)) // Determine whether even permutation - psign = 1; - - T pm = psign*M[A1][A3]; - if (pm < -1.0f + Math<T>::SingularityRadius) - { // South pole singularity - *a = 0; - *b = -S*D*((T)MATH_DOUBLE_PIOVER2); - *c = S*D*atan2( psign*M[A2][A1], M[A2][A2] ); - } - else if (pm > 1.0f - Math<T>::SingularityRadius) - { // North pole singularity - *a = 0; - *b = S*D*((T)MATH_DOUBLE_PIOVER2); - *c = S*D*atan2( psign*M[A2][A1], M[A2][A2] ); - } - else - { // Normal case (nonsingular) - *a = S*D*atan2( -psign*M[A2][A3], M[A3][A3] ); - *b = S*D*asin(pm); - *c = S*D*atan2( -psign*M[A1][A2], M[A1][A1] ); - } - - return; - } - - // Matrix to Euler Angles conversion - // a,b,c, are the YawPitchRoll angles to be returned - // rotation a around axis A1 - // is followed by rotation b around axis A2 - // is followed by rotation c around axis A1 - // rotations are CCW or CW (D) in LH or RH coordinate system (S) - template <Axis A1, Axis A2, RotateDirection D, HandedSystem S> - void ToEulerAnglesABA(T *a, T *b, T *c) const - { - static_assert(A1 != A2, "A1 != A2"); - - // Determine the axis that was not supplied - int m = 3 - A1 - A2; - - T psign = -1; - if ((A1 + 1) % 3 == A2) // Determine whether even permutation - psign = 1.0f; - - T c2 = M[A1][A1]; - if (c2 < -1 + Math<T>::SingularityRadius) - { // South pole singularity - *a = 0; - *b = S*D*((T)MATH_DOUBLE_PI); - *c = S*D*atan2( -psign*M[A2][m],M[A2][A2]); - } - else if (c2 > 1.0f - Math<T>::SingularityRadius) - { // North pole singularity - *a = 0; - *b = 0; - *c = S*D*atan2( -psign*M[A2][m],M[A2][A2]); - } - else - { // Normal case (nonsingular) - *a = S*D*atan2( M[A2][A1],-psign*M[m][A1]); - *b = S*D*acos(c2); - *c = S*D*atan2( M[A1][A2],psign*M[A1][m]); - } - return; - } - - // Creates a matrix that converts the vertices from one coordinate system - // to another. - static Matrix4 AxisConversion(const WorldAxes& to, const WorldAxes& from) - { - // Holds axis values from the 'to' structure - int toArray[3] = { to.XAxis, to.YAxis, to.ZAxis }; - - // The inverse of the toArray - int inv[4]; - inv[0] = inv[abs(to.XAxis)] = 0; - inv[abs(to.YAxis)] = 1; - inv[abs(to.ZAxis)] = 2; - - Matrix4 m(0, 0, 0, - 0, 0, 0, - 0, 0, 0); - - // Only three values in the matrix need to be changed to 1 or -1. - m.M[inv[abs(from.XAxis)]][0] = T(from.XAxis/toArray[inv[abs(from.XAxis)]]); - m.M[inv[abs(from.YAxis)]][1] = T(from.YAxis/toArray[inv[abs(from.YAxis)]]); - m.M[inv[abs(from.ZAxis)]][2] = T(from.ZAxis/toArray[inv[abs(from.ZAxis)]]); - return m; - } - - - // Creates a matrix for translation by vector - static Matrix4 Translation(const Vector3<T>& v) - { - Matrix4 t; - t.M[0][3] = v.x; - t.M[1][3] = v.y; - t.M[2][3] = v.z; - return t; - } - - // Creates a matrix for translation by vector - static Matrix4 Translation(T x, T y, T z = 0.0f) - { - Matrix4 t; - t.M[0][3] = x; - t.M[1][3] = y; - t.M[2][3] = z; - return t; - } - - // Sets the translation part - void SetTranslation(const Vector3<T>& v) - { - M[0][3] = v.x; - M[1][3] = v.y; - M[2][3] = v.z; - } - - Vector3<T> GetTranslation() const - { - return Vector3<T>( M[0][3], M[1][3], M[2][3] ); - } - - // Creates a matrix for scaling by vector - static Matrix4 Scaling(const Vector3<T>& v) - { - Matrix4 t; - t.M[0][0] = v.x; - t.M[1][1] = v.y; - t.M[2][2] = v.z; - return t; - } - - // Creates a matrix for scaling by vector - static Matrix4 Scaling(T x, T y, T z) - { - Matrix4 t; - t.M[0][0] = x; - t.M[1][1] = y; - t.M[2][2] = z; - return t; - } - - // Creates a matrix for scaling by constant - static Matrix4 Scaling(T s) - { - Matrix4 t; - t.M[0][0] = s; - t.M[1][1] = s; - t.M[2][2] = s; - return t; - } - - // Simple L1 distance in R^12 - T Distance(const Matrix4& m2) const - { - T d = fabs(M[0][0] - m2.M[0][0]) + fabs(M[0][1] - m2.M[0][1]); - d += fabs(M[0][2] - m2.M[0][2]) + fabs(M[0][3] - m2.M[0][3]); - d += fabs(M[1][0] - m2.M[1][0]) + fabs(M[1][1] - m2.M[1][1]); - d += fabs(M[1][2] - m2.M[1][2]) + fabs(M[1][3] - m2.M[1][3]); - d += fabs(M[2][0] - m2.M[2][0]) + fabs(M[2][1] - m2.M[2][1]); - d += fabs(M[2][2] - m2.M[2][2]) + fabs(M[2][3] - m2.M[2][3]); - d += fabs(M[3][0] - m2.M[3][0]) + fabs(M[3][1] - m2.M[3][1]); - d += fabs(M[3][2] - m2.M[3][2]) + fabs(M[3][3] - m2.M[3][3]); - return d; - } - - // Creates a rotation matrix rotating around the X axis by 'angle' radians. - // Just for quick testing. Not for final API. Need to remove case. - static Matrix4 RotationAxis(Axis A, T angle, RotateDirection d, HandedSystem s) - { - T sina = s * d *sin(angle); - T cosa = cos(angle); - - switch(A) - { - case Axis_X: - return Matrix4(1, 0, 0, - 0, cosa, -sina, - 0, sina, cosa); - case Axis_Y: - return Matrix4(cosa, 0, sina, - 0, 1, 0, - -sina, 0, cosa); - case Axis_Z: - return Matrix4(cosa, -sina, 0, - sina, cosa, 0, - 0, 0, 1); - } - } - - - // Creates a rotation matrix rotating around the X axis by 'angle' radians. - // Rotation direction is depends on the coordinate system: - // RHS (Oculus default): Positive angle values rotate Counter-clockwise (CCW), - // while looking in the negative axis direction. This is the - // same as looking down from positive axis values towards origin. - // LHS: Positive angle values rotate clock-wise (CW), while looking in the - // negative axis direction. - static Matrix4 RotationX(T angle) - { - T sina = sin(angle); - T cosa = cos(angle); - return Matrix4(1, 0, 0, - 0, cosa, -sina, - 0, sina, cosa); - } - - // Creates a rotation matrix rotating around the Y axis by 'angle' radians. - // Rotation direction is depends on the coordinate system: - // RHS (Oculus default): Positive angle values rotate Counter-clockwise (CCW), - // while looking in the negative axis direction. This is the - // same as looking down from positive axis values towards origin. - // LHS: Positive angle values rotate clock-wise (CW), while looking in the - // negative axis direction. - static Matrix4 RotationY(T angle) - { - T sina = sin(angle); - T cosa = cos(angle); - return Matrix4(cosa, 0, sina, - 0, 1, 0, - -sina, 0, cosa); - } - - // Creates a rotation matrix rotating around the Z axis by 'angle' radians. - // Rotation direction is depends on the coordinate system: - // RHS (Oculus default): Positive angle values rotate Counter-clockwise (CCW), - // while looking in the negative axis direction. This is the - // same as looking down from positive axis values towards origin. - // LHS: Positive angle values rotate clock-wise (CW), while looking in the - // negative axis direction. - static Matrix4 RotationZ(T angle) - { - T sina = sin(angle); - T cosa = cos(angle); - return Matrix4(cosa, -sina, 0, - sina, cosa, 0, - 0, 0, 1); - } - - // LookAtRH creates a View transformation matrix for right-handed coordinate system. - // The resulting matrix points camera from 'eye' towards 'at' direction, with 'up' - // specifying the up vector. The resulting matrix should be used with PerspectiveRH - // projection. - static Matrix4 LookAtRH(const Vector3<T>& eye, const Vector3<T>& at, const Vector3<T>& up) - { - Vector3<T> z = (eye - at).Normalized(); // Forward - Vector3<T> x = up.Cross(z).Normalized(); // Right - Vector3<T> y = z.Cross(x); - - Matrix4 m(x.x, x.y, x.z, -(x.Dot(eye)), - y.x, y.y, y.z, -(y.Dot(eye)), - z.x, z.y, z.z, -(z.Dot(eye)), - 0, 0, 0, 1 ); - return m; - } - - // LookAtLH creates a View transformation matrix for left-handed coordinate system. - // The resulting matrix points camera from 'eye' towards 'at' direction, with 'up' - // specifying the up vector. - static Matrix4 LookAtLH(const Vector3<T>& eye, const Vector3<T>& at, const Vector3<T>& up) - { - Vector3<T> z = (at - eye).Normalized(); // Forward - Vector3<T> x = up.Cross(z).Normalized(); // Right - Vector3<T> y = z.Cross(x); - - Matrix4 m(x.x, x.y, x.z, -(x.Dot(eye)), - y.x, y.y, y.z, -(y.Dot(eye)), - z.x, z.y, z.z, -(z.Dot(eye)), - 0, 0, 0, 1 ); - return m; - } - - // PerspectiveRH creates a right-handed perspective projection matrix that can be - // used with the Oculus sample renderer. - // yfov - Specifies vertical field of view in radians. - // aspect - Screen aspect ration, which is usually width/height for square pixels. - // Note that xfov = yfov * aspect. - // znear - Absolute value of near Z clipping clipping range. - // zfar - Absolute value of far Z clipping clipping range (larger then near). - // Even though RHS usually looks in the direction of negative Z, positive values - // are expected for znear and zfar. - static Matrix4 PerspectiveRH(T yfov, T aspect, T znear, T zfar) - { - Matrix4 m; - T tanHalfFov = tan(yfov * 0.5f); - - m.M[0][0] = 1. / (aspect * tanHalfFov); - m.M[1][1] = 1. / tanHalfFov; - m.M[2][2] = zfar / (znear - zfar); - m.M[3][2] = -1.; - m.M[2][3] = (zfar * znear) / (znear - zfar); - m.M[3][3] = 0.; - - // Note: Post-projection matrix result assumes Left-Handed coordinate system, - // with Y up, X right and Z forward. This supports positive z-buffer values. - // This is the case even for RHS coordinate input. - return m; - } - - // PerspectiveLH creates a left-handed perspective projection matrix that can be - // used with the Oculus sample renderer. - // yfov - Specifies vertical field of view in radians. - // aspect - Screen aspect ration, which is usually width/height for square pixels. - // Note that xfov = yfov * aspect. - // znear - Absolute value of near Z clipping clipping range. - // zfar - Absolute value of far Z clipping clipping range (larger then near). - static Matrix4 PerspectiveLH(T yfov, T aspect, T znear, T zfar) - { - Matrix4 m; - T tanHalfFov = tan(yfov * 0.5f); - - m.M[0][0] = 1. / (aspect * tanHalfFov); - m.M[1][1] = 1. / tanHalfFov; - //m.M[2][2] = zfar / (znear - zfar); - m.M[2][2] = zfar / (zfar - znear); - m.M[3][2] = -1.; - m.M[2][3] = (zfar * znear) / (znear - zfar); - m.M[3][3] = 0.; - - // Note: Post-projection matrix result assumes Left-Handed coordinate system, - // with Y up, X right and Z forward. This supports positive z-buffer values. - // This is the case even for RHS coordinate input. - return m; - } - - static Matrix4 Ortho2D(T w, T h) - { - Matrix4 m; - m.M[0][0] = 2.0/w; - m.M[1][1] = -2.0/h; - m.M[0][3] = -1.0; - m.M[1][3] = 1.0; - m.M[2][2] = 0; - return m; - } -}; - -typedef Matrix4<float> Matrix4f; -typedef Matrix4<double> Matrix4d; - -//------------------------------------------------------------------------------------- -// ***** Matrix3 -// -// Matrix3 is a 3x3 matrix used for representing a rotation matrix. -// The matrix is stored in row-major order in memory, meaning that values -// of the first row are stored before the next one. -// -// The arrangement of the matrix is chosen to be in Right-Handed -// coordinate system and counterclockwise rotations when looking down -// the axis -// -// Transformation Order: -// - Transformations are applied from right to left, so the expression -// M1 * M2 * M3 * V means that the vector V is transformed by M3 first, -// followed by M2 and M1. -// -// Coordinate system: Right Handed -// -// Rotations: Counterclockwise when looking down the axis. All angles are in radians. - -template<typename T> -class SymMat3; - -template<class T> -class Matrix3 -{ - static const Matrix3 IdentityValue; - -public: - T M[3][3]; - - enum NoInitType { NoInit }; - - // Construct with no memory initialization. - Matrix3(NoInitType) { } - - // By default, we construct identity matrix. - Matrix3() - { - SetIdentity(); - } - - Matrix3(T m11, T m12, T m13, - T m21, T m22, T m23, - T m31, T m32, T m33) - { - M[0][0] = m11; M[0][1] = m12; M[0][2] = m13; - M[1][0] = m21; M[1][1] = m22; M[1][2] = m23; - M[2][0] = m31; M[2][1] = m32; M[2][2] = m33; - } - - /* - explicit Matrix3(const Quat<T>& q) - { - T ww = q.w*q.w; - T xx = q.x*q.x; - T yy = q.y*q.y; - T zz = q.z*q.z; - - M[0][0] = ww + xx - yy - zz; M[0][1] = 2 * (q.x*q.y - q.w*q.z); M[0][2] = 2 * (q.x*q.z + q.w*q.y); - M[1][0] = 2 * (q.x*q.y + q.w*q.z); M[1][1] = ww - xx + yy - zz; M[1][2] = 2 * (q.y*q.z - q.w*q.x); - M[2][0] = 2 * (q.x*q.z - q.w*q.y); M[2][1] = 2 * (q.y*q.z + q.w*q.x); M[2][2] = ww - xx - yy + zz; - } - */ - - explicit Matrix3(const Quat<T>& q) - { - const T tx = q.x+q.x, ty = q.y+q.y, tz = q.z+q.z; - const T twx = q.w*tx, twy = q.w*ty, twz = q.w*tz; - const T txx = q.x*tx, txy = q.x*ty, txz = q.x*tz; - const T tyy = q.y*ty, tyz = q.y*tz, tzz = q.z*tz; - M[0][0] = T(1) - (tyy + tzz); M[0][1] = txy - twz; M[0][2] = txz + twy; - M[1][0] = txy + twz; M[1][1] = T(1) - (txx + tzz); M[1][2] = tyz - twx; - M[2][0] = txz - twy; M[2][1] = tyz + twx; M[2][2] = T(1) - (txx + tyy); - } - - inline explicit Matrix3(T s) - { - M[0][0] = M[1][1] = M[2][2] = s; - M[0][1] = M[0][2] = M[1][0] = M[1][2] = M[2][0] = M[2][1] = 0; - } - - explicit Matrix3(const Pose<T>& p) - { - Matrix3 result(p.Rotation); - result.SetTranslation(p.Translation); - *this = result; - } - - // C-interop support - explicit Matrix3(const Matrix4<typename Math<T>::OtherFloatType> &src) - { - for (int i = 0; i < 3; i++) - for (int j = 0; j < 3; j++) - M[i][j] = (T)src.M[i][j]; - } - - // C-interop support. - Matrix3(const typename CompatibleTypes<Matrix3<T> >::Type& s) - { - static_assert(sizeof(s) == sizeof(Matrix3), "sizeof(s) == sizeof(Matrix3)"); - memcpy(M, s.M, sizeof(M)); - } - - operator const typename CompatibleTypes<Matrix3<T> >::Type () const - { - typename CompatibleTypes<Matrix3<T> >::Type result; - static_assert(sizeof(result) == sizeof(Matrix3), "sizeof(result) == sizeof(Matrix3)"); - memcpy(result.M, M, sizeof(M)); - return result; - } - - void ToString(char* dest, size_t destsize) const - { - size_t pos = 0; - for (int r=0; r<3; r++) - for (int c=0; c<3; c++) - pos += OVR_sprintf(dest+pos, destsize-pos, "%g ", M[r][c]); - } - - static Matrix3 FromString(const char* src) - { - Matrix3 result; - for (int r=0; r<3; r++) - for (int c=0; c<3; c++) - { - result.M[r][c] = (T)atof(src); - while (src && *src != ' ') - src++; - while (src && *src == ' ') - src++; - } - return result; - } - - static const Matrix3& Identity() { return IdentityValue; } - - void SetIdentity() - { - M[0][0] = M[1][1] = M[2][2] = 1; - M[0][1] = M[1][0] = M[2][0] = 0; - M[0][2] = M[1][2] = M[2][1] = 0; - } - - bool operator== (const Matrix3& b) const - { - bool isEqual = true; - for (int i = 0; i < 3; i++) - for (int j = 0; j < 3; j++) - isEqual &= (M[i][j] == b.M[i][j]); - - return isEqual; - } - - Matrix3 operator+ (const Matrix3& b) const - { - Matrix4<T> result(*this); - result += b; - return result; - } - - Matrix3& operator+= (const Matrix3& b) - { - for (int i = 0; i < 3; i++) - for (int j = 0; j < 3; j++) - M[i][j] += b.M[i][j]; - return *this; - } - - void operator= (const Matrix3& b) - { - for (int i = 0; i < 3; i++) - for (int j = 0; j < 3; j++) - M[i][j] = b.M[i][j]; - return; - } - - void operator= (const SymMat3<T>& b) - { - for (int i = 0; i < 3; i++) - for (int j = 0; j < 3; j++) - M[i][j] = 0; - - M[0][0] = b.v[0]; - M[0][1] = b.v[1]; - M[0][2] = b.v[2]; - M[1][1] = b.v[3]; - M[1][2] = b.v[4]; - M[2][2] = b.v[5]; - - return; - } - - Matrix3 operator- (const Matrix3& b) const - { - Matrix3 result(*this); - result -= b; - return result; - } - - Matrix3& operator-= (const Matrix3& b) - { - for (int i = 0; i < 3; i++) - for (int j = 0; j < 3; j++) - M[i][j] -= b.M[i][j]; - return *this; - } - - // Multiplies two matrices into destination with minimum copying. - static Matrix3& Multiply(Matrix3* d, const Matrix3& a, const Matrix3& b) - { - OVR_ASSERT((d != &a) && (d != &b)); - int i = 0; - do { - d->M[i][0] = a.M[i][0] * b.M[0][0] + a.M[i][1] * b.M[1][0] + a.M[i][2] * b.M[2][0]; - d->M[i][1] = a.M[i][0] * b.M[0][1] + a.M[i][1] * b.M[1][1] + a.M[i][2] * b.M[2][1]; - d->M[i][2] = a.M[i][0] * b.M[0][2] + a.M[i][1] * b.M[1][2] + a.M[i][2] * b.M[2][2]; - } while((++i) < 3); - - return *d; - } - - Matrix3 operator* (const Matrix3& b) const - { - Matrix3 result(Matrix3::NoInit); - Multiply(&result, *this, b); - return result; - } - - Matrix3& operator*= (const Matrix3& b) - { - return Multiply(this, Matrix3(*this), b); - } - - Matrix3 operator* (T s) const - { - Matrix3 result(*this); - result *= s; - return result; - } - - Matrix3& operator*= (T s) - { - for (int i = 0; i < 3; i++) - for (int j = 0; j < 3; j++) - M[i][j] *= s; - return *this; - } - - Vector3<T> operator* (const Vector3<T> &b) const - { - Vector3<T> result; - result.x = M[0][0]*b.x + M[0][1]*b.y + M[0][2]*b.z; - result.y = M[1][0]*b.x + M[1][1]*b.y + M[1][2]*b.z; - result.z = M[2][0]*b.x + M[2][1]*b.y + M[2][2]*b.z; - - return result; - } - - Matrix3 operator/ (T s) const - { - Matrix3 result(*this); - result /= s; - return result; - } - - Matrix3& operator/= (T s) - { - for (int i = 0; i < 3; i++) - for (int j = 0; j < 3; j++) - M[i][j] /= s; - return *this; - } - - Vector2<T> Transform(const Vector2<T>& v) const - { - const float rcpZ = 1.0f / (M[2][0] * v.x + M[2][1] * v.y + M[2][2]); - return Vector2<T>((M[0][0] * v.x + M[0][1] * v.y + M[0][2]) * rcpZ, - (M[1][0] * v.x + M[1][1] * v.y + M[1][2]) * rcpZ); - } - - Vector3<T> Transform(const Vector3<T>& v) const - { - return Vector3<T>(M[0][0] * v.x + M[0][1] * v.y + M[0][2] * v.z, - M[1][0] * v.x + M[1][1] * v.y + M[1][2] * v.z, - M[2][0] * v.x + M[2][1] * v.y + M[2][2] * v.z); - } - - Matrix3 Transposed() const - { - return Matrix3(M[0][0], M[1][0], M[2][0], - M[0][1], M[1][1], M[2][1], - M[0][2], M[1][2], M[2][2]); - } - - void Transpose() - { - *this = Transposed(); - } - - - T SubDet (const size_t* rows, const size_t* cols) const - { - return M[rows[0]][cols[0]] * (M[rows[1]][cols[1]] * M[rows[2]][cols[2]] - M[rows[1]][cols[2]] * M[rows[2]][cols[1]]) - - M[rows[0]][cols[1]] * (M[rows[1]][cols[0]] * M[rows[2]][cols[2]] - M[rows[1]][cols[2]] * M[rows[2]][cols[0]]) - + M[rows[0]][cols[2]] * (M[rows[1]][cols[0]] * M[rows[2]][cols[1]] - M[rows[1]][cols[1]] * M[rows[2]][cols[0]]); - } - - // M += a*b.t() - inline void Rank1Add(const Vector3<T> &a, const Vector3<T> &b) - { - M[0][0] += a.x*b.x; M[0][1] += a.x*b.y; M[0][2] += a.x*b.z; - M[1][0] += a.y*b.x; M[1][1] += a.y*b.y; M[1][2] += a.y*b.z; - M[2][0] += a.z*b.x; M[2][1] += a.z*b.y; M[2][2] += a.z*b.z; - } - - // M -= a*b.t() - inline void Rank1Sub(const Vector3<T> &a, const Vector3<T> &b) - { - M[0][0] -= a.x*b.x; M[0][1] -= a.x*b.y; M[0][2] -= a.x*b.z; - M[1][0] -= a.y*b.x; M[1][1] -= a.y*b.y; M[1][2] -= a.y*b.z; - M[2][0] -= a.z*b.x; M[2][1] -= a.z*b.y; M[2][2] -= a.z*b.z; - } - - inline Vector3<T> Col(int c) const - { - return Vector3<T>(M[0][c], M[1][c], M[2][c]); - } - - inline Vector3<T> Row(int r) const - { - return Vector3<T>(M[r][0], M[r][1], M[r][2]); - } - - inline T Determinant() const - { - const Matrix3<T>& m = *this; - T d; - - d = m.M[0][0] * (m.M[1][1]*m.M[2][2] - m.M[1][2] * m.M[2][1]); - d -= m.M[0][1] * (m.M[1][0]*m.M[2][2] - m.M[1][2] * m.M[2][0]); - d += m.M[0][2] * (m.M[1][0]*m.M[2][1] - m.M[1][1] * m.M[2][0]); - - return d; - } - - inline Matrix3<T> Inverse() const - { - Matrix3<T> a; - const Matrix3<T>& m = *this; - T d = Determinant(); - - assert(d != 0); - T s = T(1)/d; - - a.M[0][0] = s * (m.M[1][1] * m.M[2][2] - m.M[1][2] * m.M[2][1]); - a.M[1][0] = s * (m.M[1][2] * m.M[2][0] - m.M[1][0] * m.M[2][2]); - a.M[2][0] = s * (m.M[1][0] * m.M[2][1] - m.M[1][1] * m.M[2][0]); - - a.M[0][1] = s * (m.M[0][2] * m.M[2][1] - m.M[0][1] * m.M[2][2]); - a.M[1][1] = s * (m.M[0][0] * m.M[2][2] - m.M[0][2] * m.M[2][0]); - a.M[2][1] = s * (m.M[0][1] * m.M[2][0] - m.M[0][0] * m.M[2][1]); - - a.M[0][2] = s * (m.M[0][1] * m.M[1][2] - m.M[0][2] * m.M[1][1]); - a.M[1][2] = s * (m.M[0][2] * m.M[1][0] - m.M[0][0] * m.M[1][2]); - a.M[2][2] = s * (m.M[0][0] * m.M[1][1] - m.M[0][1] * m.M[1][0]); - - return a; - } - -}; - -typedef Matrix3<float> Matrix3f; -typedef Matrix3<double> Matrix3d; - -//------------------------------------------------------------------------------------- - -template<typename T> -class SymMat3 -{ -private: - typedef SymMat3<T> this_type; - -public: - typedef T Value_t; - // Upper symmetric - T v[6]; // _00 _01 _02 _11 _12 _22 - - inline SymMat3() {} - - inline explicit SymMat3(T s) - { - v[0] = v[3] = v[5] = s; - v[1] = v[2] = v[4] = 0; - } - - inline explicit SymMat3(T a00, T a01, T a02, T a11, T a12, T a22) - { - v[0] = a00; v[1] = a01; v[2] = a02; - v[3] = a11; v[4] = a12; - v[5] = a22; - } - - static inline int Index(unsigned int i, unsigned int j) - { - return (i <= j) ? (3*i - i*(i+1)/2 + j) : (3*j - j*(j+1)/2 + i); - } - - inline T operator()(int i, int j) const { return v[Index(i,j)]; } - - inline T &operator()(int i, int j) { return v[Index(i,j)]; } - - template<typename U> - inline SymMat3<U> CastTo() const - { - return SymMat3<U>(static_cast<U>(v[0]), static_cast<U>(v[1]), static_cast<U>(v[2]), - static_cast<U>(v[3]), static_cast<U>(v[4]), static_cast<U>(v[5])); - } - - inline this_type& operator+=(const this_type& b) - { - v[0]+=b.v[0]; - v[1]+=b.v[1]; - v[2]+=b.v[2]; - v[3]+=b.v[3]; - v[4]+=b.v[4]; - v[5]+=b.v[5]; - return *this; - } - - inline this_type& operator-=(const this_type& b) - { - v[0]-=b.v[0]; - v[1]-=b.v[1]; - v[2]-=b.v[2]; - v[3]-=b.v[3]; - v[4]-=b.v[4]; - v[5]-=b.v[5]; - - return *this; - } - - inline this_type& operator*=(T s) - { - v[0]*=s; - v[1]*=s; - v[2]*=s; - v[3]*=s; - v[4]*=s; - v[5]*=s; - - return *this; - } - - inline SymMat3 operator*(T s) const - { - SymMat3 d; - d.v[0] = v[0]*s; - d.v[1] = v[1]*s; - d.v[2] = v[2]*s; - d.v[3] = v[3]*s; - d.v[4] = v[4]*s; - d.v[5] = v[5]*s; - - return d; - } - - // Multiplies two matrices into destination with minimum copying. - static SymMat3& Multiply(SymMat3* d, const SymMat3& a, const SymMat3& b) - { - // _00 _01 _02 _11 _12 _22 - - d->v[0] = a.v[0] * b.v[0]; - d->v[1] = a.v[0] * b.v[1] + a.v[1] * b.v[3]; - d->v[2] = a.v[0] * b.v[2] + a.v[1] * b.v[4]; - - d->v[3] = a.v[3] * b.v[3]; - d->v[4] = a.v[3] * b.v[4] + a.v[4] * b.v[5]; - - d->v[5] = a.v[5] * b.v[5]; - - return *d; - } - - inline T Determinant() const - { - const this_type& m = *this; - T d; - - d = m(0,0) * (m(1,1)*m(2,2) - m(1,2) * m(2,1)); - d -= m(0,1) * (m(1,0)*m(2,2) - m(1,2) * m(2,0)); - d += m(0,2) * (m(1,0)*m(2,1) - m(1,1) * m(2,0)); - - return d; - } - - inline this_type Inverse() const - { - this_type a; - const this_type& m = *this; - T d = Determinant(); - - assert(d != 0); - T s = T(1)/d; - - a(0,0) = s * (m(1,1) * m(2,2) - m(1,2) * m(2,1)); - - a(0,1) = s * (m(0,2) * m(2,1) - m(0,1) * m(2,2)); - a(1,1) = s * (m(0,0) * m(2,2) - m(0,2) * m(2,0)); - - a(0,2) = s * (m(0,1) * m(1,2) - m(0,2) * m(1,1)); - a(1,2) = s * (m(0,2) * m(1,0) - m(0,0) * m(1,2)); - a(2,2) = s * (m(0,0) * m(1,1) - m(0,1) * m(1,0)); - - return a; - } - - inline T Trace() const { return v[0] + v[3] + v[5]; } - - // M = a*a.t() - inline void Rank1(const Vector3<T> &a) - { - v[0] = a.x*a.x; v[1] = a.x*a.y; v[2] = a.x*a.z; - v[3] = a.y*a.y; v[4] = a.y*a.z; - v[5] = a.z*a.z; - } - - // M += a*a.t() - inline void Rank1Add(const Vector3<T> &a) - { - v[0] += a.x*a.x; v[1] += a.x*a.y; v[2] += a.x*a.z; - v[3] += a.y*a.y; v[4] += a.y*a.z; - v[5] += a.z*a.z; - } - - // M -= a*a.t() - inline void Rank1Sub(const Vector3<T> &a) - { - v[0] -= a.x*a.x; v[1] -= a.x*a.y; v[2] -= a.x*a.z; - v[3] -= a.y*a.y; v[4] -= a.y*a.z; - v[5] -= a.z*a.z; - } -}; - -typedef SymMat3<float> SymMat3f; -typedef SymMat3<double> SymMat3d; - -template<typename T> -inline Matrix3<T> operator*(const SymMat3<T>& a, const SymMat3<T>& b) -{ - #define AJB_ARBC(r,c) (a(r,0)*b(0,c)+a(r,1)*b(1,c)+a(r,2)*b(2,c)) - return Matrix3<T>( - AJB_ARBC(0,0), AJB_ARBC(0,1), AJB_ARBC(0,2), - AJB_ARBC(1,0), AJB_ARBC(1,1), AJB_ARBC(1,2), - AJB_ARBC(2,0), AJB_ARBC(2,1), AJB_ARBC(2,2)); - #undef AJB_ARBC -} - -template<typename T> -inline Matrix3<T> operator*(const Matrix3<T>& a, const SymMat3<T>& b) -{ - #define AJB_ARBC(r,c) (a(r,0)*b(0,c)+a(r,1)*b(1,c)+a(r,2)*b(2,c)) - return Matrix3<T>( - AJB_ARBC(0,0), AJB_ARBC(0,1), AJB_ARBC(0,2), - AJB_ARBC(1,0), AJB_ARBC(1,1), AJB_ARBC(1,2), - AJB_ARBC(2,0), AJB_ARBC(2,1), AJB_ARBC(2,2)); - #undef AJB_ARBC -} - -//------------------------------------------------------------------------------------- -// ***** Angle - -// Cleanly representing the algebra of 2D rotations. -// The operations maintain the angle between -Pi and Pi, the same range as atan2. - -template<class T> -class Angle -{ -public: - enum AngularUnits - { - Radians = 0, - Degrees = 1 - }; - - Angle() : a(0) {} - - // Fix the range to be between -Pi and Pi - Angle(T a_, AngularUnits u = Radians) : a((u == Radians) ? a_ : a_*((T)MATH_DOUBLE_DEGREETORADFACTOR)) { FixRange(); } - - T Get(AngularUnits u = Radians) const { return (u == Radians) ? a : a*((T)MATH_DOUBLE_RADTODEGREEFACTOR); } - void Set(const T& x, AngularUnits u = Radians) { a = (u == Radians) ? x : x*((T)MATH_DOUBLE_DEGREETORADFACTOR); FixRange(); } - int Sign() const { if (a == 0) return 0; else return (a > 0) ? 1 : -1; } - T Abs() const { return (a > 0) ? a : -a; } - - bool operator== (const Angle& b) const { return a == b.a; } - bool operator!= (const Angle& b) const { return a != b.a; } -// bool operator< (const Angle& b) const { return a < a.b; } -// bool operator> (const Angle& b) const { return a > a.b; } -// bool operator<= (const Angle& b) const { return a <= a.b; } -// bool operator>= (const Angle& b) const { return a >= a.b; } -// bool operator= (const T& x) { a = x; FixRange(); } - - // These operations assume a is already between -Pi and Pi. - Angle& operator+= (const Angle& b) { a = a + b.a; FastFixRange(); return *this; } - Angle& operator+= (const T& x) { a = a + x; FixRange(); return *this; } - Angle operator+ (const Angle& b) const { Angle res = *this; res += b; return res; } - Angle operator+ (const T& x) const { Angle res = *this; res += x; return res; } - Angle& operator-= (const Angle& b) { a = a - b.a; FastFixRange(); return *this; } - Angle& operator-= (const T& x) { a = a - x; FixRange(); return *this; } - Angle operator- (const Angle& b) const { Angle res = *this; res -= b; return res; } - Angle operator- (const T& x) const { Angle res = *this; res -= x; return res; } - - T Distance(const Angle& b) { T c = fabs(a - b.a); return (c <= ((T)MATH_DOUBLE_PI)) ? c : ((T)MATH_DOUBLE_TWOPI) - c; } - -private: - - // The stored angle, which should be maintained between -Pi and Pi - T a; - - // Fixes the angle range to [-Pi,Pi], but assumes no more than 2Pi away on either side - inline void FastFixRange() - { - if (a < -((T)MATH_DOUBLE_PI)) - a += ((T)MATH_DOUBLE_TWOPI); - else if (a > ((T)MATH_DOUBLE_PI)) - a -= ((T)MATH_DOUBLE_TWOPI); - } - - // Fixes the angle range to [-Pi,Pi] for any given range, but slower then the fast method - inline void FixRange() - { - // do nothing if the value is already in the correct range, since fmod call is expensive - if (a >= -((T)MATH_DOUBLE_PI) && a <= ((T)MATH_DOUBLE_PI)) - return; - a = fmod(a,((T)MATH_DOUBLE_TWOPI)); - if (a < -((T)MATH_DOUBLE_PI)) - a += ((T)MATH_DOUBLE_TWOPI); - else if (a > ((T)MATH_DOUBLE_PI)) - a -= ((T)MATH_DOUBLE_TWOPI); - } -}; - - -typedef Angle<float> Anglef; -typedef Angle<double> Angled; - - -//------------------------------------------------------------------------------------- -// ***** Plane - -// Consists of a normal vector and distance from the origin where the plane is located. - -template<class T> -class Plane -{ -public: - Vector3<T> N; - T D; - - Plane() : D(0) {} - - // Normals must already be normalized - Plane(const Vector3<T>& n, T d) : N(n), D(d) {} - Plane(T x, T y, T z, T d) : N(x,y,z), D(d) {} - - // construct from a point on the plane and the normal - Plane(const Vector3<T>& p, const Vector3<T>& n) : N(n), D(-(p * n)) {} - - // Find the point to plane distance. The sign indicates what side of the plane the point is on (0 = point on plane). - T TestSide(const Vector3<T>& p) const - { - return (N.Dot(p)) + D; - } - - Plane<T> Flipped() const - { - return Plane(-N, -D); - } - - void Flip() - { - N = -N; - D = -D; - } - - bool operator==(const Plane<T>& rhs) const - { - return (this->D == rhs.D && this->N == rhs.N); - } -}; - -typedef Plane<float> Planef; -typedef Plane<double> Planed; - - -} // Namespace OVR - -#endif diff --git a/LibOVR/Src/Kernel/OVR_Nullptr.h b/LibOVR/Src/Kernel/OVR_Nullptr.h deleted file mode 100644 index a09f446..0000000 --- a/LibOVR/Src/Kernel/OVR_Nullptr.h +++ /dev/null @@ -1,150 +0,0 @@ -/************************************************************************************ - -PublicHeader: OVR_Kernel.h -Filename : OVR_Nullptr.h -Content : Implements C++11 nullptr for the case that the compiler doesn't. -Created : June 19, 2014 -Notes : - -Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); -you may not use the Oculus VR Rift SDK except in compliance with the License, -which is provided at the time of installation or download, or which -otherwise accompanies this software in either electronic or hard copy form. - -You may obtain a copy of the License at - -http://www.oculusvr.com/licenses/LICENSE-3.2 - -Unless required by applicable law or agreed to in writing, the Oculus VR SDK -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -************************************************************************************/ - -#ifndef OVR_Nullptr_h -#define OVR_Nullptr_h - -#pragma once - -#include "OVR_Types.h" - - -//----------------------------------------------------------------------------------- -// ***** OVR_HAVE_std_nullptr_t -// -// Identifies if <cstddef.h> includes std::nullptr_t. -// -#if !defined(OVR_HAVE_std_nullptr_t) && defined(OVR_CPP11_ENABLED) - #if defined(OVR_STDLIB_LIBCPP) - #define OVR_HAVE_std_nullptr_t 1 - #elif defined(OVR_STDLIB_LIBSTDCPP) - #if (__GLIBCXX__ >= 20110325) && (__GLIBCXX__ != 20110428) && (__GLIBCXX__ != 20120702) - #define OVR_HAVE_std_nullptr_t 1 - #endif - #elif defined(_MSC_VER) && (_MSC_VER >= 1600) // VS2010+ - #define OVR_HAVE_std_nullptr_t 1 - #elif defined(__clang__) - #define OVR_HAVE_std_nullptr_t 1 - #elif defined(OVR_CPP_GNUC) && (OVR_CC_VERSION >= 406) // GCC 4.6+ - #define OVR_HAVE_std_nullptr_t 1 - #endif -#endif - - -//----------------------------------------------------------------------------------- -// ***** nullptr / std::nullptr_t -// -// Declares and defines nullptr and related types. -// -#if defined(OVR_CPP_NO_NULLPTR) - namespace std - { - class nullptr_t - { - public: - template <typename T> - operator T*() const - { return 0; } - - template <typename C, typename T> - operator T C::*() const - { return 0; } - - #if OVR_CPP_NO_EXPLICIT_CONVERSION_OPERATORS - typedef void* (nullptr_t::*bool_)() const; // 4.12,p1. We can't portably use operator bool(){ return false; } because bool - operator bool_() const // is convertable to int which breaks other required functionality. - { return false; } - #else - operator bool() const - { return false; } - #endif - - private: - void operator&() const; // 5.2.10,p9 - }; - - inline nullptr_t nullptr_get() - { - nullptr_t n = { }; - return n; - } - - #if !defined(nullptr) - #define nullptr nullptr_get() - #endif - - } // namespace std - - - // 5.9,p2 p4 - // 13.6, p13 - template <typename T> - inline bool operator==(T* pT, const std::nullptr_t) - { return pT == 0; } - - template <typename T> - inline bool operator==(const std::nullptr_t, T* pT) - { return pT == 0; } - - template <typename T, typename U> - inline bool operator==(const std::nullptr_t, T U::* pU) - { return pU == 0; } - - template <typename T, typename U> - inline bool operator==(T U::* pTU, const std::nullptr_t) - { return pTU == 0; } - - inline bool operator==(const std::nullptr_t, const std::nullptr_t) - { return true; } - - inline bool operator!=(const std::nullptr_t, const std::nullptr_t) - { return false; } - - inline bool operator<(const std::nullptr_t, const std::nullptr_t) - { return false; } - - inline bool operator<=(const std::nullptr_t, const std::nullptr_t) - { return true; } - - inline bool operator>(const std::nullptr_t, const std::nullptr_t) - { return false; } - - inline bool operator>=(const std::nullptr_t, const std::nullptr_t) - { return true; } - - using std::nullptr_t; - using std::nullptr_get; - -// Some compilers natively support C++11 nullptr but the standard library being used -// doesn't declare std::nullptr_t, in which case we provide one ourselves. -#elif !defined(OVR_HAVE_std_nullptr_t) && !defined(OVR_CPP_NO_DECLTYPE) - namespace std { typedef decltype(nullptr) nullptr_t; } -#endif - - -#endif - diff --git a/LibOVR/Src/Kernel/OVR_Observer.h b/LibOVR/Src/Kernel/OVR_Observer.h deleted file mode 100644 index 76b4be6..0000000 --- a/LibOVR/Src/Kernel/OVR_Observer.h +++ /dev/null @@ -1,457 +0,0 @@ -/************************************************************************************ - -PublicHeader: Kernel -Filename : OVR_Observer.h -Content : Observer pattern -Created : June 20, 2014 -Author : Chris Taylor - -Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); -you may not use the Oculus VR Rift SDK except in compliance with the License, -which is provided at the time of installation or download, or which -otherwise accompanies this software in either electronic or hard copy form. - -You may obtain a copy of the License at - -http://www.oculusvr.com/licenses/LICENSE-3.2 - -Unless required by applicable law or agreed to in writing, the Oculus VR SDK -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -************************************************************************************/ - -#ifndef OVR_Observer_h -#define OVR_Observer_h - -#include "OVR_Types.h" -#include "OVR_Atomic.h" -#include "OVR_RefCount.h" -#include "OVR_Delegates.h" -#include "OVR_Array.h" -#include "OVR_String.h" -#include "OVR_Hash.h" - -namespace OVR { - -template<class DelegateT> class Observer; -template<class DelegateT> class ObserverScope; -template<class DelegateT> class ObserverHash; - - -//----------------------------------------------------------------------------- -// Observer pattern - -// An Observer will observe a Subject. The Subject can emit callbacks that get -// serviced by the Observers. - -// The trickiest part of this is the shutdown code. -// To simplify shutdown, the Observer is a reference-counted object divorced -// from the handler that is called. To avoid misuse, the ObserverScope object -// is provided to ensure that the Shutdown() method is called when it goes out -// of scope. - -// The Observer<> class doubles as the subject class. -// To avoid misuse, assertions are added if a subject tries to observe, or if -// an observer tries to be watched. - -/* - Usage example: - - Say we want to invoke a handler with the signature: - - void MyHandler(int i, bool b); - - The corresponding delegate type is: - - typedef Delegate2<void, int, bool> Handler; - - Note: The return value will be ignored for the Observer pattern. - - For this example there are two classes, one that emits events and another - that listens for events: -*/ - -/* - Event emitter example: - - class MyEmitter - { - ObserverScope<Handler> TheSubject; - - public: - void ClearAllListeners() - { - TheSubject.ReleaseAll(); - } - - void CallListeners(int x, bool y) - { - TheSubject->Call(x, y); - } - - Observer<Handler>* GetSubject() - { - return TheSubject; - } - }; -*/ - -/* - Event listener example: - - class MyListener - { - ObserverScope<Handler> TheObserver; - - void OnEvent(int x, bool y) - { - // Handle event here - } - - public: - MyListener() - { - TheObserver.SetHandler( - Handler::FromMember<MyListener, &MyListener::OnEvent>(this) - ); - } - - void ClearListener() - { - TheObserver.ReleaseAll(); - } - - void ListenTo(Observer<Handler>* emitter) - { - TheObserver->Observe(emitter); - } - }; -*/ - -/* - Usage example: - - MyListener listener; - MyEmitter emitter; - - // To listen to an emitter, - listener.ListenTo(emitter.GetSubject()); - - // To call the listeners, - emitter.CallListeners(22, true); -*/ - -template<class DelegateT> -class Observer : public RefCountBase< Observer<DelegateT> > -{ - friend class ObserverScope<DelegateT>; - friend class ObserverHash<DelegateT>; - -public: - typedef Observer<DelegateT> ThisType; - typedef DelegateT Handler; - -protected: - bool IsShutdown; // Flag to indicate that the object went out of scope - mutable Lock TheLock; // Lock to synchronize calls and shutdown - Array< Ptr< ThisType > > References; // List of observed or observing objects - Handler TheHandler; // Observer-only: Handler for callbacks - - Observer() : - IsShutdown(false) - { - TheHandler.Invalidate(); - } - Observer(Handler handler) : - IsShutdown(false), - TheHandler(handler) - { - } - ~Observer() - { - OVR_ASSERT(References.GetSizeI() == 0); - } - -public: - void SetHandler(Handler handler) - { - OVR_ASSERT(References.GetSizeI() == 0); - TheHandler = handler; - } - - // Release references and prevent further actions - void Shutdown() - { - Lock::Locker locker(&TheLock); - IsShutdown = true; - References.ClearAndRelease(); - } - - // Get count of references held - int GetSizeI() const - { - Lock::Locker locker(&TheLock); - return References.GetSizeI(); - } - - // Observe a subject - bool Observe(ThisType *subject) - { - OVR_ASSERT(TheHandler.IsValid()); - - if (!subject) - { - return false; - } - - Lock::Locker locker(&TheLock); - - if (IsShutdown) - { - return false; - } - - if (!subject->SubjectAddObserver(this)) - { - return false; - } - - References.PushBack(subject); - return true; - } - -protected: - // Subject function: AddObserver() - // Returns true if the observer was added - bool SubjectAddObserver(ThisType* observer) - { - OVR_ASSERT(!TheHandler.IsValid()); - - if (!observer) - { - return true; - } - - Lock::Locker locker(&TheLock); - - if (IsShutdown) - { - return false; - } - - const int count = References.GetSizeI(); - for (int i = 0; i < count; ++i) - { - if (References[i] == observer) - { - // Already watched - return true; - } - } - - References.PushBack(observer); - - return true; - } - -public: - // Subject function: Call() -#define OVR_OBSERVER_CALL_BODY(params) \ - bool callSuccess = false; \ - Lock::Locker locker(&TheLock); \ - int count = References.GetSizeI(); \ - for (int i = 0; i < count; ++i) \ - { \ - if (!References[i]->IsShutdown) \ - { \ - OVR_ASSERT(References[i]->TheHandler.IsValid()); \ - References[i]->TheHandler params; \ - callSuccess = true; \ - } \ - if (References[i]->IsShutdown) \ - { \ - References.RemoveAt(i); \ - --i; --count; \ - } \ - } \ - return callSuccess; - - // Call: Various parameter counts - // Returns true if a call was made - bool Call() - { - OVR_OBSERVER_CALL_BODY(()) - } - template<class Param1> - bool Call(Param1& p1) - { - OVR_OBSERVER_CALL_BODY((p1)) - } - template<class Param1> - bool Call(Param1* p1) - { - OVR_OBSERVER_CALL_BODY((p1)) - } - template<class Param1, class Param2> - bool Call(Param1& p1, Param2& p2) - { - OVR_OBSERVER_CALL_BODY((p1, p2)) - } - template<class Param1, class Param2> - bool Call(Param1* p1, Param2* p2) - { - OVR_OBSERVER_CALL_BODY((p1, p2)) - } - template<class Param1, class Param2, class Param3> - bool Call(Param1& p1, Param2& p2, Param3& p3) - { - OVR_OBSERVER_CALL_BODY((p1, p2, p3)) - } - template<class Param1, class Param2, class Param3> - bool Call(Param1* p1, Param2* p2, Param3* p3) - { - OVR_OBSERVER_CALL_BODY((p1, p2, p3)) - } - -#undef OVR_OBSERVER_CALL_BODY -}; - - -//----------------------------------------------------------------------------- -// ObserverScope - -// Scoped shutdown of the Observer object -template<class DelegateT> -class ObserverScope : public NewOverrideBase -{ - Ptr< Observer<DelegateT> > TheObserver; - DelegateT TheHandler; - - void Shutdown() - { - if (TheObserver) - { - TheObserver->Shutdown(); - TheObserver.Clear(); - } - } - -public: - ObserverScope() - { - TheObserver = *new Observer<DelegateT>; - } - ~ObserverScope() - { - Shutdown(); - } - - // Release all references and recreate it - void ReleaseAll() - { - Shutdown(); - TheObserver = *new Observer<DelegateT>; - if (TheHandler.IsValid()) - { - TheObserver->SetHandler(TheHandler); - } - } - - void SetHandler(DelegateT handler) - { - TheHandler = handler; - TheObserver->SetHandler(handler); - } - - Observer<DelegateT>* GetPtr() - { - return TheObserver.GetPtr(); - } - Observer<DelegateT>* operator->() - { - return TheObserver.GetPtr(); - } - const Observer<DelegateT>* operator->() const - { - return TheObserver.GetPtr(); - } - operator Observer<DelegateT>*() - { - return TheObserver.GetPtr(); - } -}; - - -//----------------------------------------------------------------------------- -// ObserverHash - -// A hash containing Observers -template<class DelegateT> -class ObserverHash : public NewOverrideBase -{ -public: - ObserverHash() {} - ~ObserverHash() {Clear();} - void Clear() - { - Lock::Locker locker(&TheLock); - typename OVR::Hash< String, Ptr<Observer<DelegateT> >, OVR::String::HashFunctor >::Iterator it = _Hash.Begin(); - for( it = _Hash.Begin(); it != _Hash.End(); ++it ) - { - Ptr<Observer<DelegateT> > o = it->Second; - o->Shutdown(); - } - } - - Ptr<Observer<DelegateT> > GetSubject(OVR::String key) - { - Lock::Locker locker(&TheLock); - Ptr<Observer<DelegateT> > *o = _Hash.Get(key); - if (o) - return (*o); - return NULL; - } - - // Add handler to new observer with implicit creation of subject. - void AddObserverToSubject(OVR::String key, Observer<DelegateT> *observer) - { - Lock::Locker locker(&TheLock); - Ptr<Observer<DelegateT> > *subjectPtr = _Hash.Get(key); - - if (subjectPtr==NULL) - { - Ptr<Observer<DelegateT> > subject = *new Observer<DelegateT>(); - _Hash.Add(key, subject); - observer->Observe(subject); - } - else - { - observer->Observe(*subjectPtr); - } - } - - void RemoveSubject(OVR::String key) - { - Lock::Locker locker(&TheLock); - Ptr<Observer<DelegateT> > *subjectPtr = _Hash.Get(key); - if (subjectPtr!=NULL) - { - (*subjectPtr)->Shutdown(); - _Hash.Remove(key); - } - } - -protected: - OVR::Hash< OVR::String, Ptr<Observer<DelegateT> >, OVR::String::HashFunctor > _Hash; - Lock TheLock; // Lock to synchronize calls and shutdown -}; - - -} // namespace OVR - -#endif // OVR_Observer_h diff --git a/LibOVR/Src/Kernel/OVR_RefCount.cpp b/LibOVR/Src/Kernel/OVR_RefCount.cpp deleted file mode 100644 index f761811..0000000 --- a/LibOVR/Src/Kernel/OVR_RefCount.cpp +++ /dev/null @@ -1,111 +0,0 @@ -/************************************************************************************ - -Filename : OVR_RefCount.cpp -Content : Reference counting implementation -Created : September 19, 2012 -Notes : - -Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); -you may not use the Oculus VR Rift SDK except in compliance with the License, -which is provided at the time of installation or download, or which -otherwise accompanies this software in either electronic or hard copy form. - -You may obtain a copy of the License at - -http://www.oculusvr.com/licenses/LICENSE-3.2 - -Unless required by applicable law or agreed to in writing, the Oculus VR SDK -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -************************************************************************************/ - -#include "OVR_RefCount.h" -#include "OVR_Atomic.h" -#include "OVR_Log.h" - -namespace OVR { - -#ifdef OVR_CC_ARM -void* ReturnArg0(void* p) -{ - return p; -} -#endif - -// ***** Reference Count Base implementation - -RefCountImplCore::~RefCountImplCore() -{ - // RefCount can be either 1 or 0 here. - // 0 if Release() was properly called. - // 1 if the object was declared on stack or as an aggregate. - OVR_ASSERT(RefCount <= 1); -} - -#ifdef OVR_BUILD_DEBUG -void RefCountImplCore::reportInvalidDelete(void *pmem) -{ - OVR_DEBUG_LOG( - ("Invalid delete call on ref-counted object at %p. Please use Release()", pmem)); - OVR_ASSERT(0); -} -#endif - -RefCountNTSImplCore::~RefCountNTSImplCore() -{ - // RefCount can be either 1 or 0 here. - // 0 if Release() was properly called. - // 1 if the object was declared on stack or as an aggregate. - OVR_ASSERT(RefCount <= 1); -} - -#ifdef OVR_BUILD_DEBUG -void RefCountNTSImplCore::reportInvalidDelete(void *pmem) -{ - OVR_DEBUG_LOG( - ("Invalid delete call on ref-counted object at %p. Please use Release()", pmem)); - OVR_ASSERT(0); -} -#endif - - -// *** Thread-Safe RefCountImpl - -void RefCountImpl::AddRef() -{ - AtomicOps<int>::ExchangeAdd_NoSync(&RefCount, 1); -} -void RefCountImpl::Release() -{ - if ((AtomicOps<int>::ExchangeAdd_NoSync(&RefCount, -1) - 1) == 0) - delete this; -} - -// *** Thread-Safe RefCountVImpl w/virtual AddRef/Release - -void RefCountVImpl::AddRef() -{ - AtomicOps<int>::ExchangeAdd_NoSync(&RefCount, 1); -} -void RefCountVImpl::Release() -{ - if ((AtomicOps<int>::ExchangeAdd_NoSync(&RefCount, -1) - 1) == 0) - delete this; -} - -// *** NON-Thread-Safe RefCountImpl - -void RefCountNTSImpl::Release() const -{ - RefCount--; - if (RefCount == 0) - delete this; -} - - -} // OVR diff --git a/LibOVR/Src/Kernel/OVR_RefCount.h b/LibOVR/Src/Kernel/OVR_RefCount.h deleted file mode 100644 index 33c6f37..0000000 --- a/LibOVR/Src/Kernel/OVR_RefCount.h +++ /dev/null @@ -1,565 +0,0 @@ -/************************************************************************************ - -PublicHeader: Kernel -Filename : OVR_RefCount.h -Content : Reference counting implementation headers -Created : September 19, 2012 -Notes : - -Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); -you may not use the Oculus VR Rift SDK except in compliance with the License, -which is provided at the time of installation or download, or which -otherwise accompanies this software in either electronic or hard copy form. - -You may obtain a copy of the License at - -http://www.oculusvr.com/licenses/LICENSE-3.2 - -Unless required by applicable law or agreed to in writing, the Oculus VR SDK -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -************************************************************************************/ - -#ifndef OVR_RefCount_h -#define OVR_RefCount_h - -#include "OVR_Types.h" -#include "OVR_Allocator.h" - -namespace OVR { - -//----------------------------------------------------------------------------------- -// ***** Reference Counting - -// There are three types of reference counting base classes: -// -// RefCountBase - Provides thread-safe reference counting (Default). -// RefCountBaseNTS - Non Thread Safe version of reference counting. - - -// ***** Declared classes - -template<class C> -class RefCountBase; -template<class C> -class RefCountBaseNTS; - -class RefCountImpl; -class RefCountNTSImpl; - - -//----------------------------------------------------------------------------------- -// ***** Implementation For Reference Counting - -// RefCountImplCore holds RefCount value and defines a few utility -// functions shared by all implementations. - -class RefCountImplCore -{ -protected: - volatile int RefCount; - -public: - // RefCountImpl constructor always initializes RefCount to 1 by default. - OVR_FORCE_INLINE RefCountImplCore() : RefCount(1) { } - - // Need virtual destructor - // This: 1. Makes sure the right destructor's called. - // 2. Makes us have VTable, necessary if we are going to have format needed by InitNewMem() - virtual ~RefCountImplCore(); - - // Debug method only. - int GetRefCount() const { return RefCount; } - - // This logic is used to detect invalid 'delete' calls of reference counted - // objects. Direct delete calls are not allowed on them unless they come in - // internally from Release. -#ifdef OVR_BUILD_DEBUG - static void OVR_CDECL reportInvalidDelete(void *pmem); - inline static void checkInvalidDelete(RefCountImplCore *pmem) - { - if (pmem->RefCount != 0) - reportInvalidDelete(pmem); - } -#else - inline static void checkInvalidDelete(RefCountImplCore *) { } -#endif - - // Base class ref-count content should not be copied. - void operator = (const RefCountImplCore &) { } -}; - -class RefCountNTSImplCore -{ -protected: - mutable int RefCount; - -public: - // RefCountImpl constructor always initializes RefCount to 1 by default. - OVR_FORCE_INLINE RefCountNTSImplCore() : RefCount(1) { } - - // Need virtual destructor - // This: 1. Makes sure the right destructor's called. - // 2. Makes us have VTable, necessary if we are going to have format needed by InitNewMem() - virtual ~RefCountNTSImplCore(); - - // Debug method only. - int GetRefCount() const { return RefCount; } - - // This logic is used to detect invalid 'delete' calls of reference counted - // objects. Direct delete calls are not allowed on them unless they come in - // internally from Release. -#ifdef OVR_BUILD_DEBUG - static void OVR_CDECL reportInvalidDelete(void *pmem); - OVR_FORCE_INLINE static void checkInvalidDelete(RefCountNTSImplCore *pmem) - { - if (pmem->RefCount != 0) - reportInvalidDelete(pmem); - } -#else - OVR_FORCE_INLINE static void checkInvalidDelete(RefCountNTSImplCore *) { } -#endif - - // Base class ref-count content should not be copied. - void operator = (const RefCountNTSImplCore &) { } -}; - - - -// RefCountImpl provides Thread-Safe implementation of reference counting, so -// it should be used by default in most places. - -class RefCountImpl : public RefCountImplCore -{ -public: - // Thread-Safe Ref-Count Implementation. - void AddRef(); - void Release(); -}; - -// RefCountVImpl provides Thread-Safe implementation of reference counting, plus, -// virtual AddRef and Release. - -class RefCountVImpl : virtual public RefCountImplCore -{ -public: - // Thread-Safe Ref-Count Implementation. - virtual void AddRef(); - virtual void Release(); -}; - - -// RefCountImplNTS provides Non-Thread-Safe implementation of reference counting, -// which is slightly more efficient since it doesn't use atomics. - -class RefCountNTSImpl : public RefCountNTSImplCore -{ -public: - OVR_FORCE_INLINE void AddRef() const { RefCount++; } - void Release() const; -}; - - - -// RefCountBaseStatImpl<> is a common class that adds new/delete override with Stat tracking -// to the reference counting implementation. Base must be one of the RefCountImpl classes. - -template<class Base> -class RefCountBaseStatImpl : public Base -{ -public: - RefCountBaseStatImpl() { } - - // *** Override New and Delete - - // DOM-IGNORE-BEGIN - // Undef new temporarily if it is being redefined -#ifdef OVR_DEFINE_NEW -#undef new -#endif - -#ifdef OVR_BUILD_DEBUG - // Custom check used to detect incorrect calls of 'delete' on ref-counted objects. - #define OVR_REFCOUNTALLOC_CHECK_DELETE(class_name, p) \ - do {if (p) Base::checkInvalidDelete((class_name*)p); } while(0) -#else - #define OVR_REFCOUNTALLOC_CHECK_DELETE(class_name, p) -#endif - - // Redefine all new & delete operators. - OVR_MEMORY_REDEFINE_NEW_IMPL(Base, OVR_REFCOUNTALLOC_CHECK_DELETE) - -#undef OVR_REFCOUNTALLOC_CHECK_DELETE - -#ifdef OVR_DEFINE_NEW -#define new OVR_DEFINE_NEW -#endif - // OVR_BUILD_DEFINE_NEW - // DOM-IGNORE-END -}; - - -template<class Base> -class RefCountBaseStatVImpl : virtual public Base -{ -public: - RefCountBaseStatVImpl() { } - - // *** Override New and Delete - - // DOM-IGNORE-BEGIN - // Undef new temporarily if it is being redefined -#ifdef OVR_DEFINE_NEW -#undef new -#endif - -#define OVR_REFCOUNTALLOC_CHECK_DELETE(class_name, p) - - // Redefine all new & delete operators. - OVR_MEMORY_REDEFINE_NEW_IMPL(Base, OVR_REFCOUNTALLOC_CHECK_DELETE) - -#undef OVR_REFCOUNTALLOC_CHECK_DELETE - -#ifdef OVR_DEFINE_NEW -#define new OVR_DEFINE_NEW -#endif - // OVR_BUILD_DEFINE_NEW - // DOM-IGNORE-END -}; - - - -//----------------------------------------------------------------------------------- -// *** End user RefCountBase<> classes - - -// RefCountBase is a base class for classes that require thread-safe reference -// counting; it also overrides the new and delete operators to use MemoryHeap. -// -// Reference counted objects start out with RefCount value of 1. Further lifetime -// management is done through the AddRef() and Release() methods, typically -// hidden by Ptr<>. - -template<class C> -class RefCountBase : public RefCountBaseStatImpl<RefCountImpl> -{ -public: - // Constructor. - OVR_FORCE_INLINE RefCountBase() : RefCountBaseStatImpl<RefCountImpl>() { } -}; - -// RefCountBaseV is the same as RefCountBase but with virtual AddRef/Release - -template<class C> -class RefCountBaseV : virtual public RefCountBaseStatVImpl<RefCountVImpl> -{ -public: - // Constructor. - OVR_FORCE_INLINE RefCountBaseV() : RefCountBaseStatVImpl<RefCountVImpl>() { } -}; - - -// RefCountBaseNTS is a base class for classes that require Non-Thread-Safe reference -// counting; it also overrides the new and delete operators to use MemoryHeap. -// This class should only be used if all pointers to it are known to be assigned, -// destroyed and manipulated within one thread. -// -// Reference counted objects start out with RefCount value of 1. Further lifetime -// management is done through the AddRef() and Release() methods, typically -// hidden by Ptr<>. - -template<class C> -class RefCountBaseNTS : public RefCountBaseStatImpl<RefCountNTSImpl> -{ -public: - // Constructor. - OVR_FORCE_INLINE RefCountBaseNTS() : RefCountBaseStatImpl<RefCountNTSImpl>() { } -}; - -//----------------------------------------------------------------------------------- -// ***** Pickable template pointer -enum PickType { PickValue }; - -template <typename T> -class Pickable -{ -public: - Pickable() : pV(NULL) {} - explicit Pickable(T* p) : pV(p) {} - Pickable(T* p, PickType) : pV(p) - { - OVR_ASSERT(pV); - if (pV) - pV->AddRef(); - } - template <typename OT> - Pickable(const Pickable<OT>& other) : pV(other.GetPtr()) {} - -public: - Pickable& operator =(const Pickable& other) - { - OVR_ASSERT(pV == NULL); - pV = other.pV; - // Extra check. - //other.pV = NULL; - return *this; - } - -public: - T* GetPtr() const { return pV; } - T* operator->() const - { - return pV; - } - T& operator*() const - { - OVR_ASSERT(pV); - return *pV; - } - -private: - T* pV; -}; - -template <typename T> -OVR_FORCE_INLINE -Pickable<T> MakePickable(T* p) -{ - return Pickable<T>(p); -} - -//----------------------------------------------------------------------------------- -// ***** Ref-Counted template pointer - -// Automatically AddRefs and Releases interfaces - -void* ReturnArg0(void* p); - -template<class C> -class Ptr -{ -#ifdef OVR_CC_ARM - static C* ReturnArg(void* p) { return (C*)ReturnArg0(p); } -#endif - -protected: - C *pObject; - -public: - - // Constructors - OVR_FORCE_INLINE Ptr() : pObject(0) - { } -#ifdef OVR_CC_ARM - OVR_FORCE_INLINE Ptr(C &robj) : pObject(ReturnArg(&robj)) -#else - OVR_FORCE_INLINE Ptr(C &robj) : pObject(&robj) -#endif - { } - OVR_FORCE_INLINE Ptr(Pickable<C> v) : pObject(v.GetPtr()) - { - // No AddRef() on purpose. - } - OVR_FORCE_INLINE Ptr(Ptr<C>& other, PickType) : pObject(other.pObject) - { - other.pObject = NULL; - // No AddRef() on purpose. - } - OVR_FORCE_INLINE Ptr(C *pobj) - { - if (pobj) pobj->AddRef(); - pObject = pobj; - } - OVR_FORCE_INLINE Ptr(const Ptr<C> &src) - { - if (src.pObject) src.pObject->AddRef(); - pObject = src.pObject; - } - - template<class R> - OVR_FORCE_INLINE Ptr(Ptr<R> &src) - { - if (src) src->AddRef(); - pObject = src; - } - template<class R> - OVR_FORCE_INLINE Ptr(Pickable<R> v) : pObject(v.GetPtr()) - { - // No AddRef() on purpose. - } - - // Destructor - OVR_FORCE_INLINE ~Ptr() - { - if (pObject) pObject->Release(); - } - - // Compares - OVR_FORCE_INLINE bool operator == (const Ptr &other) const { return pObject == other.pObject; } - OVR_FORCE_INLINE bool operator != (const Ptr &other) const { return pObject != other.pObject; } - - OVR_FORCE_INLINE bool operator == (C *pother) const { return pObject == pother; } - OVR_FORCE_INLINE bool operator != (C *pother) const { return pObject != pother; } - - - OVR_FORCE_INLINE bool operator < (const Ptr &other) const { return pObject < other.pObject; } - - // Assignment - template<class R> - OVR_FORCE_INLINE const Ptr<C>& operator = (const Ptr<R> &src) - { - // By design we don't check for src == pObject, as we don't expect that to be the case the large majority of the time. - if (src) src->AddRef(); - if (pObject) pObject->Release(); - pObject = src; - return *this; - } - // Specialization - OVR_FORCE_INLINE const Ptr<C>& operator = (const Ptr<C> &src) - { - if (src) src->AddRef(); - if (pObject) pObject->Release(); - pObject = src; - return *this; - } - - OVR_FORCE_INLINE const Ptr<C>& operator = (C *psrc) - { - if (psrc) psrc->AddRef(); - if (pObject) pObject->Release(); - pObject = psrc; - return *this; - } - OVR_FORCE_INLINE const Ptr<C>& operator = (C &src) - { - if (pObject) pObject->Release(); - pObject = &src; - return *this; - } - OVR_FORCE_INLINE Ptr<C>& operator = (Pickable<C> src) - { - return Pick(src); - } - template<class R> - OVR_FORCE_INLINE Ptr<C>& operator = (Pickable<R> src) - { - return Pick(src); - } - - // Set Assignment - template<class R> - OVR_FORCE_INLINE Ptr<C>& SetPtr(const Ptr<R> &src) - { - if (src) src->AddRef(); - if (pObject) pObject->Release(); - pObject = src; - return *this; - } - // Specialization - OVR_FORCE_INLINE Ptr<C>& SetPtr(const Ptr<C> &src) - { - if (src) src->AddRef(); - if (pObject) pObject->Release(); - pObject = src; - return *this; - } - - OVR_FORCE_INLINE Ptr<C>& SetPtr(C *psrc) - { - if (psrc) psrc->AddRef(); - if (pObject) pObject->Release(); - pObject = psrc; - return *this; - } - OVR_FORCE_INLINE Ptr<C>& SetPtr(C &src) - { - if (pObject) pObject->Release(); - pObject = &src; - return *this; - } - OVR_FORCE_INLINE Ptr<C>& SetPtr(Pickable<C> src) - { - return Pick(src); - } - - // Nulls ref-counted pointer without decrement - OVR_FORCE_INLINE void NullWithoutRelease() - { - pObject = 0; - } - - // Clears the pointer to the object - OVR_FORCE_INLINE void Clear() - { - if (pObject) pObject->Release(); - pObject = 0; - } - - // Obtain pointer reference directly, for D3D interfaces - OVR_FORCE_INLINE C*& GetRawRef() { return pObject; } - - // Access Operators - OVR_FORCE_INLINE C* GetPtr() const { return pObject; } - OVR_FORCE_INLINE C& operator * () const { return *pObject; } - OVR_FORCE_INLINE C* operator -> () const { return pObject; } - // Conversion - OVR_FORCE_INLINE operator C* () const { return pObject; } - - // Pickers. - - // Pick a value. - OVR_FORCE_INLINE Ptr<C>& Pick(Ptr<C>& other) - { - if (&other != this) - { - if (pObject) pObject->Release(); - pObject = other.pObject; - other.pObject = 0; - } - - return *this; - } - - OVR_FORCE_INLINE Ptr<C>& Pick(Pickable<C> v) - { - if (v.GetPtr() != pObject) - { - if (pObject) pObject->Release(); - pObject = v.GetPtr(); - } - - return *this; - } - - template<class R> - OVR_FORCE_INLINE Ptr<C>& Pick(Pickable<R> v) - { - if (v.GetPtr() != pObject) - { - if (pObject) pObject->Release(); - pObject = v.GetPtr(); - } - - return *this; - } - - OVR_FORCE_INLINE Ptr<C>& Pick(C* p) - { - if (p != pObject) - { - if (pObject) pObject->Release(); - pObject = p; - } - - return *this; - } -}; - -} // OVR - -#endif diff --git a/LibOVR/Src/Kernel/OVR_SharedMemory.cpp b/LibOVR/Src/Kernel/OVR_SharedMemory.cpp deleted file mode 100644 index 1a6ccd9..0000000 --- a/LibOVR/Src/Kernel/OVR_SharedMemory.cpp +++ /dev/null @@ -1,691 +0,0 @@ -/************************************************************************************ - -Filename : OVR_SharedMemory.cpp -Content : Inter-process shared memory subsystem -Created : June 1, 2014 -Notes : - -Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); -you may not use the Oculus VR Rift SDK except in compliance with the License, -which is provided at the time of installation or download, or which -otherwise accompanies this software in either electronic or hard copy form. - -You may obtain a copy of the License at - -http://www.oculusvr.com/licenses/LICENSE-3.2 - -Unless required by applicable law or agreed to in writing, the Oculus VR SDK -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -************************************************************************************/ - -#include "OVR_SharedMemory.h" -#include "OVR_Atomic.h" -#include "OVR_Log.h" -#include "OVR_String.h" -#include "OVR_Array.h" - -#if defined(OVR_OS_WIN32) && !defined(OVR_FAKE_SHAREDMEMORY) -#include <Sddl.h> // ConvertStringSecurityDescriptorToSecurityDescriptor -#endif // OVR_OS_WIN32 - -#if (defined(OVR_OS_LINUX) || defined(OVR_OS_MAC)) && !defined(OVR_FAKE_SHAREDMEMORY) -#include <sys/mman.h> // shm_open(), mmap() -#include <errno.h> // error results for mmap -#include <sys/stat.h> // mode constants -#include <fcntl.h> // O_ constants -#include <unistd.h> // close() -#endif // OVR_OS_LINUX - -OVR_DEFINE_SINGLETON(OVR::SharedMemoryFactory); - -namespace OVR { - - - //// Fake version - -#if defined(OVR_FAKE_SHAREDMEMORY) - - class FakeMemoryBlock : public RefCountBase<FakeMemoryBlock> - { - String Name; - char* Data; - int SizeBytes; - int References; - - public: - FakeMemoryBlock(const String& name, int size) : - Name(name), - Data(NULL), - SizeBytes(size), - References(1) - { - Data = new char[SizeBytes]; - } - ~FakeMemoryBlock() - { - delete[] Data; - } - - bool IsNamed(const String& name) - { - return Name.CompareNoCase(name) == 0; - } - void* GetData() - { - return Data; - } - int GetSizeI() - { - return SizeBytes; - } - void IncrementReferences() - { - ++References; - } - bool DecrementReferences() - { - return --References <= 0; - } - }; - - class SharedMemoryInternal : public NewOverrideBase - { - public: - void* FileView; - Ptr<FakeMemoryBlock> Block; - - void Close(); - - SharedMemoryInternal(FakeMemoryBlock* block) : - Block(block) - { - FileView = Block->GetData(); - } - ~SharedMemoryInternal() - { - Close(); - } - - static SharedMemoryInternal* CreateSharedMemory(const SharedMemory::OpenParameters& params); - }; - - - //// FakeMemoryManager - - class FakeMemoryManager : public NewOverrideBase, public SystemSingletonBase<FakeMemoryManager> - { - OVR_DECLARE_SINGLETON(FakeMemoryManager); - - Lock FakeLock; - Array< Ptr<FakeMemoryBlock> > FakeArray; - - public: - SharedMemoryInternal* Open(const char *name, int bytes, bool openOnly) - { - Lock::Locker locker(&FakeLock); - - const int count = FakeArray.GetSizeI(); - for (int ii = 0; ii < count; ++ii) - { - if (FakeArray[ii]->IsNamed(name)) - { - FakeArray[ii]->IncrementReferences(); - return new SharedMemoryInternal(FakeArray[ii]); - } - } - - if (openOnly) - { - return NULL; - } - - Ptr<FakeMemoryBlock> data = *new FakeMemoryBlock(name, bytes); - FakeArray.PushBack(data); - return new SharedMemoryInternal(data); - } - - void Free(FakeMemoryBlock* block) - { - Lock::Locker locker(&FakeLock); - - const int count = FakeArray.GetSizeI(); - for (int ii = 0; ii < count; ++ii) - { - if (FakeArray[ii].GetPtr() == block) - { - // If the reference count hit zero, - if (FakeArray[ii]->DecrementReferences()) - { - // Toast - FakeArray.RemoveAtUnordered(ii); - } - break; - } - } - } - }; - - FakeMemoryManager::FakeMemoryManager() - { - PushDestroyCallbacks(); - } - - FakeMemoryManager::~FakeMemoryManager() - { - OVR_ASSERT(FakeArray.GetSizeI() == 0); - } - - void FakeMemoryManager::OnSystemDestroy() - { - delete this; - } - - -} // namespace OVR - -OVR_DEFINE_SINGLETON(FakeMemoryManager); - -namespace OVR { - - -void SharedMemoryInternal::Close() -{ - FakeMemoryManager::GetInstance()->Free(Block); - Block.Clear(); -} - -SharedMemoryInternal* SharedMemoryInternal::CreateSharedMemory(const SharedMemory::OpenParameters& params) -{ - return FakeMemoryManager::GetInstance()->Open(params.globalName, params.minSizeBytes, params.openMode == SharedMemory::OpenMode_OpenOnly); -} - -#endif - - -//// Windows version - -#if defined(OVR_OS_WIN32) && !defined(OVR_FAKE_SHAREDMEMORY) - -#pragma comment(lib, "advapi32.lib") - -// Hidden implementation class for OS-specific behavior -class SharedMemoryInternal : public NewOverrideBase -{ -public: - HANDLE FileMapping; - void* FileView; - - SharedMemoryInternal(HANDLE fileMapping, void* fileView) : - FileMapping(fileMapping), - FileView(fileView) - { - } - - ~SharedMemoryInternal() - { - // If file view is set, - if (FileView) - { - UnmapViewOfFile(FileView); - FileView = NULL; - } - - // If file mapping is set, - if (FileMapping != NULL) - { - CloseHandle(FileMapping); - FileMapping = NULL; - } - } - - static SharedMemoryInternal* DoFileMap(HANDLE hFileMapping, const char* fileName, bool openReadOnly, int minSize); - static SharedMemoryInternal* AttemptOpenSharedMemory(const char* fileName, int minSize, bool openReadOnly); - static SharedMemoryInternal* AttemptCreateSharedMemory(const char* fileName, int minSize, bool openReadOnly, bool allowRemoteWrite); - static SharedMemoryInternal* CreateSharedMemory(const SharedMemory::OpenParameters& params); -}; - -SharedMemoryInternal* SharedMemoryInternal::DoFileMap(HANDLE hFileMapping, const char* fileName, bool openReadOnly, int minSize) -{ - // Interpret the access mode as a map desired access code - DWORD mapDesiredAccess = openReadOnly ? FILE_MAP_READ : FILE_MAP_WRITE; - - // Map view of the file to this process - void* pFileView = MapViewOfFile(hFileMapping, mapDesiredAccess, 0, 0, minSize); - - // If mapping could not be created, - if (!pFileView) - { - CloseHandle(hFileMapping); - - OVR_DEBUG_LOG(("[SharedMemory] FAILURE: Unable to map view of file for %s error code = %d", fileName, GetLastError())); - OVR_UNUSED(fileName); - return NULL; - } - - // Create internal representation - SharedMemoryInternal* pimple = new SharedMemoryInternal(hFileMapping, pFileView); - - // If memory allocation fails, - if (!pimple) - { - UnmapViewOfFile(pFileView); - CloseHandle(hFileMapping); - - OVR_DEBUG_LOG(("[SharedMemory] FAILURE: Out of memory")); - return NULL; - } - - return pimple; -} - -SharedMemoryInternal* SharedMemoryInternal::AttemptOpenSharedMemory(const char* fileName, int minSize, bool openReadOnly) -{ - // Interpret the access mode as a map desired access code - DWORD mapDesiredAccess = openReadOnly ? FILE_MAP_READ : FILE_MAP_WRITE; - - // Open file mapping - HANDLE hFileMapping = OpenFileMappingA(mapDesiredAccess, TRUE, fileName); - - // If file was mapped unsuccessfully, - if (NULL == hFileMapping) - { - OVR_DEBUG_LOG(("[SharedMemory] WARNING: Unable to open file mapping for %s error code = %d (not necessarily bad)", fileName, GetLastError())); - return NULL; - } - - // Map the file - return DoFileMap(hFileMapping, fileName, openReadOnly, minSize); -} - -SharedMemoryInternal* SharedMemoryInternal::AttemptCreateSharedMemory(const char* fileName, int minSize, bool openReadOnly, bool allowRemoteWrite) -{ - // Prepare a SECURITY_ATTRIBUTES object - SECURITY_ATTRIBUTES security; - ZeroMemory(&security, sizeof(security)); - security.nLength = sizeof(security); - - // Security descriptor by DACL strings: - // ACE strings grant Allow(A), Object/Contains Inheritance (OICI) of: - // + Grant All (GA) to System (SY) - // + Grant All (GA) to Built-in Administrators (BA) - // + Grant Read-Only (GR) or Read-Write (GWGR) to Interactive Users (IU) - ie. games - static const char* DACLString_ReadOnly = "D:P(A;OICI;GA;;;SY)(A;OICI;GA;;;BA)(A;OICI;GR;;;IU)"; - static const char* DACLString_ReadWrite = "D:P(A;OICI;GA;;;SY)(A;OICI;GA;;;BA)(A;OICI;GWGR;;;IU)"; - - // Select the remote process access mode - const char* remoteAccessString = - allowRemoteWrite ? DACLString_ReadWrite : DACLString_ReadOnly; - - // Attempt to convert access string to security attributes - // Note: This will allocate the security descriptor with LocalAlloc() and must be freed later - BOOL bConvertOkay = ConvertStringSecurityDescriptorToSecurityDescriptorA( - remoteAccessString, SDDL_REVISION_1, &security.lpSecurityDescriptor, NULL); - - // If conversion fails, - if (!bConvertOkay) - { - OVR_DEBUG_LOG(("[SharedMemory] FAILURE: Unable to convert access string, error code = %d", GetLastError())); - return NULL; - } - - // Interpret the access mode as a page protection code - int pageProtectCode = openReadOnly ? PAGE_READONLY : PAGE_READWRITE; - - // Attempt to create a file mapping - HANDLE hFileMapping = CreateFileMappingA(INVALID_HANDLE_VALUE, // From page file - &security, // Security attributes - pageProtectCode, // Read-only? - 0, // High word for size = 0 - minSize, // Low word for size - fileName); // Name of global shared memory file - - // Free the security descriptor buffer - LocalFree(security.lpSecurityDescriptor); - - // If mapping could not be created, - if (NULL == hFileMapping) - { - OVR_DEBUG_LOG(("[SharedMemory] FAILURE: Unable to create file mapping for %s error code = %d", fileName, GetLastError())); - return NULL; - } - -#ifndef OVR_ALLOW_CREATE_FILE_MAPPING_IF_EXISTS - // If the file mapping already exists, - if (GetLastError() == ERROR_ALREADY_EXISTS) - { - CloseHandle(hFileMapping); - - OVR_DEBUG_LOG(("[SharedMemory] FAILURE: File mapping at %s already exists", fileName)); - return NULL; - } -#endif - - // Map the file - return DoFileMap(hFileMapping, fileName, openReadOnly, minSize); -} - -SharedMemoryInternal* SharedMemoryInternal::CreateSharedMemory(const SharedMemory::OpenParameters& params) -{ - SharedMemoryInternal* retval = NULL; - - // Construct the file mapping name in a Windows-specific way - OVR::String fileMappingName = params.globalName; - const char *fileName = fileMappingName.ToCStr(); - - // Is being opened read-only? - const bool openReadOnly = (params.accessMode == SharedMemory::AccessMode_ReadOnly); - - // Try up to 3 times to reduce low-probability failures: - static const int ATTEMPTS_MAX = 3; - for (int attempts = 0; attempts < ATTEMPTS_MAX; ++attempts) - { - // If opening should be attempted first, - if (params.openMode != SharedMemory::OpenMode_CreateOnly) - { - // Attempt to open a shared memory map - retval = AttemptOpenSharedMemory(fileName, params.minSizeBytes, openReadOnly); - - // If successful, - if (retval) - { - // Done! - break; - } - } - - // If creating the shared memory is also acceptable, - if (params.openMode != SharedMemory::OpenMode_OpenOnly) - { - // Interpret create mode - const bool allowRemoteWrite = (params.remoteMode == SharedMemory::RemoteMode_ReadWrite); - - // Attempt to create a shared memory map - retval = AttemptCreateSharedMemory(fileName, params.minSizeBytes, openReadOnly, allowRemoteWrite); - - // If successful, - if (retval) - { - // Done! - break; - } - } - } // Re-attempt create/open - - // Note: On Windows the initial contents of the region are guaranteed to be zero. - return retval; -} - -#endif // OVR_OS_WIN32 - - -#if (defined(OVR_OS_LINUX) || defined(OVR_OS_MAC)) && !defined(OVR_FAKE_SHAREDMEMORY) - -// Hidden implementation class for OS-specific behavior -class SharedMemoryInternal -{ -public: - int FileMapping; - void* FileView; - int FileSize; - - SharedMemoryInternal(int fileMapping, void* fileView, int fileSize) : - FileMapping(fileMapping), - FileView(fileView), - FileSize(fileSize) - { - } - - ~SharedMemoryInternal() - { - // If file view is set, - if (FileView) - { - munmap(FileView, FileSize); - FileView = MAP_FAILED; - } - - // If file mapping is set, - if (FileMapping >= 0) - { - close(FileMapping); - FileMapping = -1; - } - } - - static SharedMemoryInternal* DoFileMap(int hFileMapping, const char* fileName, bool openReadOnly, int minSize); - static SharedMemoryInternal* AttemptOpenSharedMemory(const char* fileName, int minSize, bool openReadOnly); - static SharedMemoryInternal* AttemptCreateSharedMemory(const char* fileName, int minSize, bool openReadOnly, bool allowRemoteWrite); - static SharedMemoryInternal* CreateSharedMemory(const SharedMemory::OpenParameters& params); -}; - -SharedMemoryInternal* SharedMemoryInternal::DoFileMap(int hFileMapping, const char* fileName, bool openReadOnly, int minSize) -{ - // Calculate the required flags based on read/write mode - int prot = openReadOnly ? PROT_READ : (PROT_READ|PROT_WRITE); - - // Map the file view - void* pFileView = mmap(NULL, minSize, prot, MAP_SHARED, hFileMapping, 0); - - if (pFileView == MAP_FAILED) - { - close(hFileMapping); - - OVR_DEBUG_LOG(("[SharedMemory] FAILURE: Unable to map view of file for %s error code = %d", fileName, errno)); - OVR_UNUSED(fileName); - return NULL; - } - - // Create internal representation - SharedMemoryInternal* pimple = new SharedMemoryInternal(hFileMapping, pFileView, minSize); - - // If memory allocation fails, - if (!pimple) - { - munmap(pFileView, minSize); - close(hFileMapping); - - OVR_DEBUG_LOG(("[SharedMemory] FAILURE: Out of memory")); - return NULL; - } - - return pimple; -} - -SharedMemoryInternal* SharedMemoryInternal::AttemptOpenSharedMemory(const char* fileName, int minSize, bool openReadOnly) -{ - // Calculate permissions and flags based on read/write mode - int flags = openReadOnly ? O_RDONLY : O_RDWR; - int perms = openReadOnly ? S_IRUSR : (S_IRUSR | S_IWUSR); - - // Attempt to open the shared memory file - int hFileMapping = shm_open(fileName, flags, perms); - - // If file was not opened successfully, - if (hFileMapping < 0) - { - OVR_DEBUG_LOG(("[SharedMemory] WARNING: Unable to open file mapping for %s error code = %d (not necessarily bad)", fileName, errno)); - return NULL; - } - - // Map the file - return DoFileMap(hFileMapping, fileName, openReadOnly, minSize); -} - -SharedMemoryInternal* SharedMemoryInternal::AttemptCreateSharedMemory(const char* fileName, int minSize, bool openReadOnly, bool allowRemoteWrite) -{ - // Create mode - // Note: Cannot create the shared memory file read-only because then ftruncate() will fail. - int flags = O_CREAT | O_RDWR; - -#ifndef OVR_ALLOW_CREATE_FILE_MAPPING_IF_EXISTS - // Require exclusive access when creating (seems like a good idea without trying it yet..) - if (shm_unlink(fileName) < 0) - { - OVR_DEBUG_LOG(("[SharedMemory] WARNING: Unable to unlink shared memory file %s error code = %d", fileName, errno)); - } - flags |= O_EXCL; -#endif - - // Set own read/write permissions - int perms = openReadOnly ? S_IRUSR : (S_IRUSR|S_IWUSR); - - // Allow other users to read/write the shared memory file - perms |= allowRemoteWrite ? (S_IWGRP|S_IWOTH|S_IRGRP|S_IROTH) : (S_IRGRP|S_IROTH); - - // Attempt to open the shared memory file - int hFileMapping = shm_open(fileName, flags, perms); - - // If file was not opened successfully, - if (hFileMapping < 0) - { - OVR_DEBUG_LOG(("[SharedMemory] FAILURE: Unable to create file mapping for %s error code = %d", fileName, errno)); - return NULL; - } - - int truncRes = ftruncate(hFileMapping, minSize); - - // If file was not opened successfully, - if (truncRes < 0) - { - close(hFileMapping); - OVR_DEBUG_LOG(("[SharedMemory] FAILURE: Unable to truncate file for %s to %d error code = %d", fileName, minSize, errno)); - return NULL; - } - - // Map the file - return DoFileMap(hFileMapping, fileName, openReadOnly, minSize); -} - -SharedMemoryInternal* SharedMemoryInternal::CreateSharedMemory(const SharedMemory::OpenParameters& params) -{ - SharedMemoryInternal* retval = NULL; - - // Construct the file mapping name in a Linux-specific way - OVR::String fileMappingName = "/"; - fileMappingName += params.globalName; - const char *fileName = fileMappingName.ToCStr(); - - // Is being opened read-only? - const bool openReadOnly = (params.accessMode == SharedMemory::AccessMode_ReadOnly); - - // Try up to 3 times to reduce low-probability failures: - static const int ATTEMPTS_MAX = 3; - for (int attempts = 0; attempts < ATTEMPTS_MAX; ++attempts) - { - // If opening should be attempted first, - if (params.openMode != SharedMemory::OpenMode_CreateOnly) - { - // Attempt to open a shared memory map - retval = AttemptOpenSharedMemory(fileName, params.minSizeBytes, openReadOnly); - - // If successful, - if (retval) - { - // Done! - break; - } - } - - // If creating the shared memory is also acceptable, - if (params.openMode != SharedMemory::OpenMode_OpenOnly) - { - // Interpret create mode - const bool allowRemoteWrite = (params.remoteMode == SharedMemory::RemoteMode_ReadWrite); - - // Attempt to create a shared memory map - retval = AttemptCreateSharedMemory(fileName, params.minSizeBytes, openReadOnly, allowRemoteWrite); - - // If successful, - if (retval) - { - // Done! - break; - } - } - } // Re-attempt create/open - - // Note: On Windows the initial contents of the region are guaranteed to be zero. - return retval; -} - -#endif // OVR_OS_LINUX - - -//// SharedMemory - -SharedMemory::SharedMemory(int size, void* data, SharedMemoryInternal* pInternal) : - Size(size), - Data(data), - Internal(pInternal) -{ -} -// Call close when it goes out of scope -SharedMemory::~SharedMemory() -{ - Close(); - delete Internal; -} - -void SharedMemory::Close() -{ - if (Internal) - { - delete Internal; - Internal = NULL; - } -} - - -//// SharedMemoryFactory - -Ptr<SharedMemory> SharedMemoryFactory::Open(const SharedMemory::OpenParameters& params) -{ - Ptr<SharedMemory> retval; - - // If no name specified or no size requested, - if (!params.globalName || (params.minSizeBytes <= 0)) - { - OVR_DEBUG_LOG(("[SharedMemory] FAILURE: Invalid parameters to Create()")); - return NULL; - } - - OVR_DEBUG_LOG(("[SharedMemory] Creating shared memory region: %s > %d bytes", - params.globalName, params.minSizeBytes)); - - // Attempt to create a shared memory region from the parameters - SharedMemoryInternal* pInternal = SharedMemoryInternal::CreateSharedMemory(params); - - if (pInternal) - { - // Create the wrapper object - retval = *new SharedMemory(params.minSizeBytes, pInternal->FileView, pInternal); - } - - return retval; -} - -SharedMemoryFactory::SharedMemoryFactory() -{ - OVR_DEBUG_LOG(("[SharedMemory] Creating factory")); - - PushDestroyCallbacks(); -} - -SharedMemoryFactory::~SharedMemoryFactory() -{ - OVR_DEBUG_LOG(("[SharedMemory] Destroying factory")); -} - -void SharedMemoryFactory::OnSystemDestroy() -{ - delete this; -} - - -} // namespace OVR diff --git a/LibOVR/Src/Kernel/OVR_SharedMemory.h b/LibOVR/Src/Kernel/OVR_SharedMemory.h deleted file mode 100644 index 2cc8b04..0000000 --- a/LibOVR/Src/Kernel/OVR_SharedMemory.h +++ /dev/null @@ -1,240 +0,0 @@ -/************************************************************************************ - -PublicHeader: OVR -Filename : OVR_SharedMemory.h -Content : Inter-process shared memory subsystem -Created : June 1, 2014 -Notes : - -Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); -you may not use the Oculus VR Rift SDK except in compliance with the License, -which is provided at the time of installation or download, or which -otherwise accompanies this software in either electronic or hard copy form. - -You may obtain a copy of the License at - -http://www.oculusvr.com/licenses/LICENSE-3.2 - -Unless required by applicable law or agreed to in writing, the Oculus VR SDK -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -************************************************************************************/ - -#ifndef OVR_SharedMemory_h -#define OVR_SharedMemory_h - -#include "OVR_Types.h" -#include "OVR_RefCount.h" -#include "OVR_Allocator.h" -#include "OVR_System.h" - -#ifdef OVR_SINGLE_PROCESS /* Everything running in one process usually for debugging */ -#define OVR_FAKE_SHAREDMEMORY /* Single-process version to avoid admin privs */ -#endif - -namespace OVR { - -class SharedMemoryInternal; // Opaque - - -// SharedMemory -// Note: Safe when used between 32-bit and 64-bit processes -class SharedMemory : public RefCountBase<SharedMemory> -{ - friend class SharedMemoryFactory; - - OVR_NON_COPYABLE(SharedMemory); - -public: - // Only constructed by the SharedMemory Factory - SharedMemory(int size, void* data, SharedMemoryInternal* pInternal); - // Call close when it goes out of scope - ~SharedMemory(); - - // Modes for opening a new shared memory region - enum OpenMode - { - // Note: On Windows, Create* requires Administrator priviledges or running as a Service. - OpenMode_CreateOnly, // Must not already exist - OpenMode_OpenOnly, // Must already exist - OpenMode_CreateOrOpen // May exist or not - }; - - // Local access restrictions - enum AccessMode - { - AccessMode_ReadOnly, // Acquire read-only access - AccessMode_ReadWrite, // Acquire read or write access - }; - - // Remote access restrictions - enum RemoteMode - { - RemoteMode_ReadOnly, // Other processes will need to open in read-only mode - RemoteMode_ReadWrite // Other processes can open in read-write mode - }; - - // Modes for opening a new shared memory region - struct OpenParameters - { - OpenParameters() : - globalName(NULL), - minSizeBytes(0), - openMode(SharedMemory::OpenMode_CreateOrOpen), - remoteMode(SharedMemory::RemoteMode_ReadWrite), - accessMode(SharedMemory::AccessMode_ReadWrite) - { - } - - // Creation parameters - const char* globalName; // Name of the shared memory region - int minSizeBytes; // Minimum number of bytes to request - SharedMemory::OpenMode openMode; // Creating the file or opening the file? - SharedMemory::RemoteMode remoteMode; // When creating, what access should other processes get? - SharedMemory::AccessMode accessMode; // When opening/creating, what access should this process get? - }; - -public: - // Returns the size of the shared memory region - int GetSizeI() const - { - return Size; - } - - // Returns the process-local pointer to the shared memory region - // Note: This may be different on different processes - void* GetData() const - { - return Data; - } - -protected: - int Size; // How many shared bytes are shared at the pointer address? - void* Data; // Pointer to the shared memory region. - - // Hidden implementation class for OS-specific behavior - SharedMemoryInternal* Internal; - - // Close and cleanup the shared memory region - // Note: This is called on destruction - void Close(); -}; - - -// SharedMemoryFactory -class SharedMemoryFactory : public NewOverrideBase, public SystemSingletonBase<SharedMemoryFactory> -{ - OVR_DECLARE_SINGLETON(SharedMemoryFactory); - -public: - // Construct a SharedMemory object. - // Note: The new object is reference-counted so it should be stored with Ptr<>. Initial reference count is 1. - Ptr<SharedMemory> Open(const SharedMemory::OpenParameters&); -}; - - -// A shared object -// Its constructor will be called when creating a writer -// Its destructor will not be called -template<class SharedType> -class ISharedObject : public NewOverrideBase -{ -public: - static const int RegionSize = (int)sizeof(SharedType); - -protected: - Ptr<SharedMemory> pSharedMemory; - - bool Open(const char* name, bool readOnly) - { - // Configure open parameters based on read-only mode - SharedMemory::OpenParameters params; - - // FIXME: This is a hack. We currently need to allow clients to open this for read-write even - // though they only need read-only access. This is because in the first 0.4 release the - // LocklessUpdater class technically writes to it (increments by 0) to read from the space. - // This was quickly corrected in 0.4.1 and we are waiting for the right time to disallow write - // access when everyone upgrades to 0.4.1+. - //params.remoteMode = SharedMemory::RemoteMode_ReadOnly; - params.remoteMode = SharedMemory::RemoteMode_ReadWrite; - - params.globalName = name; - params.accessMode = readOnly ? SharedMemory::AccessMode_ReadOnly : SharedMemory::AccessMode_ReadWrite; - params.minSizeBytes = RegionSize; - params.openMode = readOnly ? SharedMemory::OpenMode_OpenOnly : SharedMemory::OpenMode_CreateOrOpen; - - // Attempt to open the shared memory file - pSharedMemory = SharedMemoryFactory::GetInstance()->Open(params); - - // If it was not able to be opened, - if (pSharedMemory && pSharedMemory->GetSizeI() >= RegionSize && pSharedMemory->GetData()) - { - // If writing, - if (!readOnly) - { - // Construct the object also - Construct<SharedType>(pSharedMemory->GetData()); - } - - return true; - } - - return false; - } - - SharedType* Get() const - { - if (!pSharedMemory) - { - return NULL; - } - - void* data = pSharedMemory->GetData(); - if (!data) - { - return NULL; - } - - return reinterpret_cast<SharedType*>(data); - } -}; - -// Writer specialized shared object: Ctor will be called on Open() -template<class SharedType> -class SharedObjectWriter : public ISharedObject<SharedType> -{ -public: - OVR_FORCE_INLINE bool Open(const char* name) - { - return ISharedObject<SharedType>::Open(name, false); - } - OVR_FORCE_INLINE SharedType* Get() - { - return ISharedObject<SharedType>::Get(); - } -}; - -// Reader specialized shared object: Ctor will not be called -template<class SharedType> -class SharedObjectReader : public ISharedObject<SharedType> -{ -public: - OVR_FORCE_INLINE bool Open(const char* name) - { - return ISharedObject<SharedType>::Open(name, true); - } - OVR_FORCE_INLINE const SharedType* Get() const - { - return ISharedObject<SharedType>::Get(); - } -}; - - -} // namespace OVR - -#endif // OVR_SharedMemory_h diff --git a/LibOVR/Src/Kernel/OVR_Std.cpp b/LibOVR/Src/Kernel/OVR_Std.cpp deleted file mode 100644 index fc5ad04..0000000 --- a/LibOVR/Src/Kernel/OVR_Std.cpp +++ /dev/null @@ -1,1097 +0,0 @@ -/************************************************************************************ - -Filename : OVR_Std.cpp -Content : Standard C function implementation -Created : September 19, 2012 -Notes : - -Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); -you may not use the Oculus VR Rift SDK except in compliance with the License, -which is provided at the time of installation or download, or which -otherwise accompanies this software in either electronic or hard copy form. - -You may obtain a copy of the License at - -http://www.oculusvr.com/licenses/LICENSE-3.2 - -Unless required by applicable law or agreed to in writing, the Oculus VR SDK -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -************************************************************************************/ - -#include "OVR_Std.h" -#include "OVR_Alg.h" - -// localeconv() call in OVR_strtod() -#include <locale.h> - -namespace OVR { - -// Source for functions not available on all platforms is included here. - -size_t OVR_CDECL OVR_strlcpy(char* dest, const char* src, size_t destsize) -{ - const char* s = src; - size_t n = destsize; - - if(n && --n) - { - do{ - if((*dest++ = *s++) == 0) - break; - } while(--n); - } - - if(!n) - { - if(destsize) - *dest = 0; - while(*s++) - { } - } - - return (size_t)((s - src) - 1); -} - - -size_t OVR_CDECL OVR_strlcat(char* dest, const char* src, size_t destsize) -{ - const size_t d = destsize ? OVR_strlen(dest) : 0; - const size_t s = OVR_strlen(src); - const size_t t = s + d; - - OVR_ASSERT((destsize == 0) || (d < destsize)); - - if(t < destsize) - memcpy(dest + d, src, (s + 1) * sizeof(*src)); - else - { - if(destsize) - { - memcpy(dest + d, src, ((destsize - d) - 1) * sizeof(*src)); - dest[destsize - 1] = 0; - } - } - - return t; -} - - -// Case insensitive compare implemented in platform-specific way. -int OVR_CDECL OVR_stricmp(const char* a, const char* b) -{ -#if defined(OVR_OS_MS) - #if defined(OVR_CC_MSVC) && (OVR_CC_MSVC >= 1400) - return ::_stricmp(a, b); - #else - return ::stricmp(a, b); - #endif - -#else - return strcasecmp(a, b); -#endif -} - -int OVR_CDECL OVR_strnicmp(const char* a, const char* b, size_t count) -{ -#if defined(OVR_OS_MS) - #if defined(OVR_CC_MSVC) && (OVR_CC_MSVC >= 1400) - return ::_strnicmp(a, b, count); - #else - return ::strnicmp(a, b, count); - #endif - -#else - return strncasecmp(a, b, count); -#endif -} - -wchar_t* OVR_CDECL OVR_wcscpy(wchar_t* dest, size_t destsize, const wchar_t* src) -{ -#if defined(OVR_MSVC_SAFESTRING) - wcscpy_s(dest, destsize, src); - return dest; -#elif defined(OVR_OS_MS) - OVR_UNUSED(destsize); - wcscpy(dest, src); - return dest; -#else - size_t l = OVR_wcslen(src) + 1; // incl term null - l = (l < destsize) ? l : destsize; - memcpy(dest, src, l * sizeof(wchar_t)); - return dest; -#endif -} - -wchar_t* OVR_CDECL OVR_wcsncpy(wchar_t* dest, size_t destsize, const wchar_t* src, size_t count) -{ -#if defined(OVR_MSVC_SAFESTRING) - wcsncpy_s(dest, destsize, src, count); - return dest; -#else - size_t srclen = OVR_wcslen(src); - size_t l = Alg::Min(srclen, count); - l = (l < destsize) ? l : destsize; - memcpy(dest, src, l * sizeof(wchar_t)); - if (count > srclen) - { - size_t remLen = Alg::Min(destsize - l, (count - srclen)); - memset(&dest[l], 0, sizeof(wchar_t)*remLen); - } - else if (l < destsize) - dest[l] = 0; - return dest; -#endif -} - - -wchar_t* OVR_CDECL OVR_wcscat(wchar_t* dest, size_t destsize, const wchar_t* src) -{ -#if defined(OVR_MSVC_SAFESTRING) - wcscat_s(dest, destsize, src); - return dest; -#elif defined(OVR_OS_MS) - OVR_UNUSED(destsize); - wcscat(dest, src); - return dest; -#else - size_t dstlen = OVR_wcslen(dest); // do not incl term null - size_t srclen = OVR_wcslen(src) + 1; // incl term null - size_t copylen = (dstlen + srclen < destsize) ? srclen : destsize - dstlen; - memcpy(dest + dstlen, src, copylen * sizeof(wchar_t)); - return dest; -#endif -} - -size_t OVR_CDECL OVR_wcslen(const wchar_t* str) -{ -#if defined(OVR_OS_MS) - return wcslen(str); -#else - size_t i = 0; - while(str[i] != '\0') - ++i; - return i; -#endif -} - -int OVR_CDECL OVR_wcscmp(const wchar_t* a, const wchar_t* b) -{ -#if defined(OVR_OS_MS) || defined(OVR_OS_LINUX) - return wcscmp(a, b); -#else - // not supported, use custom implementation - const wchar_t *pa = a, *pb = b; - while (*pa && *pb) - { - wchar_t ca = *pa; - wchar_t cb = *pb; - if (ca < cb) - return -1; - else if (ca > cb) - return 1; - pa++; - pb++; - } - if (*pa) - return 1; - else if (*pb) - return -1; - else - return 0; -#endif -} - -int OVR_CDECL OVR_wcsicmp(const wchar_t* a, const wchar_t* b) -{ -#if defined(OVR_OS_MS) - #if defined(OVR_CC_MSVC) && (OVR_CC_MSVC >= 1400) - return ::_wcsicmp(a, b); - #else - return ::wcsicmp(a, b); - #endif -#elif defined(OVR_OS_MAC) || defined(__CYGWIN__) || defined(OVR_OS_ANDROID) || defined(OVR_OS_IPHONE) - // not supported, use custom implementation - const wchar_t *pa = a, *pb = b; - while (*pa && *pb) - { - wchar_t ca = OVR_towlower(*pa); - wchar_t cb = OVR_towlower(*pb); - if (ca < cb) - return -1; - else if (ca > cb) - return 1; - pa++; - pb++; - } - if (*pa) - return 1; - else if (*pb) - return -1; - else - return 0; -#else - return wcscasecmp(a, b); -#endif -} - -// This function is not inline because of dependency on <locale.h> -double OVR_CDECL OVR_strtod(const char* str, char** tailptr) -{ -#if !defined(OVR_OS_ANDROID) // The Android C library doesn't have localeconv. - const char s = *localeconv()->decimal_point; - - if (s != '.') // If the C library is using a locale that is not using '.' as a decimal point, we convert the input str's '.' chars to the char that the C library expects (e.g. ',' or ' '). - { - char buffer[347 + 1]; - - OVR_strcpy(buffer, sizeof(buffer), str); - - // Ensure null-termination of string - buffer[sizeof(buffer)-1] = '\0'; - - for (char* c = buffer; *c != '\0'; ++c) - { - if (*c == '.') - { - *c = s; - break; - } - } - - char *nextPtr = NULL; - double retval = strtod(buffer, &nextPtr); - - // If a tail pointer is requested, - if (tailptr) - { - // Return a tail pointer that points to the same offset as nextPtr, in the orig string - *tailptr = !nextPtr ? NULL : (char*)str + (int)(nextPtr - buffer); - } - - return retval; - } -#endif - - return strtod(str, tailptr); -} - - -#ifndef OVR_NO_WCTYPE - -//// Use this class to generate Unicode bitsets. For example: -//// -//// UnicodeBitSet bitSet; -//// for(unsigned i = 0; i < 65536; ++i) -//// { -//// if (iswalpha(i)) -//// bitSet.Set(i); -//// } -//// bitSet.Dump(); -//// -////--------------------------------------------------------------- -//class UnicodeBitSet -//{ -//public: -// UnicodeBitSet() -// { -// memset(Offsets, 0, sizeof(Offsets)); -// memset(Bits, 0, sizeof(Bits)); -// } -// -// void Set(unsigned bit) { Bits[bit >> 8][(bit >> 4) & 15] |= 1 << (bit & 15); } -// -// void Dump() -// { -// unsigned i, j; -// unsigned offsetCount = 0; -// for(i = 0; i < 256; ++i) -// { -// if (isNull(i)) Offsets[i] = 0; -// else -// if (isFull(i)) Offsets[i] = 1; -// else Offsets[i] = uint16_t(offsetCount++ * 16 + 256); -// } -// for(i = 0; i < 16; ++i) -// { -// for(j = 0; j < 16; ++j) -// { -// printf("%5u,", Offsets[i*16+j]); -// } -// printf("\n"); -// } -// for(i = 0; i < 256; ++i) -// { -// if (Offsets[i] > 255) -// { -// for(j = 0; j < 16; j++) -// { -// printf("%5u,", Bits[i][j]); -// } -// printf("\n"); -// } -// } -// } -// -//private: -// bool isNull(unsigned n) const -// { -// const uint16_t* p = Bits[n]; -// for(unsigned i = 0; i < 16; ++i) -// if (p[i] != 0) return false; -// return true; -// } -// -// bool isFull(unsigned n) const -// { -// const uint16_t* p = Bits[n]; -// for(unsigned i = 0; i < 16; ++i) -// if (p[i] != 0xFFFF) return false; -// return true; -// } -// -// uint16_t Offsets[256]; -// uint16_t Bits[256][16]; -//}; - - -const uint16_t UnicodeAlnumBits[] = { - 256, 1, 272, 288, 304, 320, 336, 352, 0, 368, 384, 400, 416, 432, 448, 464, - 480, 496, 512, 528, 544, 1, 560, 576, 592, 0, 0, 0, 0, 0, 608, 624, - 640, 656, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 672, 688, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 704, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 720, - 1, 1, 1, 1, 736, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 752, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 768, 784, 1, 800, 816, 832, - 0, 0, 0, 1023,65534, 2047,65534, 2047, 0, 0, 0, 524,65535,65407,65535,65407, -65535,65535,65532, 15, 0,65535,65535,65535,65535,65535,16383,63999, 3, 0,16415, 0, - 0, 0, 0, 0, 32, 0, 0, 1024,55104,65535,65531,65535,32767,64767,65535, 15, -65535,65535,65535,65535,65535,65535,65535,65535,61443,65535,65535,65535, 6559,65535,65535, 831, - 0, 0, 0,65534,65535, 639,65534,65535, 255, 0, 0, 0, 0,65535, 2047, 7, - 0, 0,65534, 2047,65534, 63, 1023,65535,65535,65535,65535,65535,65535, 8175, 8702, 8191, - 0,65535, 8191,65535, 0, 0, 0, 0,65535,65535,65535, 1, 0, 0, 0, 0, -65518,65535,65535,58367, 8191,65281,65487, 0,40942,65529,65023,50117, 6559,45184,65487, 3, -34788,65529,65023,50029, 6535,24064,65472, 31,45038,65531,65023,58349, 7103, 1,65473, 0, -40942,65529,65023,58317, 6543,45248,65475, 0,51180,54845,50968,50111, 7623, 128,65408, 0, -57326,65533,65023,50159, 7647, 96,65475, 0,57324,65533,65023,50159, 7647,16480,65475, 0, -57324,65533,65023,50175, 7631, 128,65475, 0,65516,64639,65535,12283,32895,65375, 0, 12, -65534,65535,65535, 2047,32767, 1023, 0, 0, 9622,65264,60590,15359, 8223,13311, 0, 0, - 1, 0, 1023, 0,65279,65535, 2047,65534, 3843,65279,65535, 8191, 0, 0, 0, 0, -65535,65535,63227, 327, 1023, 1023, 0, 0, 0, 0,65535,65535, 63,65535,65535, 127, -65535,65535,65535,65535,65535,33791,65535,65535,65535,65535,65287,65535,65535,65535,65535, 1023, -65407,65535,65535,65535,15743,15743,65535,65535,15743,65535,32767,32573,32573,65407,32767,65535, -32767,32573,65535,65535,65407, 2047,65024, 3, 0, 0,65535,65535,65535,65535,65535, 31, -65534,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535, -65535,65535,65535,65535,65535,65535,40959, 127,65534, 2047,65535,65535,65535,65535, 2047, 0, - 0, 0, 0, 0, 0, 0, 0, 0,65535,65535,65535,65535, 511, 0, 1023, 0, - 0, 1023,65535,65535,65527,65535,65535, 255,65535,65535, 1023, 0, 0, 0, 0, 0, -65535,65535,65535,65535,65535,65535,65535,65535,65535, 4095,65535,65535,65535,65535,65535, 1023, -65535,16191,65535,65535,16191,43775,65535,16383,65535,65535,65535,24543, 8156, 4047, 8191, 8156, - 0, 0, 0, 0, 0, 0, 0,32768, 0, 0, 0, 0, 0, 0, 0, 0, -64644,15919,48464, 1019, 0, 0,65535,65535, 15, 0, 0, 0, 0, 0, 0, 0, - 192, 0, 1022, 1792,65534,65535,65535,65535,65535, 31,65534,65535,65535,65535,65535, 2047, -65504,65535, 8191,65534,65535,65535,65535,65535,32767, 0,65535, 255, 0, 0, 0, 0, -65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535, 63, 0, 0, 0, 0, -65535,65535,65535,65535,65535,65535,65535,65535,65535,65535, 63, 0, 0, 0, 0, 0, -65535,65535,65535,65535,65535,65535,65535,65535, 8191, 0, 0, 0, 0, 0, 0, 0, -65535,65535,65535,65535,65535,65535,65535,65535,65535,65535, 15, 0, 0, 0, 0, 0, -65535,65535,16383, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 127,41208,65023,24447,65499,65535,65535,65535,65535,65535,65535, 3, 0,65528,65535,65535, -65535,65535,65535,16383, 0,65535,65535,65535,65535,65532,65535,65535, 255, 0, 0, 4095, - 0, 0, 0, 0, 0, 0, 0,65495,65535,65535,65535,65535,65535,65535,65535, 8191, - 0, 1023,65534, 2047,65534, 2047,65472,65534,65535,16383,65535,32767,64764, 7420, 0, 0}; - -const uint16_t UnicodeAlphaBits[] = { - 256, 1, 272, 288, 304, 320, 336, 352, 0, 368, 384, 400, 416, 432, 448, 464, - 480, 496, 512, 528, 544, 1, 560, 576, 592, 0, 0, 0, 0, 0, 608, 624, - 640, 656, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 672, 688, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 704, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 720, - 1, 1, 1, 1, 736, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 752, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 768, 784, 1, 800, 816, 832, - 0, 0, 0, 0,65534, 2047,65534, 2047, 0, 0, 0, 0,65535,65407,65535,65407, -65535,65535,65532, 15, 0,65535,65535,65535,65535,65535,16383,63999, 3, 0,16415, 0, - 0, 0, 0, 0, 32, 0, 0, 1024,55104,65535,65531,65535,32767,64767,65535, 15, -65535,65535,65535,65535,65535,65535,65535,65535,61443,65535,65535,65535, 6559,65535,65535, 831, - 0, 0, 0,65534,65535, 639,65534,65535, 255, 0, 0, 0, 0,65535, 2047, 7, - 0, 0,65534, 2047,65534, 63, 0,65535,65535,65535,65535,65535,65535, 8175, 8702, 7168, - 0,65535, 8191,65535, 0, 0, 0, 0,65535,65535,65535, 1, 0, 0, 0, 0, -65518,65535,65535,58367, 8191,65281, 15, 0,40942,65529,65023,50117, 6559,45184, 15, 3, -34788,65529,65023,50029, 6535,24064, 0, 31,45038,65531,65023,58349, 7103, 1, 1, 0, -40942,65529,65023,58317, 6543,45248, 3, 0,51180,54845,50968,50111, 7623, 128, 0, 0, -57326,65533,65023,50159, 7647, 96, 3, 0,57324,65533,65023,50159, 7647,16480, 3, 0, -57324,65533,65023,50175, 7631, 128, 3, 0,65516,64639,65535,12283,32895,65375, 0, 12, -65534,65535,65535, 2047,32767, 0, 0, 0, 9622,65264,60590,15359, 8223,12288, 0, 0, - 1, 0, 0, 0,65279,65535, 2047,65534, 3843,65279,65535, 8191, 0, 0, 0, 0, -65535,65535,63227, 327, 0, 1023, 0, 0, 0, 0,65535,65535, 63,65535,65535, 127, -65535,65535,65535,65535,65535,33791,65535,65535,65535,65535,65287,65535,65535,65535,65535, 1023, -65407,65535,65535,65535,15743,15743,65535,65535,15743,65535,32767,32573,32573,65407,32767,65535, -32767,32573,65535,65535,65407, 2047, 0, 0, 0, 0,65535,65535,65535,65535,65535, 31, -65534,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535, -65535,65535,65535,65535,65535,65535,40959, 127,65534, 2047,65535,65535,65535,65535, 2047, 0, - 0, 0, 0, 0, 0, 0, 0, 0,65535,65535,65535,65535, 511, 0, 0, 0, - 0, 0,65535,65535,65527,65535,65535, 255,65535,65535, 1023, 0, 0, 0, 0, 0, -65535,65535,65535,65535,65535,65535,65535,65535,65535, 4095,65535,65535,65535,65535,65535, 1023, -65535,16191,65535,65535,16191,43775,65535,16383,65535,65535,65535,24543, 8156, 4047, 8191, 8156, - 0, 0, 0, 0, 0, 0, 0,32768, 0, 0, 0, 0, 0, 0, 0, 0, -64644,15919,48464, 1019, 0, 0,65535,65535, 15, 0, 0, 0, 0, 0, 0, 0, - 192, 0, 1022, 1792,65534,65535,65535,65535,65535, 31,65534,65535,65535,65535,65535, 2047, -65504,65535, 8191,65534,65535,65535,65535,65535,32767, 0,65535, 255, 0, 0, 0, 0, -65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535, 63, 0, 0, 0, 0, -65535,65535,65535,65535,65535,65535,65535,65535,65535,65535, 63, 0, 0, 0, 0, 0, -65535,65535,65535,65535,65535,65535,65535,65535, 8191, 0, 0, 0, 0, 0, 0, 0, -65535,65535,65535,65535,65535,65535,65535,65535,65535,65535, 15, 0, 0, 0, 0, 0, -65535,65535,16383, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 127,41208,65023,24447,65499,65535,65535,65535,65535,65535,65535, 3, 0,65528,65535,65535, -65535,65535,65535,16383, 0,65535,65535,65535,65535,65532,65535,65535, 255, 0, 0, 4095, - 0, 0, 0, 0, 0, 0, 0,65495,65535,65535,65535,65535,65535,65535,65535, 8191, - 0, 0,65534, 2047,65534, 2047,65472,65534,65535,16383,65535,32767,64764, 7420, 0, 0}; - -const uint16_t UnicodeDigitBits[] = { - 256, 0, 0, 0, 0, 0, 272, 0, 0, 288, 304, 320, 336, 352, 368, 384, - 400, 0, 0, 416, 0, 0, 0, 432, 448, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 464, - 0, 0, 0, 1023, 0, 0, 0, 0, 0, 0, 0, 524, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1023, 0, 0, 0, 0, 0, 0, 0, 0, 1023, - 0, 0, 0, 0, 0, 0,65472, 0, 0, 0, 0, 0, 0, 0,65472, 0, - 0, 0, 0, 0, 0, 0,65472, 0, 0, 0, 0, 0, 0, 0,65472, 0, - 0, 0, 0, 0, 0, 0,65472, 0, 0, 0, 0, 0, 0, 0,65408, 0, - 0, 0, 0, 0, 0, 0,65472, 0, 0, 0, 0, 0, 0, 0,65472, 0, - 0, 0, 0, 0, 0, 0,65472, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1023, 0, 0, 0, 0, 0, 0, 0, 1023, 0, 0, - 0, 0, 1023, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 1023, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0,65024, 3, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1023, 0, - 0, 1023, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1023, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; - -const uint16_t UnicodeSpaceBits[] = { - 256, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 272, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 288, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 304, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -15872, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, - 4095, 0,33536, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; - -const uint16_t UnicodeXDigitBits[] = { - 256, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 272, - 0, 0, 0, 1023, 126, 0, 126, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1023, 126, 0, 126, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; - -// Uncomment if necessary -//const uint16_t UnicodeCntrlBits[] = { -// 256, 0, 0, 0, 0, 0, 0, 272, 0, 0, 0, 0, 0, 0, 0, 0, -// 0, 0, 0, 0, 0, 0, 0, 0, 288, 0, 0, 0, 0, 0, 0, 0, -// 304, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 320, 336, -//65535,65535, 0, 0, 0, 0, 0,32768,65535,65535, 0, 0, 0, 0, 0, 0, -//32768, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -//30720, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -//61440, 0,31744, 0, 0, 0,64512, 0, 0, 0, 0, 0, 0, 0, 0, 0, -// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,32768, -// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3584}; -// -//const uint16_t UnicodeGraphBits[] = { -// 256, 1, 272, 288, 304, 320, 336, 352, 0, 368, 384, 400, 416, 432, 448, 464, -// 480, 496, 512, 528, 544, 1, 560, 576, 592, 0, 0, 0, 0, 0, 608, 624, -// 640, 656, 0, 672, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -// 688, 704, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -// 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 720, 1, 1, -// 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -// 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -// 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -// 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -// 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 736, -// 1, 1, 1, 1, 752, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, -// 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -// 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -// 1, 1, 1, 1, 1, 1, 1, 768, 0, 0, 0, 0, 0, 0, 0, 0, -// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -// 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 784, 800, 1, 816, 832, 848, -// 0, 0,65534,65535,65535,65535,65535,32767, 0, 0,65534,65535,65535,65535,65535,65535, -//65535,65535,65532, 15, 0,65535,65535,65535,65535,65535,16383,63999, 3, 0,16415, 0, -// 0, 0, 0, 0, 32, 0, 0,17408,55232,65535,65531,65535,32767,64767,65535, 15, -//65535,65535,65535,65535,65535,65535,65535,65535,61443,65535,65535,65535, 6559,65535,65535, 831, -// 0, 0, 0,65534,65535,65151,65534,65535, 1791, 0, 0,16384, 9,65535, 2047, 31, -// 4096,34816,65534, 2047,65534, 63,16383,65535,65535,65535,65535,65535,65535, 8191, 8702, 8191, -//16383,65535, 8191,65535, 0, 0, 0, 0,65535,65535,65535, 1, 0, 0, 0, 0, -//65518,65535,65535,58367, 8191,65281,65535, 1,40942,65529,65023,50117, 6559,45184,65487, 3, -//34788,65529,65023,50029, 6535,24064,65472, 31,45038,65531,65023,58349, 7103, 1,65473, 0, -//40942,65529,65023,58317, 6543,45248,65475, 0,51180,54845,50968,50111, 7623, 128,65408, 0, -//57326,65533,65023,50159, 7647, 96,65475, 0,57324,65533,65023,50159, 7647,16480,65475, 0, -//57324,65533,65023,50175, 7631, 128,65475, 0,65516,64639,65535,12283,32895,65375, 0, 28, -//65534,65535,65535, 2047,65535, 4095, 0, 0, 9622,65264,60590,15359, 8223,13311, 0, 0, -//65521, 7, 1023,15360,65279,65535, 2047,65534, 3875,65279,65535, 8191, 0, 0, 0, 0, -//65535,65535,63227, 327,65535, 1023, 0, 0, 0, 0,65535,65535, 63,65535,65535, 2175, -//65535,65535,65535,65535,65535,33791,65535,65535,65535,65535,65287,65535,65535,65535,65535, 1023, -//65407,65535,65535,65535,15743,15743,65535,65535,15743,65535,32767,32573,32573,65407,32767,65535, -//32767,32573,65535,65535,65407, 2047,65534, 3, 0, 0,65535,65535,65535,65535,65535, 31, -//65534,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535, -//65535,65535,65535,65535,65535,65535,65535, 127,65534, 8191,65535,65535,65535,65535,16383, 0, -// 0, 0, 0, 0, 0, 0, 0, 0,65535,65535,65535,65535, 511, 6128, 1023, 0, -// 2047, 1023,65535,65535,65527,65535,65535, 255,65535,65535, 1023, 0, 0, 0, 0, 0, -//65535,65535,65535,65535,65535,65535,65535,65535,65535, 4095,65535,65535,65535,65535,65535, 1023, -//65535,16191,65535,65535,16191,43775,65535,16383,65535,65535,65535,24543, 8156, 4047, 8191, 8156, -// 0,65535, 255,65535,16239, 0, 0,57344,24576, 0, 0, 0, 0, 0, 0, 0, -//64644,15919,48464, 1019, 0, 0,65535,65535, 15, 0, 0, 0, 0, 0, 0, 0, -// 0, 0, 1536, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -//65486,65523, 1022, 1793,65534,65535,65535,65535,65535, 31,65534,65535,65535,65535,65535, 4095, -//65504,65535, 8191,65534,65535,65535,65535,65535,32767, 0,65535, 255, 0, 0, 0, 0, -//65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535, 63, 0, 0, 0, 0, -//65535,65535,65535,65535,65535,65535,65535,65535,65535,65535, 63, 0, 0, 0, 0, 0, -//65535,65535,65535,65535,65535,65535,65535,65535, 8191, 0, 0, 0, 0, 0, 0, 0, -//65535,65535,65535,65535,65535,65535,65535,65535,65535,65535, 15, 0, 0, 0, 0, 0, -//65535,65535,16383, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -// 127,41208,65023,24447,65499,65535,65535,65535,65535,65535,65535, 3, 0,65528,65535,65535, -//65535,65535,65535,65535, 0,65535,65535,65535,65535,65532,65535,65535, 255, 0, 0, 4095, -// 0, 0, 0,65535,65055,65527, 3339,65495,65535,65535,65535,65535,65535,65535,65535, 8191, -//63470,36863,65535,49151,65534,12287,65534,65534,65535,16383,65535,32767,64764, 7420, 0, 0}; -// -//const uint16_t UnicodePrintBits[] = { -// 256, 1, 272, 288, 304, 320, 336, 352, 0, 368, 384, 400, 416, 432, 448, 464, -// 480, 496, 512, 528, 544, 1, 560, 576, 592, 0, 0, 0, 0, 0, 608, 624, -// 640, 656, 0, 672, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -// 688, 704, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -// 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 720, 1, 1, -// 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -// 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -// 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -// 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -// 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 736, -// 1, 1, 1, 1, 752, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, -// 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -// 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -// 1, 1, 1, 1, 1, 1, 1, 768, 0, 0, 0, 0, 0, 0, 0, 0, -// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -// 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 784, 800, 1, 816, 832, 848, -// 512, 0,65535,65535,65535,65535,65535,32767, 0, 0,65535,65535,65535,65535,65535,65535, -//65535,65535,65532, 15, 0,65535,65535,65535,65535,65535,16383,63999, 3, 0,16415, 0, -// 0, 0, 0, 0, 32, 0, 0,17408,55232,65535,65531,65535,32767,64767,65535, 15, -//65535,65535,65535,65535,65535,65535,65535,65535,61443,65535,65535,65535, 6559,65535,65535, 831, -// 0, 0, 0,65534,65535,65151,65534,65535, 1791, 0, 0,16384, 9,65535, 2047, 31, -// 4096,34816,65534, 2047,65534, 63,16383,65535,65535,65535,65535,65535,65535, 8191, 8702, 8191, -//16383,65535, 8191,65535, 0, 0, 0, 0,65535,65535,65535, 1, 0, 0, 0, 0, -//65518,65535,65535,58367, 8191,65281,65535, 1,40942,65529,65023,50117, 6559,45184,65487, 3, -//34788,65529,65023,50029, 6535,24064,65472, 31,45038,65531,65023,58349, 7103, 1,65473, 0, -//40942,65529,65023,58317, 6543,45248,65475, 0,51180,54845,50968,50111, 7623, 128,65408, 0, -//57326,65533,65023,50159, 7647, 96,65475, 0,57324,65533,65023,50159, 7647,16480,65475, 0, -//57324,65533,65023,50175, 7631, 128,65475, 0,65516,64639,65535,12283,32895,65375, 0, 28, -//65534,65535,65535, 2047,65535, 4095, 0, 0, 9622,65264,60590,15359, 8223,13311, 0, 0, -//65521, 7, 1023,15360,65279,65535, 2047,65534, 3875,65279,65535, 8191, 0, 0, 0, 0, -//65535,65535,63227, 327,65535, 1023, 0, 0, 0, 0,65535,65535, 63,65535,65535, 2175, -//65535,65535,65535,65535,65535,33791,65535,65535,65535,65535,65287,65535,65535,65535,65535, 1023, -//65407,65535,65535,65535,15743,15743,65535,65535,15743,65535,32767,32573,32573,65407,32767,65535, -//32767,32573,65535,65535,65407, 2047,65534, 3, 0, 0,65535,65535,65535,65535,65535, 31, -//65534,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535, -//65535,65535,65535,65535,65535,65535,65535, 127,65534, 8191,65535,65535,65535,65535,16383, 0, -// 0, 0, 0, 0, 0, 0, 0, 0,65535,65535,65535,65535, 511, 6128, 1023, 0, -// 2047, 1023,65535,65535,65527,65535,65535, 255,65535,65535, 1023, 0, 0, 0, 0, 0, -//65535,65535,65535,65535,65535,65535,65535,65535,65535, 4095,65535,65535,65535,65535,65535, 1023, -//65535,16191,65535,65535,16191,43775,65535,16383,65535,65535,65535,24543, 8156, 4047, 8191, 8156, -// 0,65535, 255,65535,16239, 0, 0,57344,24576, 0, 0, 0, 0, 0, 0, 0, -//64644,15919,48464, 1019, 0, 0,65535,65535, 15, 0, 0, 0, 0, 0, 0, 0, -// 0, 0, 1536, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -//65487,65523, 1022, 1793,65534,65535,65535,65535,65535, 31,65534,65535,65535,65535,65535, 4095, -//65504,65535, 8191,65534,65535,65535,65535,65535,32767, 0,65535, 255, 0, 0, 0, 0, -//65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535, 63, 0, 0, 0, 0, -//65535,65535,65535,65535,65535,65535,65535,65535,65535,65535, 63, 0, 0, 0, 0, 0, -//65535,65535,65535,65535,65535,65535,65535,65535, 8191, 0, 0, 0, 0, 0, 0, 0, -//65535,65535,65535,65535,65535,65535,65535,65535,65535,65535, 15, 0, 0, 0, 0, 0, -//65535,65535,16383, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -// 127,41208,65023,24447,65499,65535,65535,65535,65535,65535,65535, 3, 0,65528,65535,65535, -//65535,65535,65535,65535, 0,65535,65535,65535,65535,65532,65535,65535, 255, 0, 0, 4095, -// 0, 0, 0,65535,65055,65527, 3339,65495,65535,65535,65535,65535,65535,65535,65535,40959, -//63470,36863,65535,49151,65534,12287,65534,65534,65535,16383,65535,32767,64764, 7420, 0, 0}; -// -//const uint16_t UnicodePunctBits[] = { -// 256, 0, 0, 272, 0, 288, 304, 320, 0, 336, 0, 0, 0, 352, 368, 384, -// 400, 0, 0, 416, 0, 0, 432, 448, 464, 0, 0, 0, 0, 0, 0, 0, -// 480, 0, 0, 496, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -// 512, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 528, 544, 560, -// 0, 0,65534,64512, 1,63488, 1,30720, 0, 0,65534,65535, 0, 128, 0, 128, -// 0, 0, 0, 0, 0, 0, 0,16384, 128, 0, 0, 0, 0, 0, 0, 0, -// 0, 0, 0, 0, 0,64512, 0, 0, 1536, 0, 0,16384, 9, 0, 0, 24, -// 4096,34816, 0, 0, 0, 0,15360, 0, 0, 0, 0, 0, 0, 16, 0, 0, -//16383, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -// 0, 0, 0, 0, 0, 0, 48, 1, 0, 0, 0, 0, 0, 0, 0, 0, -// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, -// 0, 0, 0, 0,32768, 3072, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -//65520, 7, 0,15360, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, -// 0, 0, 0, 0,64512, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2048, -// 0, 0, 0, 0, 0, 0, 510, 0, 0, 0, 0, 0, 0, 0, 0, 0, -// 0, 0, 0, 0, 0, 0,24576, 0, 0, 6144, 0, 0, 0, 0,14336, 0, -// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6128, 0, 0, -// 2047, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -// 0,65535, 255,65535,16239, 0, 0,24576,24576, 0, 0, 0, 0, 0, 0, 0, -// 0, 0, 1536, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -//65294,65523, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2048, -// 0, 0, 0,49152, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -// 0, 0, 0,65535,65055,65527, 3339, 0, 0, 0, 0, 0, 0, 0, 0, 0, -//63470,35840, 1,47104, 0,10240, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0}; -// -//const uint16_t UnicodeLowerBits[] = { -// 256, 272, 288, 304, 320, 336, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 352, 368, -// 384, 400, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 416, 0, 0, 0, 432, -// 0, 0, 0, 0, 0, 0,65534, 2047, 0, 0, 0, 0, 0,32768,65535,65407, -//43690,43690,43690,21930,43861,43690,43690,54442,12585,20004,11562,58961,23392,46421,43690,43565, -//43690,43690,43688, 10, 0,65535,65535,65535,65535,65535,16383, 0, 0, 0, 0, 0, -// 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,61440,65535,32767,43235,43690, 15, -// 0, 0, 0,65535,65535,65535,43690,43690,40962,43690,43690,43690, 4372,43690,43690, 554, -// 0, 0, 0, 0, 0, 0,65534,65535, 255, 0, 0, 0, 0, 0, 0, 0, -//43690,43690,43690,43690,43690,43690,43690,43690,43690, 4074,43690,43690,43690,43690,43690, 682, -// 255, 63, 255, 255, 63, 255, 255,16383,65535,65535,65535,20703, 4316, 207, 255, 4316, -// 0, 0, 0, 0, 0, 0, 0,32768, 0, 0, 0, 0, 0, 0, 0, 0, -//50176, 8,32768, 528, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -// 127, 248, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -// 0, 0, 0, 0,65534, 2047, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; -// -//const uint16_t UnicodeUpperBits[] = { -// 256, 272, 288, 304, 320, 336, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -// 352, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 368, 384, -// 0, 400, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 416, -// 0, 0, 0, 0,65534, 2047, 0, 0, 0, 0, 0, 0,65535,32639, 0, 0, -//21845,21845,21845,43605,21674,21845,21845,11093,52950,45531,53973, 4526,44464,19114,21845,21974, -//21845,21845,21844, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -// 0, 0, 0, 0, 0, 0, 0, 0,55104,65534, 4091, 0, 0,21532,21845, 0, -//65535,65535,65535, 0, 0, 0,21845,21845,20481,21845,21845,21845, 2187,21845,21845, 277, -// 0, 0, 0,65534,65535, 127, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,65535,65535, 63, 0, 0, 0, -//21845,21845,21845,21845,21845,21845,21845,21845,21845, 21,21845,21845,21845,21845,21845, 341, -//65280,16128,65280,65280,16128,43520,65280, 0,65280,65280,65280, 7936, 7936, 3840, 7936, 7936, -//14468,15911,15696, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -// 0, 0,65534, 2047, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; - - -// MA: March 19, 2010 -// Modified ToUpper and ToLower tables to match values expected by AS3 tests. -// ToLower modifications: -// 304 -> 105 -// 1024 -> 1104 * -// 1037 -> 1117 * -// UoUpper modifications: -// 255 -> 376 -// 305 -> 73 -// 383 -> 83 -// 1104 -> 1024 * -// 1117 -> 1037 * -// Entries marked with a '*' don't make complete sense based on Unicode manual, although -// they match AS3. - - -static const uint16_t UnicodeToUpperBits[] = { - 256, 272, 288, 304, 320, 336, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 352, 368, - 0, 384, 0, 0, 400, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 416, - 0, 0, 0, 0, 0, 0,65534, 2047, 0, 0, 0, 0, 0, 0,65535,65407, -43690,43690,43690,21674,43349,43690,43690,54442, 4392, 516, 8490, 8785,21056,46421,43690,43048, // MA: Modified for AS3. -43690, 170, 0, 0, 0, 2776,33545, 36, 3336, 4, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,61440,65534,32767, 0,43688, 0, - 0, 0, 0,65535,65535,65535,43690,43690, 2,43690,43690,43690, 4372,43690,35498, 554, // MA: Modified for AS3. - 0, 0, 0, 0, 0, 0,65534,65535, 127, 0, 0, 0, 0, 0, 0, 0, -43690,43690,43690,43690,43690,43690,43690,43690,43690, 42,43690,43690,43690,43690,43690, 682, - 255, 63, 255, 255, 63, 170, 255,16383, 0, 0, 0, 3, 0, 3, 35, 0, - 0, 0, 0, 0, 0, 0, 0,65535, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,65535, 1023, 0, - 0, 0, 0, 0,65534, 2047, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; - -static const uint16_t UnicodeToLowerBits[] = { - 256, 272, 288, 304, 320, 336, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 352, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 368, 384, - 0, 400, 0, 0, 416, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 432, - 0, 0, 0, 0,65534, 2047, 0, 0, 0, 0, 0, 0,65535,32639, 0, 0, -21845,21845,21845,43605,21674,21845,21845,11093,52950,45531,53909, 4526,42128,19114,21845,21522,// MA: Modidied for AS3. -21845, 85, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0,55104,65534, 4091, 0, 0, 0,21844, 0, -65535,65535,65535, 0, 0, 0,21845,21845, 1,21845,21845,21845, 2186,21845,17749, 277, - 0, 0, 0,65534,65535, 127, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,65535,65535, 63, 0, 0, 0, -21845,21845,21845,21845,21845,21845,21845,21845,21845, 21,21845,21845,21845,21845,21845, 341, -65280,16128,65280,65280,16128,43520,65280, 0, 0, 0, 0, 3840, 3840, 3840, 7936, 3840, - 0, 0, 0, 0, 0, 0,65535, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,65472,65535, 0, 0, 0, - 0, 0,65534, 2047, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; - -struct GUnicodePairType -{ - uint16_t Key, Value; -}; - -static inline bool CmpUnicodeKey(const GUnicodePairType& a, uint16_t key) -{ - return a.Key < key; -} - -static const GUnicodePairType UnicodeToUpperTable[] = { -{ 97, 65}, { 98, 66}, { 99, 67}, { 100, 68}, { 101, 69}, { 102, 70}, { 103, 71}, -{ 104, 72}, { 105, 73}, { 106, 74}, { 107, 75}, { 108, 76}, { 109, 77}, { 110, 78}, -{ 111, 79}, { 112, 80}, { 113, 81}, { 114, 82}, { 115, 83}, { 116, 84}, { 117, 85}, -{ 118, 86}, { 119, 87}, { 120, 88}, { 121, 89}, { 122, 90}, { 224, 192}, { 225, 193}, -{ 226, 194}, { 227, 195}, { 228, 196}, { 229, 197}, { 230, 198}, { 231, 199}, { 232, 200}, -{ 233, 201}, { 234, 202}, { 235, 203}, { 236, 204}, { 237, 205}, { 238, 206}, { 239, 207}, -{ 240, 208}, { 241, 209}, { 242, 210}, { 243, 211}, { 244, 212}, { 245, 213}, { 246, 214}, -{ 248, 216}, { 249, 217}, { 250, 218}, { 251, 219}, { 252, 220}, { 253, 221}, { 254, 222}, -{ 255, 376}, { 257, 256}, { 259, 258}, { 261, 260}, { 263, 262}, { 265, 264}, { 267, 266}, -{ 269, 268}, { 271, 270}, { 273, 272}, { 275, 274}, { 277, 276}, { 279, 278}, { 281, 280}, -{ 283, 282}, { 285, 284}, { 287, 286}, { 289, 288}, { 291, 290}, { 293, 292}, { 295, 294}, -{ 297, 296}, { 299, 298}, { 301, 300}, { 303, 302}, { 305, 73}, { 307, 306}, { 309, 308}, { 311, 310}, -{ 314, 313}, { 316, 315}, { 318, 317}, { 320, 319}, { 322, 321}, { 324, 323}, { 326, 325}, -{ 328, 327}, { 331, 330}, { 333, 332}, { 335, 334}, { 337, 336}, { 339, 338}, { 341, 340}, -{ 343, 342}, { 345, 344}, { 347, 346}, { 349, 348}, { 351, 350}, { 353, 352}, { 355, 354}, -{ 357, 356}, { 359, 358}, { 361, 360}, { 363, 362}, { 365, 364}, { 367, 366}, { 369, 368}, -{ 371, 370}, { 373, 372}, { 375, 374}, { 378, 377}, { 380, 379}, { 382, 381}, { 383, 83}, { 387, 386}, -{ 389, 388}, { 392, 391}, { 396, 395}, { 402, 401}, { 409, 408}, { 417, 416}, { 419, 418}, -{ 421, 420}, { 424, 423}, { 429, 428}, { 432, 431}, { 436, 435}, { 438, 437}, { 441, 440}, -{ 445, 444}, { 454, 452}, { 457, 455}, { 460, 458}, { 462, 461}, { 464, 463}, { 466, 465}, -{ 468, 467}, { 470, 469}, { 472, 471}, { 474, 473}, { 476, 475}, { 477, 398}, { 479, 478}, -{ 481, 480}, { 483, 482}, { 485, 484}, { 487, 486}, { 489, 488}, { 491, 490}, { 493, 492}, -{ 495, 494}, { 499, 497}, { 501, 500}, { 507, 506}, { 509, 508}, { 511, 510}, { 513, 512}, -{ 515, 514}, { 517, 516}, { 519, 518}, { 521, 520}, { 523, 522}, { 525, 524}, { 527, 526}, -{ 529, 528}, { 531, 530}, { 533, 532}, { 535, 534}, { 595, 385}, { 596, 390}, { 598, 393}, -{ 599, 394}, { 601, 399}, { 603, 400}, { 608, 403}, { 611, 404}, { 616, 407}, { 617, 406}, -{ 623, 412}, { 626, 413}, { 629, 415}, { 643, 425}, { 648, 430}, { 650, 433}, { 651, 434}, -{ 658, 439}, { 940, 902}, { 941, 904}, { 942, 905}, { 943, 906}, { 945, 913}, { 946, 914}, -{ 947, 915}, { 948, 916}, { 949, 917}, { 950, 918}, { 951, 919}, { 952, 920}, { 953, 921}, -{ 954, 922}, { 955, 923}, { 956, 924}, { 957, 925}, { 958, 926}, { 959, 927}, { 960, 928}, -{ 961, 929}, { 962, 931}, { 963, 931}, { 964, 932}, { 965, 933}, { 966, 934}, { 967, 935}, -{ 968, 936}, { 969, 937}, { 970, 938}, { 971, 939}, { 972, 908}, { 973, 910}, { 974, 911}, -{ 995, 994}, { 997, 996}, { 999, 998}, { 1001, 1000}, { 1003, 1002}, { 1005, 1004}, { 1007, 1006}, -{ 1072, 1040}, { 1073, 1041}, { 1074, 1042}, { 1075, 1043}, { 1076, 1044}, { 1077, 1045}, { 1078, 1046}, -{ 1079, 1047}, { 1080, 1048}, { 1081, 1049}, { 1082, 1050}, { 1083, 1051}, { 1084, 1052}, { 1085, 1053}, -{ 1086, 1054}, { 1087, 1055}, { 1088, 1056}, { 1089, 1057}, { 1090, 1058}, { 1091, 1059}, { 1092, 1060}, -{ 1093, 1061}, { 1094, 1062}, { 1095, 1063}, { 1096, 1064}, { 1097, 1065}, { 1098, 1066}, { 1099, 1067}, -{ 1100, 1068}, { 1101, 1069}, { 1102, 1070}, { 1103, 1071}, { 1104, 1024}, { 1105, 1025}, { 1106, 1026}, { 1107, 1027}, -{ 1108, 1028}, { 1109, 1029}, { 1110, 1030}, { 1111, 1031}, { 1112, 1032}, { 1113, 1033}, { 1114, 1034}, -{ 1115, 1035}, { 1116, 1036}, { 1117, 1037}, { 1118, 1038}, { 1119, 1039}, { 1121, 1120}, { 1123, 1122}, { 1125, 1124}, -{ 1127, 1126}, { 1129, 1128}, { 1131, 1130}, { 1133, 1132}, { 1135, 1134}, { 1137, 1136}, { 1139, 1138}, -{ 1141, 1140}, { 1143, 1142}, { 1145, 1144}, { 1147, 1146}, { 1149, 1148}, { 1151, 1150}, { 1153, 1152}, -{ 1169, 1168}, { 1171, 1170}, { 1173, 1172}, { 1175, 1174}, { 1177, 1176}, { 1179, 1178}, { 1181, 1180}, -{ 1183, 1182}, { 1185, 1184}, { 1187, 1186}, { 1189, 1188}, { 1191, 1190}, { 1193, 1192}, { 1195, 1194}, -{ 1197, 1196}, { 1199, 1198}, { 1201, 1200}, { 1203, 1202}, { 1205, 1204}, { 1207, 1206}, { 1209, 1208}, -{ 1211, 1210}, { 1213, 1212}, { 1215, 1214}, { 1218, 1217}, { 1220, 1219}, { 1224, 1223}, { 1228, 1227}, -{ 1233, 1232}, { 1235, 1234}, { 1237, 1236}, { 1239, 1238}, { 1241, 1240}, { 1243, 1242}, { 1245, 1244}, -{ 1247, 1246}, { 1249, 1248}, { 1251, 1250}, { 1253, 1252}, { 1255, 1254}, { 1257, 1256}, { 1259, 1258}, -{ 1263, 1262}, { 1265, 1264}, { 1267, 1266}, { 1269, 1268}, { 1273, 1272}, { 1377, 1329}, { 1378, 1330}, -{ 1379, 1331}, { 1380, 1332}, { 1381, 1333}, { 1382, 1334}, { 1383, 1335}, { 1384, 1336}, { 1385, 1337}, -{ 1386, 1338}, { 1387, 1339}, { 1388, 1340}, { 1389, 1341}, { 1390, 1342}, { 1391, 1343}, { 1392, 1344}, -{ 1393, 1345}, { 1394, 1346}, { 1395, 1347}, { 1396, 1348}, { 1397, 1349}, { 1398, 1350}, { 1399, 1351}, -{ 1400, 1352}, { 1401, 1353}, { 1402, 1354}, { 1403, 1355}, { 1404, 1356}, { 1405, 1357}, { 1406, 1358}, -{ 1407, 1359}, { 1408, 1360}, { 1409, 1361}, { 1410, 1362}, { 1411, 1363}, { 1412, 1364}, { 1413, 1365}, -{ 1414, 1366}, { 7681, 7680}, { 7683, 7682}, { 7685, 7684}, { 7687, 7686}, { 7689, 7688}, { 7691, 7690}, -{ 7693, 7692}, { 7695, 7694}, { 7697, 7696}, { 7699, 7698}, { 7701, 7700}, { 7703, 7702}, { 7705, 7704}, -{ 7707, 7706}, { 7709, 7708}, { 7711, 7710}, { 7713, 7712}, { 7715, 7714}, { 7717, 7716}, { 7719, 7718}, -{ 7721, 7720}, { 7723, 7722}, { 7725, 7724}, { 7727, 7726}, { 7729, 7728}, { 7731, 7730}, { 7733, 7732}, -{ 7735, 7734}, { 7737, 7736}, { 7739, 7738}, { 7741, 7740}, { 7743, 7742}, { 7745, 7744}, { 7747, 7746}, -{ 7749, 7748}, { 7751, 7750}, { 7753, 7752}, { 7755, 7754}, { 7757, 7756}, { 7759, 7758}, { 7761, 7760}, -{ 7763, 7762}, { 7765, 7764}, { 7767, 7766}, { 7769, 7768}, { 7771, 7770}, { 7773, 7772}, { 7775, 7774}, -{ 7777, 7776}, { 7779, 7778}, { 7781, 7780}, { 7783, 7782}, { 7785, 7784}, { 7787, 7786}, { 7789, 7788}, -{ 7791, 7790}, { 7793, 7792}, { 7795, 7794}, { 7797, 7796}, { 7799, 7798}, { 7801, 7800}, { 7803, 7802}, -{ 7805, 7804}, { 7807, 7806}, { 7809, 7808}, { 7811, 7810}, { 7813, 7812}, { 7815, 7814}, { 7817, 7816}, -{ 7819, 7818}, { 7821, 7820}, { 7823, 7822}, { 7825, 7824}, { 7827, 7826}, { 7829, 7828}, { 7841, 7840}, -{ 7843, 7842}, { 7845, 7844}, { 7847, 7846}, { 7849, 7848}, { 7851, 7850}, { 7853, 7852}, { 7855, 7854}, -{ 7857, 7856}, { 7859, 7858}, { 7861, 7860}, { 7863, 7862}, { 7865, 7864}, { 7867, 7866}, { 7869, 7868}, -{ 7871, 7870}, { 7873, 7872}, { 7875, 7874}, { 7877, 7876}, { 7879, 7878}, { 7881, 7880}, { 7883, 7882}, -{ 7885, 7884}, { 7887, 7886}, { 7889, 7888}, { 7891, 7890}, { 7893, 7892}, { 7895, 7894}, { 7897, 7896}, -{ 7899, 7898}, { 7901, 7900}, { 7903, 7902}, { 7905, 7904}, { 7907, 7906}, { 7909, 7908}, { 7911, 7910}, -{ 7913, 7912}, { 7915, 7914}, { 7917, 7916}, { 7919, 7918}, { 7921, 7920}, { 7923, 7922}, { 7925, 7924}, -{ 7927, 7926}, { 7929, 7928}, { 7936, 7944}, { 7937, 7945}, { 7938, 7946}, { 7939, 7947}, { 7940, 7948}, -{ 7941, 7949}, { 7942, 7950}, { 7943, 7951}, { 7952, 7960}, { 7953, 7961}, { 7954, 7962}, { 7955, 7963}, -{ 7956, 7964}, { 7957, 7965}, { 7968, 7976}, { 7969, 7977}, { 7970, 7978}, { 7971, 7979}, { 7972, 7980}, -{ 7973, 7981}, { 7974, 7982}, { 7975, 7983}, { 7984, 7992}, { 7985, 7993}, { 7986, 7994}, { 7987, 7995}, -{ 7988, 7996}, { 7989, 7997}, { 7990, 7998}, { 7991, 7999}, { 8000, 8008}, { 8001, 8009}, { 8002, 8010}, -{ 8003, 8011}, { 8004, 8012}, { 8005, 8013}, { 8017, 8025}, { 8019, 8027}, { 8021, 8029}, { 8023, 8031}, -{ 8032, 8040}, { 8033, 8041}, { 8034, 8042}, { 8035, 8043}, { 8036, 8044}, { 8037, 8045}, { 8038, 8046}, -{ 8039, 8047}, { 8048, 8122}, { 8049, 8123}, { 8050, 8136}, { 8051, 8137}, { 8052, 8138}, { 8053, 8139}, -{ 8054, 8154}, { 8055, 8155}, { 8056, 8184}, { 8057, 8185}, { 8058, 8170}, { 8059, 8171}, { 8060, 8186}, -{ 8061, 8187}, { 8112, 8120}, { 8113, 8121}, { 8144, 8152}, { 8145, 8153}, { 8160, 8168}, { 8161, 8169}, -{ 8165, 8172}, { 8560, 8544}, { 8561, 8545}, { 8562, 8546}, { 8563, 8547}, { 8564, 8548}, { 8565, 8549}, -{ 8566, 8550}, { 8567, 8551}, { 8568, 8552}, { 8569, 8553}, { 8570, 8554}, { 8571, 8555}, { 8572, 8556}, -{ 8573, 8557}, { 8574, 8558}, { 8575, 8559}, { 9424, 9398}, { 9425, 9399}, { 9426, 9400}, { 9427, 9401}, -{ 9428, 9402}, { 9429, 9403}, { 9430, 9404}, { 9431, 9405}, { 9432, 9406}, { 9433, 9407}, { 9434, 9408}, -{ 9435, 9409}, { 9436, 9410}, { 9437, 9411}, { 9438, 9412}, { 9439, 9413}, { 9440, 9414}, { 9441, 9415}, -{ 9442, 9416}, { 9443, 9417}, { 9444, 9418}, { 9445, 9419}, { 9446, 9420}, { 9447, 9421}, { 9448, 9422}, -{ 9449, 9423}, {65345,65313}, {65346,65314}, {65347,65315}, {65348,65316}, {65349,65317}, {65350,65318}, -{65351,65319}, {65352,65320}, {65353,65321}, {65354,65322}, {65355,65323}, {65356,65324}, {65357,65325}, -{65358,65326}, {65359,65327}, {65360,65328}, {65361,65329}, {65362,65330}, {65363,65331}, {65364,65332}, -{65365,65333}, {65366,65334}, {65367,65335}, {65368,65336}, {65369,65337}, {65370,65338}, {65535, 0}}; - -static const GUnicodePairType UnicodeToLowerTable[] = { -{ 65, 97}, { 66, 98}, { 67, 99}, { 68, 100}, { 69, 101}, { 70, 102}, { 71, 103}, -{ 72, 104}, { 73, 105}, { 74, 106}, { 75, 107}, { 76, 108}, { 77, 109}, { 78, 110}, -{ 79, 111}, { 80, 112}, { 81, 113}, { 82, 114}, { 83, 115}, { 84, 116}, { 85, 117}, -{ 86, 118}, { 87, 119}, { 88, 120}, { 89, 121}, { 90, 122}, { 192, 224}, { 193, 225}, -{ 194, 226}, { 195, 227}, { 196, 228}, { 197, 229}, { 198, 230}, { 199, 231}, { 200, 232}, -{ 201, 233}, { 202, 234}, { 203, 235}, { 204, 236}, { 205, 237}, { 206, 238}, { 207, 239}, -{ 208, 240}, { 209, 241}, { 210, 242}, { 211, 243}, { 212, 244}, { 213, 245}, { 214, 246}, -{ 216, 248}, { 217, 249}, { 218, 250}, { 219, 251}, { 220, 252}, { 221, 253}, { 222, 254}, -{ 256, 257}, { 258, 259}, { 260, 261}, { 262, 263}, { 264, 265}, { 266, 267}, { 268, 269}, -{ 270, 271}, { 272, 273}, { 274, 275}, { 276, 277}, { 278, 279}, { 280, 281}, { 282, 283}, -{ 284, 285}, { 286, 287}, { 288, 289}, { 290, 291}, { 292, 293}, { 294, 295}, { 296, 297}, -{ 298, 299}, { 300, 301}, { 302, 303}, { 304, 105}, { 306, 307}, { 308, 309}, { 310, 311}, { 313, 314}, -{ 315, 316}, { 317, 318}, { 319, 320}, { 321, 322}, { 323, 324}, { 325, 326}, { 327, 328}, -{ 330, 331}, { 332, 333}, { 334, 335}, { 336, 337}, { 338, 339}, { 340, 341}, { 342, 343}, -{ 344, 345}, { 346, 347}, { 348, 349}, { 350, 351}, { 352, 353}, { 354, 355}, { 356, 357}, -{ 358, 359}, { 360, 361}, { 362, 363}, { 364, 365}, { 366, 367}, { 368, 369}, { 370, 371}, -{ 372, 373}, { 374, 375}, { 376, 255}, { 377, 378}, { 379, 380}, { 381, 382}, { 385, 595}, -{ 386, 387}, { 388, 389}, { 390, 596}, { 391, 392}, { 393, 598}, { 394, 599}, { 395, 396}, -{ 398, 477}, { 399, 601}, { 400, 603}, { 401, 402}, { 403, 608}, { 404, 611}, { 406, 617}, -{ 407, 616}, { 408, 409}, { 412, 623}, { 413, 626}, { 415, 629}, { 416, 417}, { 418, 419}, -{ 420, 421}, { 423, 424}, { 425, 643}, { 428, 429}, { 430, 648}, { 431, 432}, { 433, 650}, -{ 434, 651}, { 435, 436}, { 437, 438}, { 439, 658}, { 440, 441}, { 444, 445}, { 452, 454}, -{ 455, 457}, { 458, 460}, { 461, 462}, { 463, 464}, { 465, 466}, { 467, 468}, { 469, 470}, -{ 471, 472}, { 473, 474}, { 475, 476}, { 478, 479}, { 480, 481}, { 482, 483}, { 484, 485}, -{ 486, 487}, { 488, 489}, { 490, 491}, { 492, 493}, { 494, 495}, { 497, 499}, { 500, 501}, -{ 506, 507}, { 508, 509}, { 510, 511}, { 512, 513}, { 514, 515}, { 516, 517}, { 518, 519}, -{ 520, 521}, { 522, 523}, { 524, 525}, { 526, 527}, { 528, 529}, { 530, 531}, { 532, 533}, -{ 534, 535}, { 902, 940}, { 904, 941}, { 905, 942}, { 906, 943}, { 908, 972}, { 910, 973}, -{ 911, 974}, { 913, 945}, { 914, 946}, { 915, 947}, { 916, 948}, { 917, 949}, { 918, 950}, -{ 919, 951}, { 920, 952}, { 921, 953}, { 922, 954}, { 923, 955}, { 924, 956}, { 925, 957}, -{ 926, 958}, { 927, 959}, { 928, 960}, { 929, 961}, { 931, 963}, { 932, 964}, { 933, 965}, -{ 934, 966}, { 935, 967}, { 936, 968}, { 937, 969}, { 938, 970}, { 939, 971}, { 994, 995}, -{ 996, 997}, { 998, 999}, { 1000, 1001}, { 1002, 1003}, { 1004, 1005}, { 1006, 1007}, { 1024, 1104}, { 1025, 1105}, -{ 1026, 1106}, { 1027, 1107}, { 1028, 1108}, { 1029, 1109}, { 1030, 1110}, { 1031, 1111}, { 1032, 1112}, -{ 1033, 1113}, { 1034, 1114}, { 1035, 1115}, { 1036, 1116}, { 1037, 1117}, { 1038, 1118}, { 1039, 1119}, { 1040, 1072}, -{ 1041, 1073}, { 1042, 1074}, { 1043, 1075}, { 1044, 1076}, { 1045, 1077}, { 1046, 1078}, { 1047, 1079}, -{ 1048, 1080}, { 1049, 1081}, { 1050, 1082}, { 1051, 1083}, { 1052, 1084}, { 1053, 1085}, { 1054, 1086}, -{ 1055, 1087}, { 1056, 1088}, { 1057, 1089}, { 1058, 1090}, { 1059, 1091}, { 1060, 1092}, { 1061, 1093}, -{ 1062, 1094}, { 1063, 1095}, { 1064, 1096}, { 1065, 1097}, { 1066, 1098}, { 1067, 1099}, { 1068, 1100}, -{ 1069, 1101}, { 1070, 1102}, { 1071, 1103}, { 1120, 1121}, { 1122, 1123}, { 1124, 1125}, { 1126, 1127}, -{ 1128, 1129}, { 1130, 1131}, { 1132, 1133}, { 1134, 1135}, { 1136, 1137}, { 1138, 1139}, { 1140, 1141}, -{ 1142, 1143}, { 1144, 1145}, { 1146, 1147}, { 1148, 1149}, { 1150, 1151}, { 1152, 1153}, { 1168, 1169}, -{ 1170, 1171}, { 1172, 1173}, { 1174, 1175}, { 1176, 1177}, { 1178, 1179}, { 1180, 1181}, { 1182, 1183}, -{ 1184, 1185}, { 1186, 1187}, { 1188, 1189}, { 1190, 1191}, { 1192, 1193}, { 1194, 1195}, { 1196, 1197}, -{ 1198, 1199}, { 1200, 1201}, { 1202, 1203}, { 1204, 1205}, { 1206, 1207}, { 1208, 1209}, { 1210, 1211}, -{ 1212, 1213}, { 1214, 1215}, { 1217, 1218}, { 1219, 1220}, { 1223, 1224}, { 1227, 1228}, { 1232, 1233}, -{ 1234, 1235}, { 1236, 1237}, { 1238, 1239}, { 1240, 1241}, { 1242, 1243}, { 1244, 1245}, { 1246, 1247}, -{ 1248, 1249}, { 1250, 1251}, { 1252, 1253}, { 1254, 1255}, { 1256, 1257}, { 1258, 1259}, { 1262, 1263}, -{ 1264, 1265}, { 1266, 1267}, { 1268, 1269}, { 1272, 1273}, { 1329, 1377}, { 1330, 1378}, { 1331, 1379}, -{ 1332, 1380}, { 1333, 1381}, { 1334, 1382}, { 1335, 1383}, { 1336, 1384}, { 1337, 1385}, { 1338, 1386}, -{ 1339, 1387}, { 1340, 1388}, { 1341, 1389}, { 1342, 1390}, { 1343, 1391}, { 1344, 1392}, { 1345, 1393}, -{ 1346, 1394}, { 1347, 1395}, { 1348, 1396}, { 1349, 1397}, { 1350, 1398}, { 1351, 1399}, { 1352, 1400}, -{ 1353, 1401}, { 1354, 1402}, { 1355, 1403}, { 1356, 1404}, { 1357, 1405}, { 1358, 1406}, { 1359, 1407}, -{ 1360, 1408}, { 1361, 1409}, { 1362, 1410}, { 1363, 1411}, { 1364, 1412}, { 1365, 1413}, { 1366, 1414}, -{ 4256, 4304}, { 4257, 4305}, { 4258, 4306}, { 4259, 4307}, { 4260, 4308}, { 4261, 4309}, { 4262, 4310}, -{ 4263, 4311}, { 4264, 4312}, { 4265, 4313}, { 4266, 4314}, { 4267, 4315}, { 4268, 4316}, { 4269, 4317}, -{ 4270, 4318}, { 4271, 4319}, { 4272, 4320}, { 4273, 4321}, { 4274, 4322}, { 4275, 4323}, { 4276, 4324}, -{ 4277, 4325}, { 4278, 4326}, { 4279, 4327}, { 4280, 4328}, { 4281, 4329}, { 4282, 4330}, { 4283, 4331}, -{ 4284, 4332}, { 4285, 4333}, { 4286, 4334}, { 4287, 4335}, { 4288, 4336}, { 4289, 4337}, { 4290, 4338}, -{ 4291, 4339}, { 4292, 4340}, { 4293, 4341}, { 7680, 7681}, { 7682, 7683}, { 7684, 7685}, { 7686, 7687}, -{ 7688, 7689}, { 7690, 7691}, { 7692, 7693}, { 7694, 7695}, { 7696, 7697}, { 7698, 7699}, { 7700, 7701}, -{ 7702, 7703}, { 7704, 7705}, { 7706, 7707}, { 7708, 7709}, { 7710, 7711}, { 7712, 7713}, { 7714, 7715}, -{ 7716, 7717}, { 7718, 7719}, { 7720, 7721}, { 7722, 7723}, { 7724, 7725}, { 7726, 7727}, { 7728, 7729}, -{ 7730, 7731}, { 7732, 7733}, { 7734, 7735}, { 7736, 7737}, { 7738, 7739}, { 7740, 7741}, { 7742, 7743}, -{ 7744, 7745}, { 7746, 7747}, { 7748, 7749}, { 7750, 7751}, { 7752, 7753}, { 7754, 7755}, { 7756, 7757}, -{ 7758, 7759}, { 7760, 7761}, { 7762, 7763}, { 7764, 7765}, { 7766, 7767}, { 7768, 7769}, { 7770, 7771}, -{ 7772, 7773}, { 7774, 7775}, { 7776, 7777}, { 7778, 7779}, { 7780, 7781}, { 7782, 7783}, { 7784, 7785}, -{ 7786, 7787}, { 7788, 7789}, { 7790, 7791}, { 7792, 7793}, { 7794, 7795}, { 7796, 7797}, { 7798, 7799}, -{ 7800, 7801}, { 7802, 7803}, { 7804, 7805}, { 7806, 7807}, { 7808, 7809}, { 7810, 7811}, { 7812, 7813}, -{ 7814, 7815}, { 7816, 7817}, { 7818, 7819}, { 7820, 7821}, { 7822, 7823}, { 7824, 7825}, { 7826, 7827}, -{ 7828, 7829}, { 7840, 7841}, { 7842, 7843}, { 7844, 7845}, { 7846, 7847}, { 7848, 7849}, { 7850, 7851}, -{ 7852, 7853}, { 7854, 7855}, { 7856, 7857}, { 7858, 7859}, { 7860, 7861}, { 7862, 7863}, { 7864, 7865}, -{ 7866, 7867}, { 7868, 7869}, { 7870, 7871}, { 7872, 7873}, { 7874, 7875}, { 7876, 7877}, { 7878, 7879}, -{ 7880, 7881}, { 7882, 7883}, { 7884, 7885}, { 7886, 7887}, { 7888, 7889}, { 7890, 7891}, { 7892, 7893}, -{ 7894, 7895}, { 7896, 7897}, { 7898, 7899}, { 7900, 7901}, { 7902, 7903}, { 7904, 7905}, { 7906, 7907}, -{ 7908, 7909}, { 7910, 7911}, { 7912, 7913}, { 7914, 7915}, { 7916, 7917}, { 7918, 7919}, { 7920, 7921}, -{ 7922, 7923}, { 7924, 7925}, { 7926, 7927}, { 7928, 7929}, { 7944, 7936}, { 7945, 7937}, { 7946, 7938}, -{ 7947, 7939}, { 7948, 7940}, { 7949, 7941}, { 7950, 7942}, { 7951, 7943}, { 7960, 7952}, { 7961, 7953}, -{ 7962, 7954}, { 7963, 7955}, { 7964, 7956}, { 7965, 7957}, { 7976, 7968}, { 7977, 7969}, { 7978, 7970}, -{ 7979, 7971}, { 7980, 7972}, { 7981, 7973}, { 7982, 7974}, { 7983, 7975}, { 7992, 7984}, { 7993, 7985}, -{ 7994, 7986}, { 7995, 7987}, { 7996, 7988}, { 7997, 7989}, { 7998, 7990}, { 7999, 7991}, { 8008, 8000}, -{ 8009, 8001}, { 8010, 8002}, { 8011, 8003}, { 8012, 8004}, { 8013, 8005}, { 8025, 8017}, { 8027, 8019}, -{ 8029, 8021}, { 8031, 8023}, { 8040, 8032}, { 8041, 8033}, { 8042, 8034}, { 8043, 8035}, { 8044, 8036}, -{ 8045, 8037}, { 8046, 8038}, { 8047, 8039}, { 8120, 8112}, { 8121, 8113}, { 8122, 8048}, { 8123, 8049}, -{ 8136, 8050}, { 8137, 8051}, { 8138, 8052}, { 8139, 8053}, { 8152, 8144}, { 8153, 8145}, { 8154, 8054}, -{ 8155, 8055}, { 8168, 8160}, { 8169, 8161}, { 8170, 8058}, { 8171, 8059}, { 8172, 8165}, { 8184, 8056}, -{ 8185, 8057}, { 8186, 8060}, { 8187, 8061}, { 8544, 8560}, { 8545, 8561}, { 8546, 8562}, { 8547, 8563}, -{ 8548, 8564}, { 8549, 8565}, { 8550, 8566}, { 8551, 8567}, { 8552, 8568}, { 8553, 8569}, { 8554, 8570}, -{ 8555, 8571}, { 8556, 8572}, { 8557, 8573}, { 8558, 8574}, { 8559, 8575}, { 9398, 9424}, { 9399, 9425}, -{ 9400, 9426}, { 9401, 9427}, { 9402, 9428}, { 9403, 9429}, { 9404, 9430}, { 9405, 9431}, { 9406, 9432}, -{ 9407, 9433}, { 9408, 9434}, { 9409, 9435}, { 9410, 9436}, { 9411, 9437}, { 9412, 9438}, { 9413, 9439}, -{ 9414, 9440}, { 9415, 9441}, { 9416, 9442}, { 9417, 9443}, { 9418, 9444}, { 9419, 9445}, { 9420, 9446}, -{ 9421, 9447}, { 9422, 9448}, { 9423, 9449}, {65313,65345}, {65314,65346}, {65315,65347}, {65316,65348}, -{65317,65349}, {65318,65350}, {65319,65351}, {65320,65352}, {65321,65353}, {65322,65354}, {65323,65355}, -{65324,65356}, {65325,65357}, {65326,65358}, {65327,65359}, {65328,65360}, {65329,65361}, {65330,65362}, -{65331,65363}, {65332,65364}, {65333,65365}, {65334,65366}, {65335,65367}, {65336,65368}, {65337,65369}, -{65338,65370}, {65535, 0}}; - -int OVR_CDECL OVR_towupper(wchar_t charCode) -{ - // Don't use UnicodeUpperBits! It differs from UnicodeToUpperBits. - if (UnicodeCharIs(UnicodeToUpperBits, charCode)) - { - // To protect from memory overrun in case the character is not found - // we use one extra fake element in the table {65536, 0}. - size_t idx = Alg::LowerBoundSliced( - UnicodeToUpperTable, - 0, - sizeof(UnicodeToUpperTable) / sizeof(UnicodeToUpperTable[0]) - 1, - (uint16_t)charCode, - CmpUnicodeKey); - return UnicodeToUpperTable[idx].Value; - } - return charCode; -} - -int OVR_CDECL OVR_towlower(wchar_t charCode) -{ - // Don't use UnicodeLowerBits! It differs from UnicodeToLowerBits. - if (UnicodeCharIs(UnicodeToLowerBits, charCode)) - { - // To protect from memory overrun in case the character is not found - // we use one extra fake element in the table {65536, 0}. - size_t idx = Alg::LowerBoundSliced( - UnicodeToLowerTable, - 0, - sizeof(UnicodeToLowerTable) / sizeof(UnicodeToLowerTable[0]) - 1, - (uint16_t)charCode, - CmpUnicodeKey); - return UnicodeToLowerTable[idx].Value; - } - return charCode; -} - -#endif //OVR_NO_WCTYPE - -} // OVR diff --git a/LibOVR/Src/Kernel/OVR_Std.h b/LibOVR/Src/Kernel/OVR_Std.h deleted file mode 100644 index 6a14231..0000000 --- a/LibOVR/Src/Kernel/OVR_Std.h +++ /dev/null @@ -1,638 +0,0 @@ -/************************************************************************************ - -PublicHeader: OVR_Kernel.h -Filename : OVR_Std.h -Content : Standard C function interface -Created : September 19, 2012 -Notes : - -Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); -you may not use the Oculus VR Rift SDK except in compliance with the License, -which is provided at the time of installation or download, or which -otherwise accompanies this software in either electronic or hard copy form. - -You may obtain a copy of the License at - -http://www.oculusvr.com/licenses/LICENSE-3.2 - -Unless required by applicable law or agreed to in writing, the Oculus VR SDK -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -************************************************************************************/ - -#ifndef OVR_Std_h -#define OVR_Std_h - -#include "OVR_Types.h" -#include <stdarg.h> // for va_list args -#include <string.h> -#include <stdio.h> -#include <stdlib.h> -#include <ctype.h> - -#if defined(OVR_CC_MSVC) && (OVR_CC_MSVC >= 1400) -#define OVR_MSVC_SAFESTRING -#include <errno.h> -#endif - -// Wide-char funcs -#include <wchar.h> -#include <wctype.h> - -namespace OVR { - -// Has the same behavior as itoa aside from also having a dest size argument. -// Return value: Pointer to the resulting null-terminated string, same as parameter str. -#if defined(OVR_OS_MS) -inline char* OVR_CDECL OVR_itoa(int val, char *dest, size_t destsize, int radix) -{ -#if defined(OVR_MSVC_SAFESTRING) - _itoa_s(val, dest, destsize, radix); - return dest; -#else - OVR_UNUSED(destsize); - return itoa(val, dest, radix); -#endif -} -#else // OVR_OS_MS -inline char* OVR_itoa(int val, char* dest, size_t len, int radix) -{ - if (val == 0) - { - if (len > 1) - { - dest[0] = '0'; - dest[1] = '\0'; - } - else if(len > 0) - dest[0] = '\0'; - return dest; - } - - // FIXME: Fix the following code to avoid memory write overruns when len is in sufficient. - int cur = val; - size_t i = 0; - size_t sign = 0; - - if (val < 0) - { - val = -val; - sign = 1; - } - - while ((val != 0) && (i < (len - 1 - sign))) - { - cur = val % radix; - val /= radix; - - if (radix == 16) - { - switch(cur) - { - case 10: - dest[i] = 'a'; - break; - case 11: - dest[i] = 'b'; - break; - case 12: - dest[i] = 'c'; - break; - case 13: - dest[i] = 'd'; - break; - case 14: - dest[i] = 'e'; - break; - case 15: - dest[i] = 'f'; - break; - default: - dest[i] = (char)('0' + cur); - break; - } - } - else - { - dest[i] = (char)('0' + cur); - } - ++i; - } - - if (sign) - { - dest[i++] = '-'; - } - - for (size_t j = 0; j < i / 2; ++j) - { - char tmp = dest[j]; - dest[j] = dest[i - 1 - j]; - dest[i - 1 - j] = tmp; - } - dest[i] = '\0'; - - return dest; -} - -#endif - - -// String functions - -inline size_t OVR_CDECL OVR_strlen(const char* str) -{ - return strlen(str); -} - -inline char* OVR_CDECL OVR_strcpy(char* dest, size_t destsize, const char* src) -{ -#if defined(OVR_MSVC_SAFESTRING) - strcpy_s(dest, destsize, src); - return dest; -#else - // FIXME: This should be a safer implementation - OVR_UNUSED(destsize); - return strcpy(dest, src); -#endif -} - - -// Acts the same as the strlcpy function. -// Copies src to dest, 0-terminating even if it involves truncating the write. -// Returns the required strlen of dest (which is one less than the required size of dest). -// strlcpy is a safer alternative to strcpy and strncpy and provides size information. -// However, it still may result in an incomplete copy. -// -// Example usage: -// char buffer[256]; -// if(OVR_strlcpy(buffer, "hello world", sizeof(buffer)) < sizeof(buffer)) -// { there was enough space } -// else -// { need a larger buffer } -// -size_t OVR_CDECL OVR_strlcpy(char* dest, const char* src, size_t destsize); - -// Acts the same as the strlcat function. -// Appends src to dest, 0-terminating even if it involves an incomplete write. -// Doesn't 0-terminate in the case that destsize is 0. -// Returns the required strlen of dest (which is one less than the required size of dest). -// The terminating 0 char of dest is overwritten by the first -// character of src, and a new 0 char is appended to dest. The required capacity -// of the destination is (strlen(src) + strlen(dest) + 1). -// strlcat is a safer alternative to strcat and provides size information. -// However, it still may result in an incomplete copy. -// -// Example usage: -// char buffer[256] = "hello "; -// if(OVR_strlcat(buffer, "world", sizeof(buffer)) < sizeof(buffer)) -// { there was enough space } -// else -// { need a larger buffer } -// -size_t OVR_CDECL OVR_strlcat(char* dest, const char* src, size_t destsize); - - -inline char* OVR_CDECL OVR_strncpy(char* dest, size_t destsize, const char* src, size_t count) -{ -#if defined(OVR_MSVC_SAFESTRING) - strncpy_s(dest, destsize, src, count); - return dest; -#else - // FIXME: This should be a safer implementation - OVR_UNUSED(destsize); - return strncpy(dest, src, count); -#endif -} - -inline char * OVR_CDECL OVR_strcat(char* dest, size_t destsize, const char* src) -{ -#if defined(OVR_MSVC_SAFESTRING) - strcat_s(dest, destsize, src); - return dest; -#else - // FIXME: This should be a safer implementation - OVR_UNUSED(destsize); - return strcat(dest, src); -#endif -} - -inline int OVR_CDECL OVR_strcmp(const char* dest, const char* src) -{ - return strcmp(dest, src); -} - -inline const char* OVR_CDECL OVR_strchr(const char* str, char c) -{ - return strchr(str, c); -} - -inline char* OVR_CDECL OVR_strchr(char* str, char c) -{ - return strchr(str, c); -} - -inline const char* OVR_strrchr(const char* str, char c) -{ - size_t len = OVR_strlen(str); - for (size_t i=len; i>0; i--) - if (str[i]==c) - return str+i; - return 0; -} - -inline const uint8_t* OVR_CDECL OVR_memrchr(const uint8_t* str, size_t size, uint8_t c) -{ - for (intptr_t i = (intptr_t)size - 1; i >= 0; i--) - { - if (str[i] == c) - return str + i; - } - return 0; -} - -inline char* OVR_CDECL OVR_strrchr(char* str, char c) -{ - size_t len = OVR_strlen(str); - for (size_t i=len; i>0; i--) - if (str[i]==c) - return str+i; - return 0; -} - - -double OVR_CDECL OVR_strtod(const char* string, char** tailptr); - -inline long OVR_CDECL OVR_strtol(const char* string, char** tailptr, int radix) -{ - return strtol(string, tailptr, radix); -} - -inline long OVR_CDECL OVR_strtoul(const char* string, char** tailptr, int radix) -{ - return strtoul(string, tailptr, radix); -} - -inline int OVR_CDECL OVR_strncmp(const char* ws1, const char* ws2, size_t size) -{ - return strncmp(ws1, ws2, size); -} - -inline uint64_t OVR_CDECL OVR_strtouq(const char *nptr, char **endptr, int base) -{ -#if defined(OVR_CC_MSVC) - return _strtoui64(nptr, endptr, base); -#else - return strtoull(nptr, endptr, base); -#endif -} - -inline int64_t OVR_CDECL OVR_strtoq(const char *nptr, char **endptr, int base) -{ -#if defined(OVR_CC_MSVC) - return _strtoi64(nptr, endptr, base); -#else - return strtoll(nptr, endptr, base); -#endif -} - - -inline int64_t OVR_CDECL OVR_atoq(const char* string) -{ -#if defined(OVR_CC_MSVC) - return _atoi64(string); -#else - return atoll(string); -#endif -} - -inline uint64_t OVR_CDECL OVR_atouq(const char* string) -{ - return OVR_strtouq(string, NULL, 10); -} - - -// Implemented in OVR_Std.cpp in platform-specific manner. -int OVR_CDECL OVR_stricmp(const char* dest, const char* src); -int OVR_CDECL OVR_strnicmp(const char* dest, const char* src, size_t count); - - -// This is like sprintf but with a destination buffer size argument. However, the behavior is different -// from vsnprintf in that the return value semantics are like sprintf (which returns -1 on capacity overflow) and -// not like snprintf (which returns intended strlen on capacity overflow). -inline size_t OVR_CDECL OVR_sprintf(char *dest, size_t destsize, const char* format, ...) -{ - va_list argList; - va_start(argList,format); - size_t ret; -#if defined(OVR_CC_MSVC) - #if defined(OVR_MSVC_SAFESTRING) - ret = _vsnprintf_s(dest, destsize, _TRUNCATE, format, argList); - OVR_ASSERT(ret != -1); - #else - OVR_UNUSED(destsize); - ret = _vsnprintf(dest, destsize - 1, format, argList); // -1 for space for the null character - OVR_ASSERT(ret != -1); - dest[destsize-1] = 0; - #endif -#else - OVR_UNUSED(destsize); - ret = vsprintf(dest, format, argList); - OVR_ASSERT(ret < destsize); -#endif - va_end(argList); - return ret; -} - - -// This is like vsprintf but with a destination buffer size argument. However, the behavior is different -// from vsnprintf in that the return value semantics are like vsprintf (which returns -1 on capacity overflow) and -// not like vsnprintf (which returns intended strlen on capacity overflow). -// Return value: -// On success, the total number of characters written is returned. -// On failure, a negative number is returned. -inline size_t OVR_CDECL OVR_vsprintf(char *dest, size_t destsize, const char * format, va_list argList) -{ - size_t ret; -#if defined(OVR_CC_MSVC) - #if defined(OVR_MSVC_SAFESTRING) - dest[0] = '\0'; - int rv = vsnprintf_s(dest, destsize, _TRUNCATE, format, argList); - if (rv == -1) - { - dest[destsize - 1] = '\0'; - ret = destsize - 1; - } - else - ret = (size_t)rv; - #else - OVR_UNUSED(destsize); - int rv = _vsnprintf(dest, destsize - 1, format, argList); - OVR_ASSERT(rv != -1); - ret = (size_t)rv; - dest[destsize-1] = 0; - #endif -#else - // FIXME: This should be a safer implementation - OVR_UNUSED(destsize); - ret = (size_t)vsprintf(dest, format, argList); - OVR_ASSERT(ret < destsize); -#endif - return ret; -} - -// Same behavior as ISO C99 vsnprintf. -// Returns the strlen of the resulting formatted string, or a negative value if the format is invalid. -// destsize specifies the capacity of the input buffer. -// -// Example usage: -// void Log(char *dest, size_t destsize, const char * format, ...) -// { -// char buffer[1024]; -// va_list argList; -// va_start(argList,format); -// int result = OVR_vsnprintf(dest, destsize, format, argList); -// assert(result < destsize); // Else we'd have to retry with a dynamically allocated buffer (of size=result+1) and new argList copy. -// va_end(argList); -// } - -inline int OVR_CDECL OVR_vsnprintf(char *dest, size_t destsize, const char * format, va_list argList) -{ - int ret; -#if defined(OVR_CC_MSVC) - OVR_DISABLE_MSVC_WARNING(4996) // 'vsnprintf': This function or variable may be unsafe. - ret = vsnprintf(dest, destsize, format, argList); // Microsoft vsnprintf is non-conforming; it returns -1 if destsize is insufficient. - if (ret < 0) // If there was a format error or if destsize was insufficient... - { - ret = _vscprintf(format, argList); // Get the expected dest strlen. If the return value is still -1 then there was a format error. - - if (destsize) // If we can 0-terminate the output... - { - if (ret < 0) - dest[0] = 0; - else - dest[destsize-1] = 0; - } - } - // Else the string was written OK and ret is its strlen. - OVR_RESTORE_MSVC_WARNING() -#else - ret = vsnprintf(dest, destsize, format, argList); -#endif - return ret; -} - - -// Same behavior as ISO C99 snprintf. -// Returns the strlen of the resulting formatted string, or a negative value if the format is invalid. -// destsize specifies the capacity of the input buffer. -// -// Example usage: -// char buffer[16]; -// int result = OVR_snprintf(buffer, sizeof(buffer), "%d", 37); -// if (result >= sizeof(buffer)) // If there was insufficient capacity... -// { -// char* p = new char[result + 1]; // Or char* p = (char*)OVR_ALLOC(result + 1); -// OVR_snprintf(p, (size_t)result, "%d", 37); -// delete[] p; -// } -// -inline int OVR_CDECL OVR_snprintf(char *dest, size_t destsize, const char * format, ...) -{ - va_list argList; - va_start(argList,format); - int ret = OVR_vsnprintf(dest, destsize, format, argList); - va_end(argList); - return ret; -} - - -// Returns the strlen of the resulting formatted string, or a negative value if the format is invalid. -// Note: If you are planning on printing a string then it's more efficient to just use OVR_vsnprintf and -// look at the return value and handle the uncommon case that there wasn't enough space. -inline int OVR_CDECL OVR_vscprintf(const char * format, va_list argList) -{ - int ret; -#if defined(OVR_CC_MSVC) - ret = _vscprintf(format, argList); -#else - ret = vsnprintf(NULL, 0, format, argList); -#endif - return ret; -} - - -wchar_t* OVR_CDECL OVR_wcscpy(wchar_t* dest, size_t destsize, const wchar_t* src); -wchar_t* OVR_CDECL OVR_wcsncpy(wchar_t* dest, size_t destsize, const wchar_t* src, size_t count); -wchar_t* OVR_CDECL OVR_wcscat(wchar_t* dest, size_t destsize, const wchar_t* src); -size_t OVR_CDECL OVR_wcslen(const wchar_t* str); -int OVR_CDECL OVR_wcscmp(const wchar_t* a, const wchar_t* b); -int OVR_CDECL OVR_wcsicmp(const wchar_t* a, const wchar_t* b); - -inline int OVR_CDECL OVR_wcsicoll(const wchar_t* a, const wchar_t* b) -{ -#if defined(OVR_OS_MS) - #if defined(OVR_CC_MSVC) && (OVR_CC_MSVC >= 1400) - return ::_wcsicoll(a, b); - #else - return ::wcsicoll(a, b); - #endif -#else - // not supported, use regular wcsicmp - return OVR_wcsicmp(a, b); -#endif -} - -inline int OVR_CDECL OVR_wcscoll(const wchar_t* a, const wchar_t* b) -{ -#if defined(OVR_OS_MS) || defined(OVR_OS_LINUX) - return wcscoll(a, b); -#else - // not supported, use regular wcscmp - return OVR_wcscmp(a, b); -#endif -} - -#ifndef OVR_NO_WCTYPE - -inline int OVR_CDECL UnicodeCharIs(const uint16_t* table, wchar_t charCode) -{ - unsigned offset = table[charCode >> 8]; - if (offset == 0) return 0; - if (offset == 1) return 1; - return (table[offset + ((charCode >> 4) & 15)] & (1 << (charCode & 15))) != 0; -} - -extern const uint16_t UnicodeAlnumBits[]; -extern const uint16_t UnicodeAlphaBits[]; -extern const uint16_t UnicodeDigitBits[]; -extern const uint16_t UnicodeSpaceBits[]; -extern const uint16_t UnicodeXDigitBits[]; - -// Uncomment if necessary -//extern const uint16_t UnicodeCntrlBits[]; -//extern const uint16_t UnicodeGraphBits[]; -//extern const uint16_t UnicodeLowerBits[]; -//extern const uint16_t UnicodePrintBits[]; -//extern const uint16_t UnicodePunctBits[]; -//extern const uint16_t UnicodeUpperBits[]; - -inline int OVR_CDECL OVR_iswalnum (wchar_t charCode) { return UnicodeCharIs(UnicodeAlnumBits, charCode); } -inline int OVR_CDECL OVR_iswalpha (wchar_t charCode) { return UnicodeCharIs(UnicodeAlphaBits, charCode); } -inline int OVR_CDECL OVR_iswdigit (wchar_t charCode) { return UnicodeCharIs(UnicodeDigitBits, charCode); } -inline int OVR_CDECL OVR_iswspace (wchar_t charCode) { return UnicodeCharIs(UnicodeSpaceBits, charCode); } -inline int OVR_CDECL OVR_iswxdigit(wchar_t charCode) { return UnicodeCharIs(UnicodeXDigitBits, charCode); } - -// Uncomment if necessary -//inline int OVR_CDECL OVR_iswcntrl (wchar_t charCode) { return UnicodeCharIs(UnicodeCntrlBits, charCode); } -//inline int OVR_CDECL OVR_iswgraph (wchar_t charCode) { return UnicodeCharIs(UnicodeGraphBits, charCode); } -//inline int OVR_CDECL OVR_iswlower (wchar_t charCode) { return UnicodeCharIs(UnicodeLowerBits, charCode); } -//inline int OVR_CDECL OVR_iswprint (wchar_t charCode) { return UnicodeCharIs(UnicodePrintBits, charCode); } -//inline int OVR_CDECL OVR_iswpunct (wchar_t charCode) { return UnicodeCharIs(UnicodePunctBits, charCode); } -//inline int OVR_CDECL OVR_iswupper (wchar_t charCode) { return UnicodeCharIs(UnicodeUpperBits, charCode); } - -int OVR_CDECL OVR_towupper(wchar_t charCode); -int OVR_CDECL OVR_towlower(wchar_t charCode); - -#else // OVR_NO_WCTYPE - -inline int OVR_CDECL OVR_iswspace(wchar_t c) -{ - return iswspace(c); -} - -inline int OVR_CDECL OVR_iswdigit(wchar_t c) -{ - return iswdigit(c); -} - -inline int OVR_CDECL OVR_iswxdigit(wchar_t c) -{ - return iswxdigit(c); -} - -inline int OVR_CDECL OVR_iswalpha(wchar_t c) -{ - return iswalpha(c); -} - -inline int OVR_CDECL OVR_iswalnum(wchar_t c) -{ - return iswalnum(c); -} - -inline wchar_t OVR_CDECL OVR_towlower(wchar_t c) -{ - return (wchar_t)towlower(c); -} - -inline wchar_t OVR_towupper(wchar_t c) -{ - return (wchar_t)towupper(c); -} - -#endif // OVR_NO_WCTYPE - -// ASCII versions of tolower and toupper. Don't use "char" -inline int OVR_CDECL OVR_tolower(int c) -{ - return (c >= 'A' && c <= 'Z') ? c - 'A' + 'a' : c; -} - -inline int OVR_CDECL OVR_toupper(int c) -{ - return (c >= 'a' && c <= 'z') ? c - 'a' + 'A' : c; -} - - - -inline double OVR_CDECL OVR_wcstod(const wchar_t* string, wchar_t** tailptr) -{ -#if defined(OVR_OS_OTHER) - OVR_UNUSED(tailptr); - char buffer[64]; - char* tp = NULL; - size_t max = OVR_wcslen(string); - if (max > 63) max = 63; - unsigned char c = 0; - for (size_t i=0; i < max; i++) - { - c = (unsigned char)string[i]; - buffer[i] = ((c) < 128 ? (char)c : '!'); - } - buffer[max] = 0; - return OVR_strtod(buffer, &tp); -#else - return wcstod(string, tailptr); -#endif -} - -inline long OVR_CDECL OVR_wcstol(const wchar_t* string, wchar_t** tailptr, int radix) -{ -#if defined(OVR_OS_OTHER) - OVR_UNUSED(tailptr); - char buffer[64]; - char* tp = NULL; - size_t max = OVR_wcslen(string); - if (max > 63) max = 63; - unsigned char c = 0; - for (size_t i=0; i < max; i++) - { - c = (unsigned char)string[i]; - buffer[i] = ((c) < 128 ? (char)c : '!'); - } - buffer[max] = 0; - return strtol(buffer, &tp, radix); -#else - return wcstol(string, tailptr, radix); -#endif -} - -} // OVR - -#endif // OVR_Std_h diff --git a/LibOVR/Src/Kernel/OVR_String.cpp b/LibOVR/Src/Kernel/OVR_String.cpp deleted file mode 100644 index a539992..0000000 --- a/LibOVR/Src/Kernel/OVR_String.cpp +++ /dev/null @@ -1,779 +0,0 @@ -/************************************************************************************ - -Filename : OVR_String.cpp -Content : String UTF8 string implementation with copy-on-write semantics - (thread-safe for assignment but not modification). -Created : September 19, 2012 -Notes : - -Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); -you may not use the Oculus VR Rift SDK except in compliance with the License, -which is provided at the time of installation or download, or which -otherwise accompanies this software in either electronic or hard copy form. - -You may obtain a copy of the License at - -http://www.oculusvr.com/licenses/LICENSE-3.2 - -Unless required by applicable law or agreed to in writing, the Oculus VR SDK -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -************************************************************************************/ - -#include "OVR_String.h" - -#include <stdlib.h> -#include <ctype.h> - -#ifdef OVR_OS_QNX -# include <strings.h> -#endif - -namespace OVR { - -#define String_LengthIsSize (size_t(1) << String::Flag_LengthIsSizeShift) - -String::DataDesc String::NullData = {String_LengthIsSize, 1, {0} }; - - -String::String() -{ - pData = &NullData; - pData->AddRef(); -}; - -String::String(const char* pdata) -{ - // Obtain length in bytes; it doesn't matter if _data is UTF8. - size_t size = pdata ? OVR_strlen(pdata) : 0; - pData = AllocDataCopy1(size, 0, pdata, size); -}; - -String::String(const char* pdata1, const char* pdata2, const char* pdata3) -{ - // Obtain length in bytes; it doesn't matter if _data is UTF8. - size_t size1 = pdata1 ? OVR_strlen(pdata1) : 0; - size_t size2 = pdata2 ? OVR_strlen(pdata2) : 0; - size_t size3 = pdata3 ? OVR_strlen(pdata3) : 0; - - DataDesc *pdataDesc = AllocDataCopy2(size1 + size2 + size3, 0, - pdata1, size1, pdata2, size2); - memcpy(pdataDesc->Data + size1 + size2, pdata3, size3); - pData = pdataDesc; -} - -String::String(const char* pdata, size_t size) -{ - OVR_ASSERT((size == 0) || (pdata != 0)); - pData = AllocDataCopy1(size, 0, pdata, size); -}; - - -String::String(const InitStruct& src, size_t size) -{ - pData = AllocData(size, 0); - src.InitString(GetData()->Data, size); -} - -String::String(const String& src) -{ - pData = src.GetData(); - pData->AddRef(); -} - -String::String(const StringBuffer& src) -{ - pData = AllocDataCopy1(src.GetSize(), 0, src.ToCStr(), src.GetSize()); -} - -String::String(const wchar_t* data) -{ - pData = &NullData; - pData->AddRef(); - // Simplified logic for wchar_t constructor. - if (data) - *this = data; -} - - -String::DataDesc* String::AllocData(size_t size, size_t lengthIsSize) -{ - String::DataDesc* pdesc; - - if (size == 0) - { - pdesc = &NullData; - pdesc->AddRef(); - return pdesc; - } - - pdesc = (DataDesc*)OVR_ALLOC(sizeof(DataDesc)+ size); - pdesc->Data[size] = 0; - pdesc->RefCount = 1; - pdesc->Size = size | lengthIsSize; - return pdesc; -} - - -String::DataDesc* String::AllocDataCopy1(size_t size, size_t lengthIsSize, - const char* pdata, size_t copySize) -{ - String::DataDesc* pdesc = AllocData(size, lengthIsSize); - memcpy(pdesc->Data, pdata, copySize); - return pdesc; -} - -String::DataDesc* String::AllocDataCopy2(size_t size, size_t lengthIsSize, - const char* pdata1, size_t copySize1, - const char* pdata2, size_t copySize2) -{ - String::DataDesc* pdesc = AllocData(size, lengthIsSize); - memcpy(pdesc->Data, pdata1, copySize1); - memcpy(pdesc->Data + copySize1, pdata2, copySize2); - return pdesc; -} - - -size_t String::GetLength() const -{ - // Optimize length accesses for non-UTF8 character strings. - DataDesc* pdata = GetData(); - size_t length, size = pdata->GetSize(); - - if (pdata->LengthIsSize()) - return size; - - length = (size_t)UTF8Util::GetLength(pdata->Data, (size_t)size); - - if (length == size) - pdata->Size |= String_LengthIsSize; - - return length; -} - - -//static uint32_t String_CharSearch(const char* buf, ) - - -uint32_t String::GetCharAt(size_t index) const -{ - intptr_t i = (intptr_t) index; - DataDesc* pdata = GetData(); - const char* buf = pdata->Data; - uint32_t c; - - if (pdata->LengthIsSize()) - { - OVR_ASSERT(index < pdata->GetSize()); - buf += i; - return UTF8Util::DecodeNextChar_Advance0(&buf); - } - - c = UTF8Util::GetCharAt(index, buf, pdata->GetSize()); - return c; -} - -uint32_t String::GetFirstCharAt(size_t index, const char** offset) const -{ - DataDesc* pdata = GetData(); - intptr_t i = (intptr_t) index; - const char* buf = pdata->Data; - const char* end = buf + pdata->GetSize(); - uint32_t c; - - do - { - c = UTF8Util::DecodeNextChar_Advance0(&buf); - i--; - - if (buf >= end) - { - // We've hit the end of the string; don't go further. - OVR_ASSERT(i == 0); - return c; - } - } while (i >= 0); - - *offset = buf; - - return c; -} - -uint32_t String::GetNextChar(const char** offset) const -{ - return UTF8Util::DecodeNextChar(offset); -} - - - -void String::AppendChar(uint32_t ch) -{ - DataDesc* pdata = GetData(); - size_t size = pdata->GetSize(); - char buff[8]; - intptr_t encodeSize = 0; - - // Converts ch into UTF8 string and fills it into buff. - UTF8Util::EncodeChar(buff, &encodeSize, ch); - OVR_ASSERT(encodeSize >= 0); - - SetData(AllocDataCopy2(size + (size_t)encodeSize, 0, - pdata->Data, size, buff, (size_t)encodeSize)); - pdata->Release(); -} - - -void String::AppendString(const wchar_t* pstr, intptr_t len) -{ - if (!pstr) - return; - - DataDesc* pdata = GetData(); - size_t oldSize = pdata->GetSize(); - size_t encodeSize = (size_t)UTF8Util::GetEncodeStringSize(pstr, len); - - DataDesc* pnewData = AllocDataCopy1(oldSize + (size_t)encodeSize, 0, - pdata->Data, oldSize); - UTF8Util::EncodeString(pnewData->Data + oldSize, pstr, len); - - SetData(pnewData); - pdata->Release(); -} - - -void String::AppendString(const char* putf8str, intptr_t utf8StrSz) -{ - if (!putf8str || !utf8StrSz) - return; - if (utf8StrSz == -1) - utf8StrSz = (intptr_t)OVR_strlen(putf8str); - - DataDesc* pdata = GetData(); - size_t oldSize = pdata->GetSize(); - - SetData(AllocDataCopy2(oldSize + (size_t)utf8StrSz, 0, - pdata->Data, oldSize, putf8str, (size_t)utf8StrSz)); - pdata->Release(); -} - -void String::AssignString(const InitStruct& src, size_t size) -{ - DataDesc* poldData = GetData(); - DataDesc* pnewData = AllocData(size, 0); - src.InitString(pnewData->Data, size); - SetData(pnewData); - poldData->Release(); -} - -void String::AssignString(const char* putf8str, size_t size) -{ - DataDesc* poldData = GetData(); - SetData(AllocDataCopy1(size, 0, putf8str, size)); - poldData->Release(); -} - -void String::operator = (const char* pstr) -{ - AssignString(pstr, pstr ? OVR_strlen(pstr) : 0); -} - -void String::operator = (const wchar_t* pwstr) -{ - pwstr = pwstr ? pwstr : L""; - - DataDesc* poldData = GetData(); - size_t size = (size_t)UTF8Util::GetEncodeStringSize(pwstr); - - DataDesc* pnewData = AllocData(size, 0); - UTF8Util::EncodeString(pnewData->Data, pwstr); - SetData(pnewData); - poldData->Release(); -} - - -void String::operator = (const String& src) -{ - DataDesc* psdata = src.GetData(); - DataDesc* pdata = GetData(); - - SetData(psdata); - psdata->AddRef(); - pdata->Release(); -} - - -void String::operator = (const StringBuffer& src) -{ - DataDesc* polddata = GetData(); - SetData(AllocDataCopy1(src.GetSize(), 0, src.ToCStr(), src.GetSize())); - polddata->Release(); -} - -void String::operator += (const String& src) -{ - DataDesc *pourData = GetData(), - *psrcData = src.GetData(); - size_t ourSize = pourData->GetSize(), - srcSize = psrcData->GetSize(); - size_t lflag = pourData->GetLengthFlag() & psrcData->GetLengthFlag(); - - SetData(AllocDataCopy2(ourSize + srcSize, lflag, - pourData->Data, ourSize, psrcData->Data, srcSize)); - pourData->Release(); -} - - -String String::operator + (const char* str) const -{ - String tmp1(*this); - tmp1 += (str ? str : ""); - return tmp1; -} - -String String::operator + (const String& src) const -{ - String tmp1(*this); - tmp1 += src; - return tmp1; -} - -void String::Remove(size_t posAt, intptr_t removeLength) -{ - DataDesc* pdata = GetData(); - size_t oldSize = pdata->GetSize(); - // Length indicates the number of characters to remove. - size_t length = GetLength(); - - // If index is past the string, nothing to remove. - if (posAt >= length) - return; - // Otherwise, cap removeLength to the length of the string. - if ((posAt + removeLength) > length) - removeLength = length - posAt; - - // Get the byte position of the UTF8 char at position posAt. - intptr_t bytePos = UTF8Util::GetByteIndex(posAt, pdata->Data, oldSize); - intptr_t removeSize = UTF8Util::GetByteIndex(removeLength, pdata->Data + bytePos, oldSize-bytePos); - - SetData(AllocDataCopy2(oldSize - removeSize, pdata->GetLengthFlag(), - pdata->Data, bytePos, - pData->Data + bytePos + removeSize, (oldSize - bytePos - removeSize))); - pdata->Release(); -} - - -String String::Substring(size_t start, size_t end) const -{ - size_t length = GetLength(); - if ((start >= length) || (start >= end)) - return String(); - - DataDesc* pdata = GetData(); - - // If size matches, we know the exact index range. - if (pdata->LengthIsSize()) - return String(pdata->Data + start, end - start); - - // Get position of starting character. - intptr_t byteStart = UTF8Util::GetByteIndex(start, pdata->Data, pdata->GetSize()); - intptr_t byteSize = UTF8Util::GetByteIndex(end - start, pdata->Data + byteStart, pdata->GetSize()-byteStart); - return String(pdata->Data + byteStart, (size_t)byteSize); -} - -void String::Clear() -{ - NullData.AddRef(); - GetData()->Release(); - SetData(&NullData); -} - - -String String::ToUpper() const -{ - uint32_t c; - const char* psource = GetData()->Data; - const char* pend = psource + GetData()->GetSize(); - String str; - intptr_t bufferOffset = 0; - char buffer[512]; - - while(psource < pend) - { - do { - c = UTF8Util::DecodeNextChar_Advance0(&psource); - UTF8Util::EncodeChar(buffer, &bufferOffset, OVR_towupper(wchar_t(c))); - } while ((psource < pend) && (bufferOffset < intptr_t(sizeof(buffer)-8))); - - // Append string a piece at a time. - str.AppendString(buffer, bufferOffset); - bufferOffset = 0; - } - - return str; -} - -String String::ToLower() const -{ - uint32_t c; - const char* psource = GetData()->Data; - const char* pend = psource + GetData()->GetSize(); - String str; - intptr_t bufferOffset = 0; - char buffer[512]; - - while(psource < pend) - { - do { - c = UTF8Util::DecodeNextChar_Advance0(&psource); - UTF8Util::EncodeChar(buffer, &bufferOffset, OVR_towlower(wchar_t(c))); - } while ((psource < pend) && (bufferOffset < intptr_t(sizeof(buffer)-8))); - - // Append string a piece at a time. - str.AppendString(buffer, bufferOffset); - bufferOffset = 0; - } - - return str; -} - - - -String& String::Insert(const char* substr, size_t posAt, intptr_t strSize) -{ - DataDesc* poldData = GetData(); - size_t oldSize = poldData->GetSize(); - size_t insertSize = (strSize < 0) ? OVR_strlen(substr) : (size_t)strSize; - size_t byteIndex = (poldData->LengthIsSize()) ? - posAt : (size_t)UTF8Util::GetByteIndex(posAt, poldData->Data, oldSize); - - OVR_ASSERT(byteIndex <= oldSize); - - DataDesc* pnewData = AllocDataCopy2(oldSize + insertSize, 0, - poldData->Data, byteIndex, substr, insertSize); - memcpy(pnewData->Data + byteIndex + insertSize, - poldData->Data + byteIndex, oldSize - byteIndex); - SetData(pnewData); - poldData->Release(); - return *this; -} - -/* -String& String::Insert(const uint32_t* substr, size_t posAt, intptr_t len) -{ - for (intptr_t i = 0; i < len; ++i) - { - size_t charw = InsertCharAt(substr[i], posAt); - posAt += charw; - } - return *this; -} -*/ - -size_t String::InsertCharAt(uint32_t c, size_t posAt) -{ - char buf[8]; - intptr_t index = 0; - UTF8Util::EncodeChar(buf, &index, c); - OVR_ASSERT(index >= 0); - buf[(size_t)index] = 0; - - Insert(buf, posAt, index); - return (size_t)index; -} - - -int String::CompareNoCase(const char* a, const char* b) -{ - return OVR_stricmp(a, b); -} - -int String::CompareNoCase(const char* a, const char* b, intptr_t len) -{ - if (len) - { - intptr_t f,l; - intptr_t slen = len; - const char *s = b; - do { - f = (intptr_t)OVR_tolower((int)(*(a++))); - l = (intptr_t)OVR_tolower((int)(*(b++))); - } while (--len && f && (f == l) && *b != 0); - - if (f == l && (len != 0 || *b != 0)) - { - f = (intptr_t)slen; - l = (intptr_t)OVR_strlen(s); - return int(f - l); - } - - return int(f - l); - } - else - return (0-(int)OVR_strlen(b)); -} - -// ***** Implement hash static functions - -// Hash function -size_t String::BernsteinHashFunction(const void* pdataIn, size_t size, size_t seed) -{ - const uint8_t* pdata = (const uint8_t*) pdataIn; - size_t h = seed; - while (size > 0) - { - size--; - h = ((h << 5) + h) ^ (unsigned) pdata[size]; - } - - return h; -} - -// Hash function, case-insensitive -size_t String::BernsteinHashFunctionCIS(const void* pdataIn, size_t size, size_t seed) -{ - const uint8_t* pdata = (const uint8_t*) pdataIn; - size_t h = seed; - while (size > 0) - { - size--; - h = ((h << 5) + h) ^ OVR_tolower(pdata[size]); - } - - // Alternative: "sdbm" hash function, suggested at same web page above. - // h = 0; - // for bytes { h = (h << 16) + (h << 6) - hash + *p; } - return h; -} - - - -// ***** String Buffer used for Building Strings - - -#define OVR_SBUFF_DEFAULT_GROW_SIZE 512 -// Constructors / Destructor. -StringBuffer::StringBuffer() - : pData(NULL), Size(0), BufferSize(0), GrowSize(OVR_SBUFF_DEFAULT_GROW_SIZE), LengthIsSize(false) -{ -} - -StringBuffer::StringBuffer(size_t growSize) - : pData(NULL), Size(0), BufferSize(0), GrowSize(OVR_SBUFF_DEFAULT_GROW_SIZE), LengthIsSize(false) -{ - SetGrowSize(growSize); -} - -StringBuffer::StringBuffer(const char* data) - : pData(NULL), Size(0), BufferSize(0), GrowSize(OVR_SBUFF_DEFAULT_GROW_SIZE), LengthIsSize(false) -{ - AppendString(data); -} - -StringBuffer::StringBuffer(const char* data, size_t dataSize) - : pData(NULL), Size(0), BufferSize(0), GrowSize(OVR_SBUFF_DEFAULT_GROW_SIZE), LengthIsSize(false) -{ - AppendString(data, dataSize); -} - -StringBuffer::StringBuffer(const String& src) - : pData(NULL), Size(0), BufferSize(0), GrowSize(OVR_SBUFF_DEFAULT_GROW_SIZE), LengthIsSize(false) -{ - AppendString(src.ToCStr(), src.GetSize()); -} - -StringBuffer::StringBuffer(const StringBuffer& src) - : pData(NULL), Size(0), BufferSize(0), GrowSize(OVR_SBUFF_DEFAULT_GROW_SIZE), LengthIsSize(false) -{ - AppendString(src.ToCStr(), src.GetSize()); -} - -StringBuffer::StringBuffer(const wchar_t* data) - : pData(NULL), Size(0), BufferSize(0), GrowSize(OVR_SBUFF_DEFAULT_GROW_SIZE), LengthIsSize(false) -{ - *this = data; -} - -StringBuffer::~StringBuffer() -{ - if (pData) - OVR_FREE(pData); -} -void StringBuffer::SetGrowSize(size_t growSize) -{ - if (growSize <= 16) - GrowSize = 16; - else - { - uint8_t bits = Alg::UpperBit(uint32_t(growSize-1)); - size_t size = (size_t)1 << bits; - GrowSize = size == growSize ? growSize : size; - } -} - -size_t StringBuffer::GetLength() const -{ - size_t length, size = GetSize(); - if (LengthIsSize) - return size; - - length = (size_t)UTF8Util::GetLength(pData, (size_t)GetSize()); - - if (length == GetSize()) - LengthIsSize = true; - return length; -} - -void StringBuffer::Reserve(size_t _size) -{ - if (_size >= BufferSize) // >= because of trailing zero! (!AB) - { - BufferSize = (_size + 1 + GrowSize - 1)& ~(GrowSize-1); - if (!pData) - pData = (char*)OVR_ALLOC(BufferSize); - else - pData = (char*)OVR_REALLOC(pData, BufferSize); - } -} -void StringBuffer::Resize(size_t _size) -{ - Reserve(_size); - LengthIsSize = false; - Size = _size; - if (pData) - pData[Size] = 0; -} - -void StringBuffer::Clear() -{ - Resize(0); - /* - if (pData != pEmptyNullData) - { - OVR_FREE(pHeap, pData); - pData = pEmptyNullData; - Size = BufferSize = 0; - LengthIsSize = false; - } - */ -} -// Appends a character -void StringBuffer::AppendChar(uint32_t ch) -{ - char buff[8]; - size_t origSize = GetSize(); - - // Converts ch into UTF8 string and fills it into buff. Also increments index according to the number of bytes - // in the UTF8 string. - intptr_t srcSize = 0; - UTF8Util::EncodeChar(buff, &srcSize, ch); - OVR_ASSERT(srcSize >= 0); - - size_t size = origSize + srcSize; - Resize(size); - OVR_ASSERT(pData != NULL); - memcpy(pData + origSize, buff, srcSize); -} - -// Append a string -void StringBuffer::AppendString(const wchar_t* pstr, intptr_t len) -{ - if (!pstr || !len) - return; - - intptr_t srcSize = UTF8Util::GetEncodeStringSize(pstr, len); - size_t origSize = GetSize(); - size_t size = srcSize + origSize; - - Resize(size); - OVR_ASSERT(pData != NULL); - UTF8Util::EncodeString(pData + origSize, pstr, len); -} - -void StringBuffer::AppendString(const char* putf8str, intptr_t utf8StrSz) -{ - if (!putf8str || !utf8StrSz) - return; - if (utf8StrSz == -1) - utf8StrSz = (intptr_t)OVR_strlen(putf8str); - - size_t origSize = GetSize(); - size_t size = utf8StrSz + origSize; - - Resize(size); - OVR_ASSERT(pData != NULL); - memcpy(pData + origSize, putf8str, utf8StrSz); -} - -// If pstr is NULL then the StringBuffer is cleared. -void StringBuffer::operator = (const char* pstr) -{ - pstr = pstr ? pstr : ""; - size_t size = OVR_strlen(pstr); - Resize(size); - OVR_ASSERT((pData != NULL) || (size == 0)); - memcpy(pData, pstr, size); -} - -// If pstr is NULL then the StringBuffer is cleared. -void StringBuffer::operator = (const wchar_t* pstr) -{ - pstr = pstr ? pstr : L""; - size_t size = (size_t)UTF8Util::GetEncodeStringSize(pstr); - Resize(size); - OVR_ASSERT((pData != NULL) || (size == 0)); - UTF8Util::EncodeString(pData, pstr); -} - -void StringBuffer::operator = (const String& src) -{ - const size_t size = src.GetSize(); - Resize(size); - OVR_ASSERT((pData != NULL) || (size == 0)); - memcpy(pData, src.ToCStr(), size); -} - -void StringBuffer::operator = (const StringBuffer& src) -{ - Clear(); - AppendString(src.ToCStr(), src.GetSize()); -} - - -// Inserts substr at posAt -void StringBuffer::Insert(const char* substr, size_t posAt, intptr_t len) -{ - size_t oldSize = Size; - size_t insertSize = (len < 0) ? OVR_strlen(substr) : (size_t)len; - size_t byteIndex = LengthIsSize ? posAt : - (size_t)UTF8Util::GetByteIndex(posAt, pData, (intptr_t)Size); - - OVR_ASSERT(byteIndex <= oldSize); - Reserve(oldSize + insertSize); - - OVR_ASSERT(pData != NULL); // pData is unilaterally written to below. - memmove(pData + byteIndex + insertSize, pData + byteIndex, oldSize - byteIndex + 1); - memcpy (pData + byteIndex, substr, insertSize); - LengthIsSize = false; - Size = oldSize + insertSize; - pData[Size] = 0; -} - -// Inserts character at posAt -size_t StringBuffer::InsertCharAt(uint32_t c, size_t posAt) -{ - char buf[8]; - intptr_t len = 0; - UTF8Util::EncodeChar(buf, &len, c); - OVR_ASSERT(len >= 0); - buf[(size_t)len] = 0; - - Insert(buf, posAt, len); - return (size_t)len; -} - -} // OVR diff --git a/LibOVR/Src/Kernel/OVR_String.h b/LibOVR/Src/Kernel/OVR_String.h deleted file mode 100644 index ecef940..0000000 --- a/LibOVR/Src/Kernel/OVR_String.h +++ /dev/null @@ -1,658 +0,0 @@ -/************************************************************************************ - -PublicHeader: OVR_Kernel.h -Filename : OVR_String.h -Content : String UTF8 string implementation with copy-on-write semantics - (thread-safe for assignment but not modification). -Created : September 19, 2012 -Notes : - -Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); -you may not use the Oculus VR Rift SDK except in compliance with the License, -which is provided at the time of installation or download, or which -otherwise accompanies this software in either electronic or hard copy form. - -You may obtain a copy of the License at - -http://www.oculusvr.com/licenses/LICENSE-3.2 - -Unless required by applicable law or agreed to in writing, the Oculus VR SDK -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -************************************************************************************/ - -#ifndef OVR_String_h -#define OVR_String_h - -#include "OVR_Types.h" -#include "OVR_Allocator.h" -#include "OVR_UTF8Util.h" -#include "OVR_Atomic.h" -#include "OVR_Std.h" -#include "OVR_Alg.h" - -namespace OVR { - -// ***** Classes - -class String; -class StringBuffer; - - -//----------------------------------------------------------------------------------- -// ***** String Class - -// String is UTF8 based string class with copy-on-write implementation -// for assignment. - -class String -{ -protected: - - enum FlagConstants - { - //Flag_GetLength = 0x7FFFFFFF, - // This flag is set if GetLength() == GetSize() for a string. - // Avoid extra scanning is Substring and indexing logic. - Flag_LengthIsSizeShift = (sizeof(size_t)*8 - 1) - }; - - - // Internal structure to hold string data - struct DataDesc - { - // Number of bytes. Will be the same as the number of chars if the characters - // are ascii, may not be equal to number of chars in case string data is UTF8. - size_t Size; - volatile int32_t RefCount; - char Data[1]; - - void AddRef() - { - AtomicOps<int32_t>::ExchangeAdd_NoSync(&RefCount, 1); - } - // Decrement ref count. This needs to be thread-safe, since - // a different thread could have also decremented the ref count. - // For example, if u start off with a ref count = 2. Now if u - // decrement the ref count and check against 0 in different - // statements, a different thread can also decrement the ref count - // in between our decrement and checking against 0 and will find - // the ref count = 0 and delete the object. This will lead to a crash - // when context switches to our thread and we'll be trying to delete - // an already deleted object. Hence decrementing the ref count and - // checking against 0 needs to made an atomic operation. - void Release() - { - if ((AtomicOps<int32_t>::ExchangeAdd_NoSync(&RefCount, -1) - 1) == 0) - OVR_FREE(this); - } - - static size_t GetLengthFlagBit() { return size_t(1) << Flag_LengthIsSizeShift; } - size_t GetSize() const { return Size & ~GetLengthFlagBit() ; } - size_t GetLengthFlag() const { return Size & GetLengthFlagBit(); } - bool LengthIsSize() const { return GetLengthFlag() != 0; } - }; - - // Heap type of the string is encoded in the lower bits. - enum HeapType - { - HT_Global = 0, // Heap is global. - HT_Local = 1, // SF::String_loc: Heap is determined based on string's address. - HT_Dynamic = 2, // SF::String_temp: Heap is stored as a part of the class. - HT_Mask = 3 - }; - - union { - DataDesc* pData; - size_t HeapTypeBits; - }; - typedef union { - DataDesc* pData; - size_t HeapTypeBits; - } DataDescUnion; - - inline HeapType GetHeapType() const { return (HeapType) (HeapTypeBits & HT_Mask); } - - inline DataDesc* GetData() const - { - DataDescUnion u; - u.pData = pData; - u.HeapTypeBits = (u.HeapTypeBits & ~(size_t)HT_Mask); - return u.pData; - } - - inline void SetData(DataDesc* pdesc) - { - HeapType ht = GetHeapType(); - pData = pdesc; - OVR_ASSERT((HeapTypeBits & HT_Mask) == 0); - HeapTypeBits |= ht; - } - - - DataDesc* AllocData(size_t size, size_t lengthIsSize); - DataDesc* AllocDataCopy1(size_t size, size_t lengthIsSize, - const char* pdata, size_t copySize); - DataDesc* AllocDataCopy2(size_t size, size_t lengthIsSize, - const char* pdata1, size_t copySize1, - const char* pdata2, size_t copySize2); - - // Special constructor to avoid data initalization when used in derived class. - struct NoConstructor { }; - String(const NoConstructor&) { } - -public: - - // For initializing string with dynamic buffer - struct InitStruct - { - virtual ~InitStruct() { } - virtual void InitString(char* pbuffer, size_t size) const = 0; - }; - - - // Constructors / Destructors. - String(); - String(const char* data); - String(const char* data1, const char* pdata2, const char* pdata3 = 0); - String(const char* data, size_t buflen); - String(const String& src); - String(const StringBuffer& src); - String(const InitStruct& src, size_t size); - explicit String(const wchar_t* data); - - // Destructor (Captain Obvious guarantees!) - ~String() - { - GetData()->Release(); - } - - // Declaration of NullString - static DataDesc NullData; - - - // *** General Functions - - void Clear(); - - // For casting to a pointer to char. - operator const char*() const { return GetData()->Data; } - // Pointer to raw buffer. - const char* ToCStr() const { return GetData()->Data; } - - // Returns number of bytes - size_t GetSize() const { return GetData()->GetSize() ; } - // Tells whether or not the string is empty - bool IsEmpty() const { return GetSize() == 0; } - - // Returns number of characters - size_t GetLength() const; - int GetLengthI() const { return (int)GetLength(); } - - // Returns character at the specified index - uint32_t GetCharAt(size_t index) const; - uint32_t GetFirstCharAt(size_t index, const char** offset) const; - uint32_t GetNextChar(const char** offset) const; - - // Appends a character - void AppendChar(uint32_t ch); - - // Append a string - void AppendString(const wchar_t* pstr, intptr_t len = -1); - void AppendString(const char* putf8str, intptr_t utf8StrSz = -1); - - // Assigned a string with dynamic data (copied through initializer). - void AssignString(const InitStruct& src, size_t size); - // Assigns string with known size. - void AssignString(const char* putf8str, size_t size); - - // Resize the string to the new size -// void Resize(size_t _size); - - // Removes the character at posAt - void Remove(size_t posAt, intptr_t len = 1); - - // Returns a String that's a substring of this. - // -start is the index of the first UTF8 character you want to include. - // -end is the index one past the last UTF8 character you want to include. - String Substring(size_t start, size_t end) const; - - // Case-conversion - String ToUpper() const; - String ToLower() const; - - // Inserts substr at posAt - String& Insert (const char* substr, size_t posAt, intptr_t len = -1); - - // Inserts character at posAt - size_t InsertCharAt(uint32_t c, size_t posAt); - - // Inserts substr at posAt, which is an index of a character (not byte). - // Of size is specified, it is in bytes. -// String& Insert(const uint32_t* substr, size_t posAt, intptr_t size = -1); - - // Get Byte index of the character at position = index - size_t GetByteIndex(size_t index) const { return (size_t)UTF8Util::GetByteIndex(index, GetData()->Data); } - - // Utility: case-insensitive string compare. stricmp() & strnicmp() are not - // ANSI or POSIX, do not seem to appear in Linux. - static int OVR_STDCALL CompareNoCase(const char* a, const char* b); - static int OVR_STDCALL CompareNoCase(const char* a, const char* b, intptr_t len); - - // Hash function, case-insensitive - static size_t OVR_STDCALL BernsteinHashFunctionCIS(const void* pdataIn, size_t size, size_t seed = 5381); - - // Hash function, case-sensitive - static size_t OVR_STDCALL BernsteinHashFunction(const void* pdataIn, size_t size, size_t seed = 5381); - - - // ***** File path parsing helper functions. - // Implemented in OVR_String_FilePath.cpp. - - // Absolute paths can star with: - // - protocols: 'file://', 'http://' - // - windows drive: 'c:\' - // - UNC share name: '\\share' - // - unix root '/' - static bool HasAbsolutePath(const char* path); - static bool HasExtension(const char* path); - static bool HasProtocol(const char* path); - - bool HasAbsolutePath() const { return HasAbsolutePath(ToCStr()); } - bool HasExtension() const { return HasExtension(ToCStr()); } - bool HasProtocol() const { return HasProtocol(ToCStr()); } - - String GetProtocol() const; // Returns protocol, if any, with trailing '://'. - String GetPath() const; // Returns path with trailing '/'. - String GetFilename() const; // Returns filename, including extension. - String GetExtension() const; // Returns extension with a dot. - - void StripProtocol(); // Strips front protocol, if any, from the string. - void StripExtension(); // Strips off trailing extension. - - - // Operators - // Assignment - void operator = (const char* str); - void operator = (const wchar_t* str); - void operator = (const String& src); - void operator = (const StringBuffer& src); - - // Addition - void operator += (const String& src); - void operator += (const char* psrc) { AppendString(psrc); } - void operator += (const wchar_t* psrc) { AppendString(psrc); } - void operator += (char ch) { AppendChar(ch); } - String operator + (const char* str) const; - String operator + (const String& src) const; - - // Comparison - bool operator == (const String& str) const - { - return (OVR_strcmp(GetData()->Data, str.GetData()->Data)== 0); - } - - bool operator != (const String& str) const - { - return !operator == (str); - } - - bool operator == (const char* str) const - { - return OVR_strcmp(GetData()->Data, str) == 0; - } - - bool operator != (const char* str) const - { - return !operator == (str); - } - - bool operator < (const char* pstr) const - { - return OVR_strcmp(GetData()->Data, pstr) < 0; - } - - bool operator < (const String& str) const - { - return *this < str.GetData()->Data; - } - - bool operator > (const char* pstr) const - { - return OVR_strcmp(GetData()->Data, pstr) > 0; - } - - bool operator > (const String& str) const - { - return *this > str.GetData()->Data; - } - - int CompareNoCase(const char* pstr) const - { - return CompareNoCase(GetData()->Data, pstr); - } - int CompareNoCase(const String& str) const - { - return CompareNoCase(GetData()->Data, str.ToCStr()); - } - - // Accesses raw bytes - const char& operator [] (int index) const - { - OVR_ASSERT(index >= 0 && (size_t)index < GetSize()); - return GetData()->Data[index]; - } - const char& operator [] (size_t index) const - { - OVR_ASSERT(index < GetSize()); - return GetData()->Data[index]; - } - - - // Case insensitive keys are used to look up insensitive string in hash tables - // for SWF files with version before SWF 7. - struct NoCaseKey - { - const String* pStr; - NoCaseKey(const String &str) : pStr(&str){}; - }; - - bool operator == (const NoCaseKey& strKey) const - { - return (CompareNoCase(ToCStr(), strKey.pStr->ToCStr()) == 0); - } - bool operator != (const NoCaseKey& strKey) const - { - return !(CompareNoCase(ToCStr(), strKey.pStr->ToCStr()) == 0); - } - - // Hash functor used for strings. - struct HashFunctor - { - size_t operator()(const String& data) const - { - size_t size = data.GetSize(); - return String::BernsteinHashFunction((const char*)data, size); - } - }; - // Case-insensitive hash functor used for strings. Supports additional - // lookup based on NoCaseKey. - struct NoCaseHashFunctor - { - size_t operator()(const String& data) const - { - size_t size = data.GetSize(); - return String::BernsteinHashFunctionCIS((const char*)data, size); - } - size_t operator()(const NoCaseKey& data) const - { - size_t size = data.pStr->GetSize(); - return String::BernsteinHashFunctionCIS((const char*)data.pStr->ToCStr(), size); - } - }; - -}; - - -//----------------------------------------------------------------------------------- -// ***** String Buffer used for Building Strings - -class StringBuffer -{ - char* pData; - size_t Size; - size_t BufferSize; - size_t GrowSize; - mutable bool LengthIsSize; - -public: - - // Constructors / Destructor. - StringBuffer(); - explicit StringBuffer(size_t growSize); - StringBuffer(const char* data); - StringBuffer(const char* data, size_t buflen); - StringBuffer(const String& src); - StringBuffer(const StringBuffer& src); - explicit StringBuffer(const wchar_t* data); - ~StringBuffer(); - - - // Modify grow size used for growing/shrinking the buffer. - size_t GetGrowSize() const { return GrowSize; } - void SetGrowSize(size_t growSize); - - - // *** General Functions - // Does not release memory, just sets Size to 0 - void Clear(); - - // For casting to a pointer to char. - operator const char*() const { return (pData) ? pData : ""; } - // Pointer to raw buffer. - const char* ToCStr() const { return (pData) ? pData : ""; } - - // Returns number of bytes. - size_t GetSize() const { return Size ; } - // Tells whether or not the string is empty. - bool IsEmpty() const { return GetSize() == 0; } - - // Returns number of characters - size_t GetLength() const; - - // Returns character at the specified index - uint32_t GetCharAt(size_t index) const; - uint32_t GetFirstCharAt(size_t index, const char** offset) const; - uint32_t GetNextChar(const char** offset) const; - - - // Resize the string to the new size - void Resize(size_t _size); - void Reserve(size_t _size); - - // Appends a character - void AppendChar(uint32_t ch); - - // Append a string - void AppendString(const wchar_t* pstr, intptr_t len = -1); - void AppendString(const char* putf8str, intptr_t utf8StrSz = -1); - void AppendFormat(const char* format, ...); - - // Assigned a string with dynamic data (copied through initializer). - //void AssignString(const InitStruct& src, size_t size); - - // Inserts substr at posAt - void Insert (const char* substr, size_t posAt, intptr_t len = -1); - // Inserts character at posAt - size_t InsertCharAt(uint32_t c, size_t posAt); - - // Assignment - void operator = (const char* str); - void operator = (const wchar_t* str); - void operator = (const String& src); - void operator = (const StringBuffer& src); - - // Addition - void operator += (const String& src) { AppendString(src.ToCStr(),src.GetSize()); } - void operator += (const char* psrc) { AppendString(psrc); } - void operator += (const wchar_t* psrc) { AppendString(psrc); } - void operator += (char ch) { AppendChar(ch); } - //String operator + (const char* str) const ; - //String operator + (const String& src) const ; - - // Accesses raw bytes - char& operator [] (int index) - { - OVR_ASSERT(((size_t)index) < GetSize()); - return pData[index]; - } - char& operator [] (size_t index) - { - OVR_ASSERT(index < GetSize()); - return pData[index]; - } - - const char& operator [] (int index) const - { - OVR_ASSERT(((size_t)index) < GetSize()); - return pData[index]; - } - const char& operator [] (size_t index) const - { - OVR_ASSERT(index < GetSize()); - return pData[index]; - } -}; - - -// -// Wrapper for string data. The data must have a guaranteed -// lifespan throughout the usage of the wrapper. Not intended for -// cached usage. Not thread safe. -// -class StringDataPtr -{ -public: - StringDataPtr() : pStr(NULL), Size(0) {} - StringDataPtr(const StringDataPtr& p) - : pStr(p.pStr), Size(p.Size) {} - StringDataPtr(const char* pstr, size_t sz) - : pStr(pstr), Size(sz) {} - StringDataPtr(const char* pstr) - : pStr(pstr), Size((pstr != NULL) ? OVR_strlen(pstr) : 0) {} - explicit StringDataPtr(const String& str) - : pStr(str.ToCStr()), Size(str.GetSize()) {} - template <typename T, int N> - StringDataPtr(const T (&v)[N]) - : pStr(v), Size(N) {} - -public: - const char* ToCStr() const { return pStr; } - size_t GetSize() const { return Size; } - bool IsEmpty() const { return GetSize() == 0; } - - // value is a prefix of this string - // Character's values are not compared. - bool IsPrefix(const StringDataPtr& value) const - { - return ToCStr() == value.ToCStr() && GetSize() >= value.GetSize(); - } - // value is a suffix of this string - // Character's values are not compared. - bool IsSuffix(const StringDataPtr& value) const - { - return ToCStr() <= value.ToCStr() && (End()) == (value.End()); - } - - // Find first character. - // init_ind - initial index. - intptr_t FindChar(char c, size_t init_ind = 0) const - { - for (size_t i = init_ind; i < GetSize(); ++i) - if (pStr[i] == c) - return static_cast<intptr_t>(i); - - return -1; - } - - // Find last character. - // init_ind - initial index. - intptr_t FindLastChar(char c, size_t init_ind = ~0) const - { - if (init_ind == (size_t)~0 || init_ind > GetSize()) - init_ind = GetSize(); - else - ++init_ind; - - for (size_t i = init_ind; i > 0; --i) - if (pStr[i - 1] == c) - return static_cast<intptr_t>(i - 1); - - return -1; - } - - // Create new object and trim size bytes from the left. - StringDataPtr GetTrimLeft(size_t size) const - { - // Limit trim size to the size of the string. - size = Alg::PMin(GetSize(), size); - - return StringDataPtr(ToCStr() + size, GetSize() - size); - } - // Create new object and trim size bytes from the right. - StringDataPtr GetTrimRight(size_t size) const - { - // Limit trim to the size of the string. - size = Alg::PMin(GetSize(), size); - - return StringDataPtr(ToCStr(), GetSize() - size); - } - - // Create new object, which contains next token. - // Useful for parsing. - StringDataPtr GetNextToken(char separator = ':') const - { - size_t cur_pos = 0; - const char* cur_str = ToCStr(); - - for (; cur_pos < GetSize() && cur_str[cur_pos]; ++cur_pos) - { - if (cur_str[cur_pos] == separator) - { - break; - } - } - - return StringDataPtr(ToCStr(), cur_pos); - } - - // Trim size bytes from the left. - StringDataPtr& TrimLeft(size_t size) - { - // Limit trim size to the size of the string. - size = Alg::PMin(GetSize(), size); - pStr += size; - Size -= size; - - return *this; - } - // Trim size bytes from the right. - StringDataPtr& TrimRight(size_t size) - { - // Limit trim to the size of the string. - size = Alg::PMin(GetSize(), size); - Size -= size; - - return *this; - } - - const char* Begin() const { return ToCStr(); } - const char* End() const { return ToCStr() + GetSize(); } - - // Hash functor used string data pointers - struct HashFunctor - { - size_t operator()(const StringDataPtr& data) const - { - return String::BernsteinHashFunction(data.ToCStr(), data.GetSize()); - } - }; - - bool operator== (const StringDataPtr& data) const - { - return (OVR_strncmp(pStr, data.pStr, data.Size) == 0); - } - -protected: - const char* pStr; - size_t Size; -}; - -} // OVR - -#endif diff --git a/LibOVR/Src/Kernel/OVR_StringHash.h b/LibOVR/Src/Kernel/OVR_StringHash.h deleted file mode 100644 index 410a578..0000000 --- a/LibOVR/Src/Kernel/OVR_StringHash.h +++ /dev/null @@ -1,100 +0,0 @@ -/************************************************************************************ - -PublicHeader: None -Filename : OVR_StringHash.h -Content : String hash table used when optional case-insensitive - lookup is required. -Created : September 19, 2012 -Notes : - -Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); -you may not use the Oculus VR Rift SDK except in compliance with the License, -which is provided at the time of installation or download, or which -otherwise accompanies this software in either electronic or hard copy form. - -You may obtain a copy of the License at - -http://www.oculusvr.com/licenses/LICENSE-3.2 - -Unless required by applicable law or agreed to in writing, the Oculus VR SDK -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -************************************************************************************/ - -#ifndef OVR_StringHash_h -#define OVR_StringHash_h - -#include "OVR_String.h" -#include "OVR_Hash.h" - -namespace OVR { - -//----------------------------------------------------------------------------------- -// *** StringHash - -// This is a custom string hash table that supports case-insensitive -// searches through special functions such as GetCaseInsensitive, etc. -// This class is used for Flash labels, exports and other case-insensitive tables. - -template<class U, class Allocator = ContainerAllocator<U> > -class StringHash : public Hash<String, U, String::NoCaseHashFunctor, Allocator> -{ -public: - typedef U ValueType; - typedef StringHash<U, Allocator> SelfType; - typedef Hash<String, U, String::NoCaseHashFunctor, Allocator> BaseType; - -public: - - void operator = (const SelfType& src) { BaseType::operator = (src); } - - bool GetCaseInsensitive(const String& key, U* pvalue) const - { - String::NoCaseKey ikey(key); - return BaseType::GetAlt(ikey, pvalue); - } - // Pointer-returning get variety. - const U* GetCaseInsensitive(const String& key) const - { - String::NoCaseKey ikey(key); - return BaseType::GetAlt(ikey); - } - U* GetCaseInsensitive(const String& key) - { - String::NoCaseKey ikey(key); - return BaseType::GetAlt(ikey); - } - - - typedef typename BaseType::Iterator base_iterator; - - base_iterator FindCaseInsensitive(const String& key) - { - String::NoCaseKey ikey(key); - return BaseType::FindAlt(ikey); - } - - // Set just uses a find and assigns value if found. The key is not modified; - // this behavior is identical to Flash string variable assignment. - void SetCaseInsensitive(const String& key, const U& value) - { - base_iterator it = FindCaseInsensitive(key); - if (it != BaseType::End()) - { - it->Second = value; - } - else - { - BaseType::Add(key, value); - } - } -}; - -} // OVR - -#endif diff --git a/LibOVR/Src/Kernel/OVR_String_FormatUtil.cpp b/LibOVR/Src/Kernel/OVR_String_FormatUtil.cpp deleted file mode 100644 index d52b6bb..0000000 --- a/LibOVR/Src/Kernel/OVR_String_FormatUtil.cpp +++ /dev/null @@ -1,76 +0,0 @@ -/************************************************************************************ - -Filename : OVR_String_FormatUtil.cpp -Content : String format functions. -Created : February 27, 2013 -Notes : - -Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); -you may not use the Oculus VR Rift SDK except in compliance with the License, -which is provided at the time of installation or download, or which -otherwise accompanies this software in either electronic or hard copy form. - -You may obtain a copy of the License at - -http://www.oculusvr.com/licenses/LICENSE-3.2 - -Unless required by applicable law or agreed to in writing, the Oculus VR SDK -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -************************************************************************************/ - -#include "OVR_String.h" -#include "OVR_Log.h" - -namespace OVR { - -void StringBuffer::AppendFormat(const char* format, ...) -{ - va_list argList; - char buffer[512]; - char* bufferUsed = buffer; - char* bufferAllocated = NULL; - - va_start(argList, format); - - #if !defined(OVR_CC_MSVC) // Non-Microsoft compilers require you to save a copy of the va_list. - va_list argListSaved; - va_copy(argListSaved, argList); - #endif - - int requiredStrlen = OVR_vsnprintf(bufferUsed, OVR_ARRAY_COUNT(buffer), format, argList); // The large majority of the time this will succeed. - - if(requiredStrlen >= (int)sizeof(buffer)) // If the initial capacity wasn't enough... - { - bufferAllocated = (char*)OVR_ALLOC(sizeof(char) * (requiredStrlen + 1)); - bufferUsed = bufferAllocated; - if(bufferAllocated) - { - #if !defined(OVR_CC_MSVC) - va_end(argList); - va_copy(argList, argListSaved); - #endif - requiredStrlen = OVR_vsnprintf(bufferAllocated, (requiredStrlen + 1), format, argList); - } - } - - if(requiredStrlen < 0) // If there was a printf format error... - { - bufferUsed = NULL; - } - - va_end(argList); - - if(bufferUsed) - AppendString(bufferUsed); - - if(bufferAllocated) - OVR_FREE(bufferAllocated); -} - -} // OVR diff --git a/LibOVR/Src/Kernel/OVR_String_PathUtil.cpp b/LibOVR/Src/Kernel/OVR_String_PathUtil.cpp deleted file mode 100644 index 95f3de9..0000000 --- a/LibOVR/Src/Kernel/OVR_String_PathUtil.cpp +++ /dev/null @@ -1,211 +0,0 @@ -/************************************************************************************ - -Filename : OVR_String_PathUtil.cpp -Content : String filename/url helper function -Created : September 19, 2012 -Notes : - -Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); -you may not use the Oculus VR Rift SDK except in compliance with the License, -which is provided at the time of installation or download, or which -otherwise accompanies this software in either electronic or hard copy form. - -You may obtain a copy of the License at - -http://www.oculusvr.com/licenses/LICENSE-3.2 - -Unless required by applicable law or agreed to in writing, the Oculus VR SDK -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -************************************************************************************/ - -#include "OVR_String.h" -#include "OVR_UTF8Util.h" - -namespace OVR { - -//-------------------------------------------------------------------- -// ***** Path-Scanner helper function - -// Scans file path finding filename start and extension start, fills in their addess. -void ScanFilePath(const char* url, const char** pfilename, const char** pext) -{ - const char* urlStart = url; - const char *filename = 0; - const char *lastDot = 0; - - uint32_t charVal = UTF8Util::DecodeNextChar(&url); - - while (charVal != 0) - { - if ((charVal == '/') || (charVal == '\\')) - { - filename = url; - lastDot = 0; - } - else if (charVal == '.') - { - lastDot = url - 1; - } - - charVal = UTF8Util::DecodeNextChar(&url); - } - - if (pfilename) - { - // It was a naked filename - if (urlStart && (*urlStart != '.') && *urlStart) - *pfilename = urlStart; - else - *pfilename = filename; - } - - if (pext) - { - *pext = lastDot; - } -} - -// Scans till the end of protocol. Returns first character past protocol, -// 0 if not found. -// - protocol: 'file://', 'http://' -const char* ScanPathProtocol(const char* url) -{ - uint32_t charVal = UTF8Util::DecodeNextChar(&url); - uint32_t charVal2; - - while (charVal != 0) - { - // Treat a colon followed by a slash as absolute. - if (charVal == ':') - { - charVal2 = UTF8Util::DecodeNextChar(&url); - charVal = UTF8Util::DecodeNextChar(&url); - if ((charVal == '/') && (charVal2 == '\\')) - return url; - } - charVal = UTF8Util::DecodeNextChar(&url); - } - return 0; -} - - -//-------------------------------------------------------------------- -// ***** String Path API implementation - -bool String::HasAbsolutePath(const char* url) -{ - // Absolute paths can star with: - // - protocols: 'file://', 'http://' - // - windows drive: 'c:\' - // - UNC share name: '\\share' - // - unix root '/' - - // On the other hand, relative paths are: - // - directory: 'directory/file' - // - this directory: './file' - // - parent directory: '../file' - // - // For now, we don't parse '.' or '..' out, but instead let it be concatenated - // to string and let the OS figure it out. This, however, is not good for file - // name matching in library/etc, so it should be improved. - - if (!url || !*url) - return true; // Treat empty strings as absolute. - - uint32_t charVal = UTF8Util::DecodeNextChar(&url); - - // Fist character of '/' or '\\' means absolute url. - if ((charVal == '/') || (charVal == '\\')) - return true; - - while (charVal != 0) - { - // Treat a colon followed by a slash as absolute. - if (charVal == ':') - { - charVal = UTF8Util::DecodeNextChar(&url); - // Protocol or windows drive. Absolute. - if ((charVal == '/') || (charVal == '\\')) - return true; - } - else if ((charVal == '/') || (charVal == '\\')) - { - // Not a first character (else 'if' above the loop would have caught it). - // Must be a relative url. - break; - } - - charVal = UTF8Util::DecodeNextChar(&url); - } - - // We get here for relative paths. - return false; -} - - -bool String::HasExtension(const char* path) -{ - const char* ext = 0; - ScanFilePath(path, 0, &ext); - return ext != 0; -} -bool String::HasProtocol(const char* path) -{ - return ScanPathProtocol(path) != 0; -} - - -String String::GetPath() const -{ - const char* filename = 0; - ScanFilePath(ToCStr(), &filename, 0); - - // Technically we can have extra logic somewhere for paths, - // such as enforcing protocol and '/' only based on flags, - // but we keep it simple for now. - return String(ToCStr(), filename ? (filename-ToCStr()) : GetSize()); -} - -String String::GetProtocol() const -{ - const char* protocolEnd = ScanPathProtocol(ToCStr()); - return String(ToCStr(), protocolEnd ? (protocolEnd-ToCStr()) : 0); -} - -String String::GetFilename() const -{ - const char* filename = 0; - ScanFilePath(ToCStr(), &filename, 0); - return String(filename); -} -String String::GetExtension() const -{ - const char* ext = 0; - ScanFilePath(ToCStr(), 0, &ext); - return String(ext); -} - -void String::StripExtension() -{ - const char* ext = 0; - ScanFilePath(ToCStr(), 0, &ext); - if (ext) - { - *this = String(ToCStr(), ext-ToCStr()); - } -} - -void String::StripProtocol() -{ - const char* protocol = ScanPathProtocol(ToCStr()); - if (protocol) - AssignString(protocol, OVR_strlen(protocol)); -} - -} // OVR diff --git a/LibOVR/Src/Kernel/OVR_SysFile.cpp b/LibOVR/Src/Kernel/OVR_SysFile.cpp deleted file mode 100644 index 6ef27c7..0000000 --- a/LibOVR/Src/Kernel/OVR_SysFile.cpp +++ /dev/null @@ -1,138 +0,0 @@ -/************************************************************************** - -Filename : OVR_SysFile.cpp -Content : File wrapper class implementation (Win32) - -Created : April 5, 1999 -Authors : Michael Antonov - -Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); -you may not use the Oculus VR Rift SDK except in compliance with the License, -which is provided at the time of installation or download, or which -otherwise accompanies this software in either electronic or hard copy form. - -You may obtain a copy of the License at - -http://www.oculusvr.com/licenses/LICENSE-3.2 - -Unless required by applicable law or agreed to in writing, the Oculus VR SDK -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -**************************************************************************/ - -#define GFILE_CXX - -// Standard C library (Captain Obvious guarantees!) -#include <stdio.h> - -#include "OVR_SysFile.h" -#include "OVR_Log.h" - -namespace OVR { - -// This is - a dummy file that fails on all calls. - -class UnopenedFile : public File -{ -public: - UnopenedFile() { } - ~UnopenedFile() { } - - virtual const char* GetFilePath() { return 0; } - - // ** File Information - virtual bool IsValid() { return 0; } - virtual bool IsWritable() { return 0; } - - // Return position / file size - virtual int Tell() { return 0; } - virtual int64_t LTell() { return 0; } - virtual int GetLength() { return 0; } - virtual int64_t LGetLength() { return 0; } - -// virtual bool Stat(FileStats *pfs) { return 0; } - virtual int GetErrorCode() { return Error_FileNotFound; } - - // ** Stream implementation & I/O - virtual int Write(const uint8_t * /*pbuffer*/, int /*numBytes*/) { return -1; } - virtual int Read(uint8_t * /*pbuffer*/, int /*numBytes*/) { return -1; } - virtual int SkipBytes(int /*numBytes*/) { return 0; } - virtual int BytesAvailable() { return 0; } - virtual bool Flush() { return 0; } - virtual int Seek(int /*offset*/, int /*origin*/) { return -1; } - virtual int64_t LSeek(int64_t /*offset*/, int /*origin*/) { return -1; } - - virtual int CopyFromStream(File * /*pstream*/, int /*byteSize*/) { return -1; } - virtual bool Close() { return 0; } -}; - - - -// ***** System File - -// System file is created to access objects on file system directly -// This file can refer directly to path - -// ** Constructor -SysFile::SysFile() : DelegatedFile(0) -{ - pFile = *new UnopenedFile; -} - -Ptr<File> FileFILEOpen(const String& path, int flags, int mode); - -// Opens a file -SysFile::SysFile(const String& path, int flags, int mode) : DelegatedFile(0) -{ - Open(path, flags, mode); -} - - -// ** Open & management -// Will fail if file's already open -bool SysFile::Open(const String& path, int flags, int mode) -{ - pFile = FileFILEOpen(path, flags, mode); - if ((!pFile) || (!pFile->IsValid())) - { - pFile = *new UnopenedFile; - OVR_DEBUG_LOG(("Failed to open file: %s", path.ToCStr())); - return 0; - } - //pFile = *OVR_NEW DelegatedFile(pFile); // MA Testing - if (flags & Open_Buffered) - pFile = *new BufferedFile(pFile); - return 1; -} - - -// ** Overrides - -int SysFile::GetErrorCode() -{ - return pFile ? pFile->GetErrorCode() : Error_FileNotFound; -} - - -// Overrides to provide re-open support -bool SysFile::IsValid() -{ - return pFile && pFile->IsValid(); -} -bool SysFile::Close() -{ - if (IsValid()) - { - DelegatedFile::Close(); - pFile = *new UnopenedFile; - return 1; - } - return 0; -} - -} // OVR diff --git a/LibOVR/Src/Kernel/OVR_SysFile.h b/LibOVR/Src/Kernel/OVR_SysFile.h deleted file mode 100644 index 925c51d..0000000 --- a/LibOVR/Src/Kernel/OVR_SysFile.h +++ /dev/null @@ -1,104 +0,0 @@ -/************************************************************************************ - -PublicHeader: Kernel -Filename : OVR_SysFile.h -Content : Header for all internal file management - functions and structures - to be inherited by OS specific subclasses. -Created : September 19, 2012 -Notes : - -Notes : errno may not be preserved across use of GBaseFile member functions - : Directories cannot be deleted while files opened from them are in use - (For the GetFullName function) - -Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); -you may not use the Oculus VR Rift SDK except in compliance with the License, -which is provided at the time of installation or download, or which -otherwise accompanies this software in either electronic or hard copy form. - -You may obtain a copy of the License at - -http://www.oculusvr.com/licenses/LICENSE-3.2 - -Unless required by applicable law or agreed to in writing, the Oculus VR SDK -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -************************************************************************************/ - -#ifndef OVR_SysFile_h -#define OVR_SysFile_h - -#include "OVR_File.h" - -namespace OVR { - -// ***** Declared classes -class SysFile; - -//----------------------------------------------------------------------------------- -// *** File Statistics - -// This class contents are similar to _stat, providing -// creation, modify and other information about the file. -struct FileStat -{ - // No change or create time because they are not available on most systems - int64_t ModifyTime; - int64_t AccessTime; - int64_t FileSize; - - bool operator== (const FileStat& stat) const - { - return ( (ModifyTime == stat.ModifyTime) && - (AccessTime == stat.AccessTime) && - (FileSize == stat.FileSize) ); - } -}; - -//----------------------------------------------------------------------------------- -// *** System File - -// System file is created to access objects on file system directly -// This file can refer directly to path. -// System file can be open & closed several times; however, such use is not recommended -// This class is realy a wrapper around an implementation of File interface for a -// particular platform. - -class SysFile : public DelegatedFile -{ -protected: - SysFile(const SysFile &source) : DelegatedFile () { OVR_UNUSED(source); } -public: - - // ** Constructor - SysFile(); - // Opens a file - SysFile(const String& path, int flags = Open_Read|Open_Buffered, int mode = Mode_ReadWrite); - - // ** Open & management - bool Open(const String& path, int flags = Open_Read|Open_Buffered, int mode = Mode_ReadWrite); - - OVR_FORCE_INLINE bool Create(const String& path, int mode = Mode_ReadWrite) - { return Open(path, Open_ReadWrite|Open_Create, mode); } - - // Helper function: obtain file statistics information. In OVR, this is used to detect file changes. - // Return 0 if function failed, most likely because the file doesn't exist. - static bool OVR_CDECL GetFileStat(FileStat* pfileStats, const String& path); - - // ** Overrides - // Overridden to provide re-open support - virtual int GetErrorCode(); - - virtual bool IsValid(); - - virtual bool Close(); -}; - -} // Namespace OVR - -#endif diff --git a/LibOVR/Src/Kernel/OVR_System.cpp b/LibOVR/Src/Kernel/OVR_System.cpp deleted file mode 100644 index 66c764a..0000000 --- a/LibOVR/Src/Kernel/OVR_System.cpp +++ /dev/null @@ -1,149 +0,0 @@ -/************************************************************************************ - -Filename : OVR_System.cpp -Content : General kernel initialization/cleanup, including that - of the memory allocator. -Created : September 19, 2012 -Notes : - -Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); -you may not use the Oculus VR Rift SDK except in compliance with the License, -which is provided at the time of installation or download, or which -otherwise accompanies this software in either electronic or hard copy form. - -You may obtain a copy of the License at - -http://www.oculusvr.com/licenses/LICENSE-3.2 - -Unless required by applicable law or agreed to in writing, the Oculus VR SDK -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -************************************************************************************/ - -#include "OVR_System.h" -#include "OVR_Threads.h" -#include "OVR_Timer.h" -#include "../Displays/OVR_Display.h" -#ifdef OVR_OS_WIN32 -#include "../Displays/OVR_Win32_ShimFunctions.h" -#endif - -namespace OVR { - -#ifdef OVR_OS_WIN32 -extern bool anyRiftsInExtendedMode(); -#endif - -// Stack of destroy listeners (push/pop semantics) -static SystemSingletonInternal *SystemShutdownListenerStack = 0; -static Lock stackLock; -static bool DisplayShimInitialized = false; - -void SystemSingletonInternal::PushDestroyCallbacks() -{ - Lock::Locker locker(&stackLock); - - // Push listener onto the stack - NextSingleton = SystemShutdownListenerStack; - SystemShutdownListenerStack = this; -} - -void System::DirectDisplayInitialize() -{ -#ifdef OVR_OS_WIN32 - // Set up display code for Windows - Win32::DisplayShim::GetInstance(); - - // This code will look for the first display. If it's a display - // that's extending the destkop, the code will assume we're in - // compatibility mode. Compatibility mode prevents shim loading - // and renders only to extended Rifts. - // If we find a display and it's application exclusive, - // we load the shim so we can render to it. - // If no display is available, we revert to whatever the - // driver tells us we're in - - bool anyExtendedRifts = anyRiftsInExtendedMode() || Display::InCompatibilityMode( false ); - - DisplayShimInitialized = Win32::DisplayShim::GetInstance().Initialize(anyExtendedRifts); -#endif -} - -bool System::DirectDisplayEnabled() -{ - return DisplayShimInitialized; -} - -// Initializes System core, installing allocator. -void System::Init(Log* log, Allocator *palloc) -{ - if (!Allocator::GetInstance()) - { - Log::SetGlobalLog(log); - Timer::initializeTimerSystem(); - Allocator::setInstance(palloc); - Display::Initialize(); - DirectDisplayInitialize(); - } - else - { - OVR_DEBUG_LOG(("System::Init failed - duplicate call.")); - } -} - -void System::Destroy() -{ - if (Allocator::GetInstance()) - { -#ifdef OVR_OS_WIN32 - Win32::DisplayShim::GetInstance().Shutdown(); -#endif - - // Invoke all of the post-finish callbacks (normal case) - for (SystemSingletonInternal *listener = SystemShutdownListenerStack; listener; listener = listener->NextSingleton) - { - listener->OnThreadDestroy(); - } - -#ifdef OVR_ENABLE_THREADS - // Wait for all threads to finish; this must be done so that memory - // allocator and all destructors finalize correctly. - Thread::FinishAllThreads(); -#endif - - // Invoke all of the post-finish callbacks (normal case) - for (SystemSingletonInternal *next, *listener = SystemShutdownListenerStack; listener; listener = next) - { - next = listener->NextSingleton; - - listener->OnSystemDestroy(); - } - - SystemShutdownListenerStack = 0; - - // Shutdown heap and destroy SysAlloc singleton, if any. - Allocator::GetInstance()->onSystemShutdown(); - Allocator::setInstance(0); - - Timer::shutdownTimerSystem(); - Log::SetGlobalLog(Log::GetDefaultLog()); - } - else - { - OVR_DEBUG_LOG(("System::Destroy failed - System not initialized.")); - } -} - -// Returns 'true' if system was properly initialized. -bool System::IsInitialized() -{ - return Allocator::GetInstance() != 0; -} - - -} // namespace OVR diff --git a/LibOVR/Src/Kernel/OVR_System.h b/LibOVR/Src/Kernel/OVR_System.h deleted file mode 100644 index 9d09911..0000000 --- a/LibOVR/Src/Kernel/OVR_System.h +++ /dev/null @@ -1,174 +0,0 @@ -/************************************************************************************ - -PublicHeader: OVR -Filename : OVR_System.h -Content : General kernel initialization/cleanup, including that - of the memory allocator. -Created : September 19, 2012 -Notes : - -Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); -you may not use the Oculus VR Rift SDK except in compliance with the License, -which is provided at the time of installation or download, or which -otherwise accompanies this software in either electronic or hard copy form. - -You may obtain a copy of the License at - -http://www.oculusvr.com/licenses/LICENSE-3.2 - -Unless required by applicable law or agreed to in writing, the Oculus VR SDK -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -************************************************************************************/ - -#ifndef OVR_System_h -#define OVR_System_h - -#include "OVR_Allocator.h" -#include "OVR_Log.h" -#include "OVR_Atomic.h" - -namespace OVR { - - -//----------------------------------------------------------------------------- -// SystemSingleton - -// Subsystems are implemented using the Singleton pattern. -// To avoid code duplication in all the places where Singletons are defined, -// The pattern is defined once here and used everywhere. - -class SystemSingletonInternal -{ - friend class System; - - SystemSingletonInternal* NextSingleton; - - // No copying allowed - OVR_NON_COPYABLE(SystemSingletonInternal); - -protected: - SystemSingletonInternal() : - NextSingleton(0) - { - } - - virtual ~SystemSingletonInternal(){} - - // Call this to register the destroy events - // Destroy callbacks will be called in the reverse order they were registered - // Note: As a rule of thumb, call this at the end of the singleton class constructor. - void PushDestroyCallbacks(); - - // Required: Invoked when the System object is shutting down - // Called after threads are stopped - // Called before Log, Allocator, and Timer subsystems are stopped - // Listeners are called in the opposite order they were registered - virtual void OnSystemDestroy() = 0; - - // Called just before waiting for threads to die - // Listeners are called in the opposite order they were registered - // Useful to start terminating threads at the right time - // Note: The singleton must not delete itself here. - virtual void OnThreadDestroy() {} -}; - -// Singletons derive from this class -template<class T> -class SystemSingletonBase : public SystemSingletonInternal -{ - static AtomicPtr<T> SingletonInstance; - static T* SlowGetInstance(); - -protected: - ~SystemSingletonBase() - { - // Make sure the instance gets set to zero on dtor - if (SingletonInstance == this) - SingletonInstance = 0; - } - -public: - static OVR_FORCE_INLINE T* GetInstance() - { - // Fast version - // Note: The singleton instance is stored in an AtomicPtr<> to allow it to be accessed - // atomically from multiple threads without locks. - T* instance = SingletonInstance; - return instance ? instance : SlowGetInstance(); - } -}; - -// For reference, see N3337 14.5.1.3 (Static data members of class templates): -template<class T> OVR::AtomicPtr<T> OVR::SystemSingletonBase<T>::SingletonInstance; - -// Place this in the singleton class in the header file -#define OVR_DECLARE_SINGLETON(T) \ - friend class OVR::SystemSingletonBase<T>; \ -private: \ - T(); \ - virtual ~T(); \ - virtual void OnSystemDestroy(); - -// Place this in the singleton class source file -#define OVR_DEFINE_SINGLETON(T) \ - namespace OVR { \ - template<> T* SystemSingletonBase<T>::SlowGetInstance() \ - { \ - static OVR::Lock lock; \ - OVR::Lock::Locker locker(&lock); \ - if (!SingletonInstance) SingletonInstance = new T; \ - return SingletonInstance; \ - } \ - } - - -// ***** System Core Initialization class - -// System initialization must take place before any other OVR_Kernel objects are used; -// this is done my calling System::Init(). Among other things, this is necessary to -// initialize the memory allocator. Similarly, System::Destroy must be -// called before program exist for proper cleanup. Both of these tasks can be achieved by -// simply creating System object first, allowing its constructor/destructor do the work. - -// TBD: Require additional System class for Oculus Rift API? - -class System -{ -public: - // System constructor expects allocator to be specified, if it is being substituted. - System(Log* log = Log::ConfigureDefaultLog(LogMask_Debug), - Allocator* palloc = DefaultAllocator::InitSystemSingleton()) - { - Init(log, palloc); - } - ~System() - { - Destroy(); - } - - static void OVR_CDECL DirectDisplayInitialize(); - static bool OVR_CDECL DirectDisplayEnabled(); - - // Returns 'true' if system was properly initialized. - static bool OVR_CDECL IsInitialized(); - - // Initializes System core. Users can override memory implementation by passing - // a different Allocator here. - static void OVR_CDECL Init(Log* log = Log::ConfigureDefaultLog(LogMask_Debug), - Allocator *palloc = DefaultAllocator::InitSystemSingleton()); - - // De-initializes System more, finalizing the threading system and destroying - // the global memory allocator. - static void OVR_CDECL Destroy(); -}; - - -} // namespace OVR - -#endif diff --git a/LibOVR/Src/Kernel/OVR_ThreadCommandQueue.cpp b/LibOVR/Src/Kernel/OVR_ThreadCommandQueue.cpp deleted file mode 100644 index 90ba3cc..0000000 --- a/LibOVR/Src/Kernel/OVR_ThreadCommandQueue.cpp +++ /dev/null @@ -1,401 +0,0 @@ -/************************************************************************************ - -PublicHeader: None -Filename : OVR_ThreadCommandQueue.cpp -Content : Command queue for operations executed on a thread -Created : October 29, 2012 - -Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); -you may not use the Oculus VR Rift SDK except in compliance with the License, -which is provided at the time of installation or download, or which -otherwise accompanies this software in either electronic or hard copy form. - -You may obtain a copy of the License at - -http://www.oculusvr.com/licenses/LICENSE-3.2 - -Unless required by applicable law or agreed to in writing, the Oculus VR SDK -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -************************************************************************************/ - -#include "OVR_ThreadCommandQueue.h" - -namespace OVR { - - -//------------------------------------------------------------------------ -// ***** CircularBuffer - -// CircularBuffer is a FIFO buffer implemented in a single block of memory, -// which allows writing and reading variable-size data chucks. Write fails -// if buffer is full. - -class CircularBuffer -{ - enum { - AlignSize = 16, - AlignMask = AlignSize - 1 - }; - - uint8_t* pBuffer; - size_t Size; - size_t Tail; // Byte offset of next item to be popped. - size_t Head; // Byte offset of where next push will take place. - size_t End; // When Head < Tail, this is used instead of Size. - - inline size_t roundUpSize(size_t size) - { return (size + AlignMask) & ~(size_t)AlignMask; } - -public: - - CircularBuffer(size_t size) - : Size(size), Tail(0), Head(0), End(0) - { - pBuffer = (uint8_t*)OVR_ALLOC_ALIGNED(roundUpSize(size), AlignSize); - } - ~CircularBuffer() - { - // For ThreadCommands, we must consume everything before shutdown. - OVR_ASSERT(IsEmpty()); - OVR_FREE_ALIGNED(pBuffer); - } - - bool IsEmpty() const { return (Head == Tail); } - - // Allocates a state block of specified size and advances pointers, - // returning 0 if buffer is full. - uint8_t* Write(size_t size); - - // Returns a pointer to next available data block; 0 if none available. - uint8_t* ReadBegin() - { return (Head != Tail) ? (pBuffer + Tail) : 0; } - // Consumes data of specified size; this must match size passed to Write. - void ReadEnd(size_t size); -}; - - -// Allocates a state block of specified size and advances pointers, -// returning 0 if buffer is full. -uint8_t* CircularBuffer::Write(size_t size) -{ - uint8_t* p = 0; - - size = roundUpSize(size); - // Since this is circular buffer, always allow at least one item. - OVR_ASSERT(size < Size/2); - - if (Head >= Tail) - { - OVR_ASSERT(End == 0); - - if (size <= (Size - Head)) - { - p = pBuffer + Head; - Head += size; - } - else if (size < Tail) - { - p = pBuffer; - End = Head; - Head = size; - OVR_ASSERT(Head != Tail); - } - } - else - { - OVR_ASSERT(End != 0); - - if ((Tail - Head) > size) - { - p = pBuffer + Head; - Head += size; - OVR_ASSERT(Head != Tail); - } - } - - return p; -} - -void CircularBuffer::ReadEnd(size_t size) -{ - OVR_ASSERT(Head != Tail); - size = roundUpSize(size); - - Tail += size; - if (Tail == End) - { - Tail = End = 0; - } - else if (Tail == Head) - { - OVR_ASSERT(End == 0); - Tail = Head = 0; - } -} - - -//------------------------------------------------------------------------------------- -// ***** ThreadCommand - -ThreadCommand::PopBuffer::~PopBuffer() -{ - if (Size) { - Destruct<ThreadCommand>(toCommand()); - } -} - -void ThreadCommand::PopBuffer::InitFromBuffer(void* data) -{ - ThreadCommand* cmd = (ThreadCommand*)data; - OVR_ASSERT(cmd->Size <= MaxSize); - - if (Size) { - Destruct<ThreadCommand>(toCommand()); - } - Size = cmd->Size; - memcpy(Buffer, (void*)cmd, Size); -} - -void ThreadCommand::PopBuffer::Execute() -{ - ThreadCommand* command = toCommand(); - OVR_ASSERT(command); - command->Execute(); - if (NeedsWait()) { - GetEvent()->PulseEvent(); - } -} - -//------------------------------------------------------------------------------------- - -class ThreadCommandQueueImpl : public NewOverrideBase -{ - typedef ThreadCommand::NotifyEvent NotifyEvent; - friend class ThreadCommandQueue; - -public: - - ThreadCommandQueueImpl(ThreadCommandQueue* queue) : - pQueue(queue), - ExitEnqueued(false), - ExitProcessed(false), - CommandBuffer(2048), - PullThreadId(0) - { - } - ~ThreadCommandQueueImpl(); - - - bool PushCommand(const ThreadCommand& command); - bool PopCommand(ThreadCommand::PopBuffer* popBuffer); - - - // ExitCommand is used by notify us that Thread is shutting down. - struct ExitCommand : public ThreadCommand - { - ThreadCommandQueueImpl* pImpl; - - ExitCommand(ThreadCommandQueueImpl* impl, bool wait) - : ThreadCommand(sizeof(ExitCommand), wait, true), pImpl(impl) { } - - virtual void Execute() const - { - Lock::Locker lock(&pImpl->QueueLock); - pImpl->ExitProcessed = true; - } - virtual ThreadCommand* CopyConstruct(void* p) const - { return Construct<ExitCommand>(p, *this); } - }; - - - NotifyEvent* AllocNotifyEvent_NTS() - { - NotifyEvent* p = AvailableEvents.GetFirst(); - - if (!AvailableEvents.IsNull(p)) - p->RemoveNode(); - else - p = new NotifyEvent; - return p; - } - - void FreeNotifyEvent_NTS(NotifyEvent* p) - { - AvailableEvents.PushBack(p); - } - - void FreeNotifyEvents_NTS() - { - while(!AvailableEvents.IsEmpty()) - { - NotifyEvent* p = AvailableEvents.GetFirst(); - p->RemoveNode(); - delete p; - } - } - - ThreadCommandQueue* pQueue; - Lock QueueLock; - volatile bool ExitEnqueued; - volatile bool ExitProcessed; - List<NotifyEvent> AvailableEvents; - List<NotifyEvent> BlockedProducers; - CircularBuffer CommandBuffer; - - // The pull thread id is set to the last thread that pulled commands. - // Since this thread command queue is designed for a single thread, - // reentrant behavior that would cause a dead-lock for messages that - // wait for completion can be avoided by simply comparing the - // thread id of the last pull. - OVR::ThreadId PullThreadId; -}; - -ThreadCommandQueueImpl::~ThreadCommandQueueImpl() -{ - Lock::Locker lock(&QueueLock); - OVR_ASSERT(BlockedProducers.IsEmpty()); - FreeNotifyEvents_NTS(); -} - -bool ThreadCommandQueueImpl::PushCommand(const ThreadCommand& command) -{ - if (command.NeedsWait() && PullThreadId == OVR::GetCurrentThreadId()) - { - command.Execute(); - return true; - } - - ThreadCommand::NotifyEvent* completeEvent = 0; - ThreadCommand::NotifyEvent* queueAvailableEvent = 0; - - // Repeat writing command into buffer until it is available. - for (;;) { - { // Lock Scope - Lock::Locker lock(&QueueLock); - - if (queueAvailableEvent) { - FreeNotifyEvent_NTS(queueAvailableEvent); - queueAvailableEvent = 0; - } - - // Don't allow any commands after PushExitCommand() is called. - if (ExitEnqueued && !command.ExitFlag) { - return false; - } - - bool bufferWasEmpty = CommandBuffer.IsEmpty(); - uint8_t* buffer = CommandBuffer.Write(command.GetSize()); - - if (buffer) { - ThreadCommand* c = command.CopyConstruct(buffer); - - if (c->NeedsWait()) { - completeEvent = c->pEvent = AllocNotifyEvent_NTS(); - } - - // Signal-waker consumer when we add data to buffer. - if (bufferWasEmpty) { - pQueue->OnPushNonEmpty_Locked(); - } - - break; - } - - queueAvailableEvent = AllocNotifyEvent_NTS(); - BlockedProducers.PushBack(queueAvailableEvent); - } // Lock Scope - - queueAvailableEvent->Wait(); - } // Intentional infinite loop - - // Command was enqueued, wait if necessary. - if (completeEvent) { - completeEvent->Wait(); - Lock::Locker lock(&QueueLock); - FreeNotifyEvent_NTS(completeEvent); - } - - return true; -} - - -// Pops the next command from the thread queue, if any is available. -bool ThreadCommandQueueImpl::PopCommand(ThreadCommand::PopBuffer* popBuffer) -{ - PullThreadId = OVR::GetCurrentThreadId(); - - Lock::Locker lock(&QueueLock); - - uint8_t* buffer = CommandBuffer.ReadBegin(); - if (!buffer) - { - // Notify thread while in lock scope, enabling initialization of wait. - pQueue->OnPopEmpty_Locked(); - return false; - } - - popBuffer->InitFromBuffer(buffer); - CommandBuffer.ReadEnd(popBuffer->GetSize()); - - if (!BlockedProducers.IsEmpty()) - { - ThreadCommand::NotifyEvent* queueAvailableEvent = BlockedProducers.GetFirst(); - queueAvailableEvent->RemoveNode(); - queueAvailableEvent->PulseEvent(); - // Event is freed later by waiter. - } - return true; -} - - -//------------------------------------------------------------------------------------- - -ThreadCommandQueue::ThreadCommandQueue() -{ - pImpl = new ThreadCommandQueueImpl(this); -} -ThreadCommandQueue::~ThreadCommandQueue() -{ - delete pImpl; -} - -bool ThreadCommandQueue::PushCommand(const ThreadCommand& command) -{ - return pImpl->PushCommand(command); -} - -bool ThreadCommandQueue::PopCommand(ThreadCommand::PopBuffer* popBuffer) -{ - return pImpl->PopCommand(popBuffer); -} - -void ThreadCommandQueue::PushExitCommand(bool wait) -{ - // Exit is processed in two stages: - // - First, ExitEnqueued flag is set to block further commands from queuing up. - // - Second, the actual exit call is processed on the consumer thread, flushing - // any prior commands. - // IsExiting() only returns true after exit has flushed. - { - Lock::Locker lock(&pImpl->QueueLock); - if (pImpl->ExitEnqueued) - return; - pImpl->ExitEnqueued = true; - } - - PushCommand(ThreadCommandQueueImpl::ExitCommand(pImpl, wait)); -} - -bool ThreadCommandQueue::IsExiting() const -{ - return pImpl->ExitProcessed; -} - - -} // namespace OVR diff --git a/LibOVR/Src/Kernel/OVR_ThreadCommandQueue.h b/LibOVR/Src/Kernel/OVR_ThreadCommandQueue.h deleted file mode 100644 index 9c2a7d3..0000000 --- a/LibOVR/Src/Kernel/OVR_ThreadCommandQueue.h +++ /dev/null @@ -1,318 +0,0 @@ -/************************************************************************************ - -PublicHeader: None -Filename : OVR_ThreadCommandQueue.h -Content : Command queue for operations executed on a thread -Created : October 29, 2012 -Author : Michael Antonov - -Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); -you may not use the Oculus VR Rift SDK except in compliance with the License, -which is provided at the time of installation or download, or which -otherwise accompanies this software in either electronic or hard copy form. - -You may obtain a copy of the License at - -http://www.oculusvr.com/licenses/LICENSE-3.2 - -Unless required by applicable law or agreed to in writing, the Oculus VR SDK -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -************************************************************************************/ - -#ifndef OVR_ThreadCommandQueue_h -#define OVR_ThreadCommandQueue_h - -#include "../Kernel/OVR_Types.h" -#include "../Kernel/OVR_List.h" -#include "../Kernel/OVR_Atomic.h" -#include "../Kernel/OVR_Threads.h" - -namespace OVR { - -class ThreadCommand; -class ThreadCommandQueue; - - -//------------------------------------------------------------------------------------- -// ***** ThreadCommand - -// ThreadCommand is a base class implementation for commands stored in ThreadCommandQueue. -class ThreadCommand -{ -public: - // NotifyEvent is used by ThreadCommandQueue::PushCallAndWait to notify the - // calling (producer) thread when command is completed or queue slot is available. - class NotifyEvent : public ListNode<NotifyEvent>, public NewOverrideBase - { - Event E; - public: - NotifyEvent() { } - - void Wait() { E.Wait(); } - void PulseEvent() { E.PulseEvent(); } - }; - - // ThreadCommand::PopBuffer is temporary storage for a command popped off - // by ThreadCommandQueue::PopCommand. - class PopBuffer - { - enum { MaxSize = 256 }; - - size_t Size; - union { - uint8_t Buffer[MaxSize]; - size_t Align; - }; - - ThreadCommand* toCommand() const { return (ThreadCommand*)Buffer; } - - public: - PopBuffer() : Size(0) { } - ~PopBuffer(); - - void InitFromBuffer(void* data); - - bool HasCommand() const { return Size != 0; } - size_t GetSize() const { return Size; } - bool NeedsWait() const { return toCommand()->NeedsWait(); } - NotifyEvent* GetEvent() const { return toCommand()->pEvent; } - - // Execute the command and also notifies caller to finish waiting, - // if necessary. - void Execute(); - }; - - uint16_t Size; - bool WaitFlag; - bool ExitFlag; // Marks the last exit command. - NotifyEvent* pEvent; - - ThreadCommand(size_t size, bool waitFlag, bool exitFlag = false) - : Size((uint16_t)size), WaitFlag(waitFlag), ExitFlag(exitFlag), pEvent(0) { } - virtual ~ThreadCommand() { } - - bool NeedsWait() const { return WaitFlag; } - size_t GetSize() const { return Size; } - - virtual void Execute() const = 0; - // Copy constructor used for serializing this to memory buffer. - virtual ThreadCommand* CopyConstruct(void* p) const = 0; -}; - - -//------------------------------------------------------------------------------------- - -// CleanType is a template that strips 'const' and '&' modifiers from the argument type; -// for example, typename CleanType<A&>::Type is equivalent to A. -template<class T> struct CleanType { typedef T Type; }; -template<class T> struct CleanType<T&> { typedef T Type; }; -template<class T> struct CleanType<const T> { typedef T Type; }; -template<class T> struct CleanType<const T&> { typedef T Type; }; - -// SelfType is a template that yields the argument type. This helps avoid conflicts with -// automatic template argument deduction for function calls when identical argument -// is already defined. -template<class T> struct SelfType { typedef T Type; }; - - - -//------------------------------------------------------------------------------------- -// ThreadCommand specializations for member functions with different number of -// arguments and argument types. - -// Used to return nothing from a ThreadCommand, to avoid problems with 'void'. -struct Void -{ - Void() {} - Void(int) {} -}; - -// ThreadCommand for member function with 0 arguments. -template<class C, class R> -class ThreadCommandMF0 : public ThreadCommand -{ - typedef R (C::*FnPtr)(); - C* pClass; - FnPtr pFn; - R* pRet; - - void executeImpl() const - { - pRet ? (void)(*pRet = (pClass->*pFn)()) : - (void)(pClass->*pFn)(); - } - -public: - ThreadCommandMF0(C* pclass, FnPtr fn, R* ret, bool needsWait) - : ThreadCommand(sizeof(ThreadCommandMF0), needsWait), - pClass(pclass), pFn(fn), pRet(ret) { } - - virtual void Execute() const { executeImpl(); } - virtual ThreadCommand* CopyConstruct(void* p) const - { return Construct<ThreadCommandMF0>(p, *this); } -}; - - -// ThreadCommand for member function with 1 argument. -template<class C, class R, class A0> -class ThreadCommandMF1 : public ThreadCommand -{ - typedef R (C::*FnPtr)(A0); - C* pClass; - FnPtr pFn; - R* pRet; - typename CleanType<A0>::Type AVal0; - - void executeImpl() const - { - pRet ? (void)(*pRet = (pClass->*pFn)(AVal0)) : - (void)(pClass->*pFn)(AVal0); - } - -public: - ThreadCommandMF1(C* pclass, FnPtr fn, R* ret, A0 a0, bool needsWait) - : ThreadCommand(sizeof(ThreadCommandMF1), needsWait), - pClass(pclass), pFn(fn), pRet(ret), AVal0(a0) { } - - virtual void Execute() const { executeImpl(); } - virtual ThreadCommand* CopyConstruct(void* p) const - { return Construct<ThreadCommandMF1>(p, *this); } -}; - -// ThreadCommand for member function with 2 arguments. -template<class C, class R, class A0, class A1> -class ThreadCommandMF2 : public ThreadCommand -{ - typedef R (C::*FnPtr)(A0, A1); - C* pClass; - FnPtr pFn; - R* pRet; - typename CleanType<A0>::Type AVal0; - typename CleanType<A1>::Type AVal1; - - void executeImpl() const - { - pRet ? (void)(*pRet = (pClass->*pFn)(AVal0, AVal1)) : - (void)(pClass->*pFn)(AVal0, AVal1); - } - -public: - ThreadCommandMF2(C* pclass, FnPtr fn, R* ret, A0 a0, A1 a1, bool needsWait) - : ThreadCommand(sizeof(ThreadCommandMF2), needsWait), - pClass(pclass), pFn(fn), pRet(ret), AVal0(a0), AVal1(a1) { } - - virtual void Execute() const { executeImpl(); } - virtual ThreadCommand* CopyConstruct(void* p) const - { return Construct<ThreadCommandMF2>(p, *this); } -}; - - -//------------------------------------------------------------------------------------- -// ***** ThreadCommandQueue - -// ThreadCommandQueue is a queue of executable function-call commands intended to be -// serviced by a single consumer thread. Commands are added to the queue with PushCall -// and removed with PopCall; they are processed in FIFO order. Multiple producer threads -// are supported and will be blocked if internal data buffer is full. - -class ThreadCommandQueue -{ -public: - - ThreadCommandQueue(); - virtual ~ThreadCommandQueue(); - - - // Pops the next command from the thread queue, if any is available. - // The command should be executed by calling popBuffer->Execute(). - // Returns 'false' if no command is available at the time of the call. - bool PopCommand(ThreadCommand::PopBuffer* popBuffer); - - // Generic implementaion of PushCommand; enqueues a command for execution. - // Returns 'false' if push failed, usually indicating thread shutdown. - bool PushCommand(const ThreadCommand& command); - - // - void PushExitCommand(bool wait); - - // Returns 'true' once ExitCommand has been processed, so the thread can shut down. - bool IsExiting() const; - - - // These two virtual functions serve as notifications for derived - // thread waiting. - virtual void OnPushNonEmpty_Locked() { } - virtual void OnPopEmpty_Locked() { } - - - // *** PushCall with no result - - // Enqueue a member function of 'this' class to be called on consumer thread. - // By default the function returns immediately; set 'wait' argument to 'true' to - // wait for completion. - template<class C, class R> - bool PushCall(R (C::*fn)(), bool wait = false) - { return PushCommand(ThreadCommandMF0<C,R>(static_cast<C*>(this), fn, 0, wait)); } - template<class C, class R, class A0> - bool PushCall(R (C::*fn)(A0), typename SelfType<A0>::Type a0, bool wait = false) - { return PushCommand(ThreadCommandMF1<C,R,A0>(static_cast<C*>(this), fn, 0, a0, wait)); } - template<class C, class R, class A0, class A1> - bool PushCall(R (C::*fn)(A0, A1), - typename SelfType<A0>::Type a0, typename SelfType<A1>::Type a1, bool wait = false) - { return PushCommand(ThreadCommandMF2<C,R,A0,A1>(static_cast<C*>(this), fn, 0, a0, a1, wait)); } - // Enqueue a specified member function call of class C. - // By default the function returns immediately; set 'wait' argument to 'true' to - // wait for completion. - template<class C, class R> - bool PushCall(C* p, R (C::*fn)(), bool wait = false) - { return PushCommand(ThreadCommandMF0<C,R>(p, fn, 0, wait)); } - template<class C, class R, class A0> - bool PushCall(C* p, R (C::*fn)(A0), typename SelfType<A0>::Type a0, bool wait = false) - { return PushCommand(ThreadCommandMF1<C,R,A0>(p, fn, 0, a0, wait)); } - template<class C, class R, class A0, class A1> - bool PushCall(C* p, R (C::*fn)(A0, A1), - typename SelfType<A0>::Type a0, typename SelfType<A1>::Type a1, bool wait = false) - { return PushCommand(ThreadCommandMF2<C,R,A0,A1>(p, fn, 0, a0, a1, wait)); } - - - // *** PushCall with Result - - // Enqueue a member function of 'this' class call and wait for call to complete - // on consumer thread before returning. - template<class C, class R> - bool PushCallAndWaitResult(R (C::*fn)(), R* ret) - { return PushCommand(ThreadCommandMF0<C,R>(static_cast<C*>(this), fn, ret, true)); } - template<class C, class R, class A0> - bool PushCallAndWaitResult(R (C::*fn)(A0), R* ret, typename SelfType<A0>::Type a0) - { return PushCommand(ThreadCommandMF1<C,R,A0>(static_cast<C*>(this), fn, ret, a0, true)); } - template<class C, class R, class A0, class A1> - bool PushCallAndWaitResult(R (C::*fn)(A0, A1), R* ret, - typename SelfType<A0>::Type a0, typename SelfType<A1>::Type a1) - { return PushCommand(ThreadCommandMF2<C,R,A0,A1>(static_cast<C*>(this), fn, ret, a0, a1, true)); } - // Enqueue a member function call for class C and wait for the call to complete - // on consumer thread before returning. - template<class C, class R> - bool PushCallAndWaitResult(C* p, R (C::*fn)(), R* ret) - { return PushCommand(ThreadCommandMF0<C,R>(p, fn, ret, true)); } - template<class C, class R, class A0> - bool PushCallAndWaitResult(C* p, R (C::*fn)(A0), R* ret, typename SelfType<A0>::Type a0) - { return PushCommand(ThreadCommandMF1<C,R,A0>(p, fn, ret, a0, true)); } - template<class C, class R, class A0, class A1> - bool PushCallAndWaitResult(C* p, R (C::*fn)(A0, A1), R* ret, - typename SelfType<A0>::Type a0, typename SelfType<A1>::Type a1) - { return PushCommand(ThreadCommandMF2<C,R,A0,A1>(p, fn, ret, a0, a1, true)); } - -private: - class ThreadCommandQueueImpl* pImpl; -}; - - -} // namespace OVR - -#endif // OVR_ThreadCommandQueue_h diff --git a/LibOVR/Src/Kernel/OVR_Threads.h b/LibOVR/Src/Kernel/OVR_Threads.h deleted file mode 100644 index e159157..0000000 --- a/LibOVR/Src/Kernel/OVR_Threads.h +++ /dev/null @@ -1,434 +0,0 @@ -/************************************************************************************ - -PublicHeader: None -Filename : OVR_Threads.h -Content : Contains thread-related (safe) functionality -Created : September 19, 2012 -Notes : - -Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); -you may not use the Oculus VR Rift SDK except in compliance with the License, -which is provided at the time of installation or download, or which -otherwise accompanies this software in either electronic or hard copy form. - -You may obtain a copy of the License at - -http://www.oculusvr.com/licenses/LICENSE-3.2 - -Unless required by applicable law or agreed to in writing, the Oculus VR SDK -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -************************************************************************************/ -#ifndef OVR_Threads_h -#define OVR_Threads_h - -#include "OVR_Types.h" -#include "OVR_Atomic.h" -#include "OVR_RefCount.h" -#include "OVR_Array.h" - -// Defines the infinite wait delay timeout -#define OVR_WAIT_INFINITE 0xFFFFFFFF - -// To be defined in the project configuration options -#ifdef OVR_ENABLE_THREADS - - -namespace OVR { - -//----------------------------------------------------------------------------------- -// ****** Declared classes - -// Declared with thread support only -class Mutex; -class WaitCondition; -class Event; -// Implementation forward declarations -class MutexImpl; -class WaitConditionImpl; - - - -//----------------------------------------------------------------------------------- -// ***** Mutex - -// Mutex class represents a system Mutex synchronization object that provides access -// serialization between different threads, allowing one thread mutually exclusive access -// to a resource. Mutex is more heavy-weight then Lock, but supports WaitCondition. - -class Mutex -{ - friend class WaitConditionImpl; - friend class MutexImpl; - - MutexImpl *pImpl; - -public: - // Constructor/destructor - Mutex(bool recursive = 1); - ~Mutex(); - - // Locking functions - void DoLock(); - bool TryLock(); - void Unlock(); - - // Returns 1 if the mutes is currently locked by another thread - // Returns 0 if the mutex is not locked by another thread, and can therefore be acquired. - bool IsLockedByAnotherThread(); - - // Locker class; Used for automatic locking of a mutex withing scope - class Locker - { - public: - Mutex *pMutex; - Locker(Mutex *pmutex) - { pMutex = pmutex; pMutex->DoLock(); } - ~Locker() - { pMutex->Unlock(); } - }; -}; - - -//----------------------------------------------------------------------------------- -// ***** WaitCondition - -/* - WaitCondition is a synchronization primitive that can be used to implement what is known as a monitor. - Dependent threads wait on a wait condition by calling Wait(), and get woken up by other threads that - call Notify() or NotifyAll(). - - The unique feature of this class is that it provides an atomic way of first releasing a Mutex, and then - starting a wait on a wait condition. If both the mutex and the wait condition are associated with the same - resource, this ensures that any condition checked for while the mutex was locked does not change before - the wait on the condition is actually initiated. -*/ - -class WaitCondition -{ - friend class WaitConditionImpl; - // Internal implementation structure - WaitConditionImpl *pImpl; - -public: - // Constructor/destructor - WaitCondition(); - ~WaitCondition(); - - // Release mutex and wait for condition. The mutex is re-aquired after the wait. - // Delay is specified in milliseconds (1/1000 of a second). - bool Wait(Mutex *pmutex, unsigned delay = OVR_WAIT_INFINITE); - - // Notify a condition, releasing at one object waiting - void Notify(); - // Notify a condition, releasing all objects waiting - void NotifyAll(); -}; - - -//----------------------------------------------------------------------------------- -// ***** Event - -// Event is a wait-able synchronization object similar to Windows event. -// Event can be waited on until it's signaled by another thread calling -// either SetEvent or PulseEvent. - -class Event -{ - // Event state, its mutex and the wait condition - volatile bool State; - volatile bool Temporary; - mutable Mutex StateMutex; - WaitCondition StateWaitCondition; - - void updateState(bool newState, bool newTemp, bool mustNotify); - -public: - Event(bool setInitially = 0) : State(setInitially), Temporary(false) { } - ~Event() { } - - // Wait on an event condition until it is set - // Delay is specified in milliseconds (1/1000 of a second). - bool Wait(unsigned delay = OVR_WAIT_INFINITE); - - // Set an event, releasing objects waiting on it - void SetEvent() - { updateState(true, false, true); } - - // Reset an event, un-signaling it - void ResetEvent() - { updateState(false, false, false); } - - // Set and then reset an event once a waiter is released. - // If threads are already waiting, they will be notified and released - // If threads are not waiting, the event is set until the first thread comes in - void PulseEvent() - { updateState(true, true, true); } -}; - - -//----------------------------------------------------------------------------------- -// ***** Thread class - -// ThreadHandle is a handle to a thread, which on some platforms (e.g. Windows) is -// different from ThreadId. On Unix platforms, a ThreadHandle is the same as a -// ThreadId and is pthread_t. -typedef void* ThreadHandle; - -// ThreadId uniquely identifies a thread; returned by Windows GetCurrentThreadId(), -// Unix pthread_self() and Thread::GetThreadId. -typedef void* ThreadId; - - -// *** Thread flags - -// Indicates that the thread is has been started, i.e. Start method has been called, and threads -// OnExit() method has not yet been called/returned. -#define OVR_THREAD_STARTED 0x01 -// This flag is set once the thread has ran, and finished. -#define OVR_THREAD_FINISHED 0x02 -// This flag is set temporarily if this thread was started suspended. It is used internally. -#define OVR_THREAD_START_SUSPENDED 0x08 -// This flag is used to ask a thread to exit. Message driven threads will usually check this flag -// and finish once it is set. -#define OVR_THREAD_EXIT 0x10 - - -class Thread : public RefCountBase<Thread> -{ // NOTE: Waitable must be the first base since it implements RefCountImpl. -public: - // *** Callback functions, can be used instead of overriding Run - - // Run function prototypes. - // Thread function and user handle passed to it, executed by the default - // Thread::Run implementation if not null. - typedef int (*ThreadFn)(Thread *pthread, void* h); - - // Thread ThreadFunction1 is executed if not 0, otherwise ThreadFunction2 is tried - ThreadFn ThreadFunction; - // User handle passes to a thread - void* UserHandle; - - // Thread state to start a thread with - enum ThreadState - { - NotRunning = 0, - Running = 1, - Suspended = 2 - }; - - // Thread priority - enum ThreadPriority - { - CriticalPriority, - HighestPriority, - AboveNormalPriority, - NormalPriority, - BelowNormalPriority, - LowestPriority, - IdlePriority, - }; - - // Thread constructor parameters - struct CreateParams - { - CreateParams(ThreadFn func = 0, void* hand = 0, size_t ssize = 128 * 1024, - int proc = -1, ThreadState state = NotRunning, ThreadPriority prior = NormalPriority) - : threadFunction(func), userHandle(hand), stackSize(ssize), - processor(proc), initialState(state), priority(prior) {} - ThreadFn threadFunction; // Thread function - void* userHandle; // User handle passes to a thread - size_t stackSize; // Thread stack size - int processor; // Thread hardware processor - ThreadState initialState; // - ThreadPriority priority; // Thread priority - }; - - - // *** Constructors - - // A default constructor always creates a thread in NotRunning state, because - // the derived class has not yet been initialized. The derived class can call Start explicitly. - // "processor" parameter specifies which hardware processor this thread will be run on. - // -1 means OS decides this. Implemented only on Win32 - Thread(size_t stackSize = 128 * 1024, int processor = -1); - // Constructors that initialize the thread with a pointer to function. - // An option to start a thread is available, but it should not be used if classes are derived from Thread. - // "processor" parameter specifies which hardware processor this thread will be run on. - // -1 means OS decides this. Implemented only on Win32 - Thread(ThreadFn threadFunction, void* userHandle = 0, size_t stackSize = 128 * 1024, - int processor = -1, ThreadState initialState = NotRunning); - // Constructors that initialize the thread with a create parameters structure. - explicit Thread(const CreateParams& params); - - // Destructor. - virtual ~Thread(); - - // Waits for all Threads to finish; should be called only from the root - // application thread. Once this function returns, we know that all other - // thread's references to Thread object have been released. - static void OVR_CDECL FinishAllThreads(); - - - // *** Overridable Run function for thread processing - - // - returning from this method will end the execution of the thread - // - return value is usually 0 for success - virtual int Run(); - // Called after return/exit function - virtual void OnExit(); - - - // *** Thread management - - // Starts the thread if its not already running - // - internally sets up the threading and calls Run() - // - initial state can either be Running or Suspended, NotRunning will just fail and do nothing - // - returns the exit code - virtual bool Start(ThreadState initialState = Running); - - // Quits with an exit code - virtual void Exit(int exitCode=0); - - // Suspend the thread until resumed - // Returns 1 for success, 0 for failure. - bool Suspend(); - // Resumes currently suspended thread - // Returns 1 for success, 0 for failure. - bool Resume(); - - // Static function to return a pointer to the current thread - //static Thread* GetThread(); - - - // *** Thread status query functions - - bool GetExitFlag() const; - void SetExitFlag(bool exitFlag); - - // Determines whether the thread was running and is now finished - bool IsFinished() const; - // Determines if the thread is currently suspended - bool IsSuspended() const; - // Returns current thread state - ThreadState GetThreadState() const; - - // Wait for thread to finish for a maxmimum number of milliseconds - // For maxWaitMs = 0 it simply polls and then returns if the thread is not finished - // For maxWaitMs < 0 it will wait forever - bool Join(int maxWaitMs = -1) const; - - // Returns the number of available CPUs on the system - static int GetCPUCount(); - - // Returns the thread exit code. Exit code is initialized to 0, - // and set to the return value if Run function after the thread is finished. - inline int GetExitCode() const { return ExitCode; } - // Returns an OS handle -#if defined(OVR_OS_MS) - void* GetOSHandle() const { return ThreadHandle; } -#else - pthread_t GetOSHandle() const { return ThreadHandle; } -#endif - -#if defined(OVR_OS_MS) - ThreadId GetThreadId() const { return IdValue; } -#else - ThreadId GetThreadId() const { return (ThreadId)GetOSHandle(); } -#endif - - // Returns the platform-specific equivalent const that corresponds to the given ThreadPriority. - static int GetOSPriority(ThreadPriority); - static ThreadPriority GetOVRPriority(int osPriority); // May return a value outside the ThreadPriority enum range in unusual cases. - - // Gets this instance's priority. - ThreadPriority GetPriority(); - - // Gets the current thread's priority. - static ThreadPriority GetCurrentPriority(); - - // Sets this instance's thread's priority. - // Some platforms (e.g. Unix) don't let you set thread priorities unless you have root privileges/ - bool SetPriority(ThreadPriority); - - // Sets the current thread's priority. - static bool SetCurrentPriority(ThreadPriority); - - // *** Sleep - - // Sleep secs seconds - static bool Sleep(unsigned secs); - // Sleep msecs milliseconds - static bool MSleep(unsigned msecs); - - - // *** Debugging functionality - virtual void SetThreadName(const char* name); - static void SetThreadName(const char* name, ThreadId threadId); - static void SetCurrentThreadName(const char* name); - - static void GetThreadName(char* name, size_t nameCapacity, ThreadId threadId); - static void GetCurrentThreadName(char* name, size_t nameCapacity); - -private: -#if defined(OVR_OS_WIN32) - friend unsigned WINAPI Thread_Win32StartFn(void *phandle); -#elif defined(OVR_OS_MS) // Any other Microsoft OS... - friend DWORD WINAPI Thread_Win32StartFn(void *phandle); -#else - friend void *Thread_PthreadStartFn(void * phandle); - - static int InitAttr; - static pthread_attr_t Attr; -#endif - -protected: - // Thread state flags - AtomicInt<uint32_t> ThreadFlags; - AtomicInt<int32_t> SuspendCount; - size_t StackSize; - - // Hardware processor which this thread is running on. - int Processor; - ThreadPriority Priority; - -#if defined(OVR_OS_MS) - void* ThreadHandle; - volatile ThreadId IdValue; - - // System-specific cleanup function called from destructor - void CleanupSystemThread(); - -#else - pthread_t ThreadHandle; -#endif - - // Exit code of the thread, as returned by Run. - int ExitCode; - - // Internal run function. - int PRun(); - // Finishes the thread and releases internal reference to it. - void FinishAndRelease(); - - void Init(const CreateParams& params); - - // Protected copy constructor - Thread(const Thread &source) : RefCountBase<Thread>() { OVR_UNUSED(source); } - -}; - -// Returns the unique Id of a thread it is called on, intended for -// comparison purposes. -ThreadId GetCurrentThreadId(); - - -} // OVR - -#endif // OVR_ENABLE_THREADS -#endif // OVR_Threads_h diff --git a/LibOVR/Src/Kernel/OVR_ThreadsPthread.cpp b/LibOVR/Src/Kernel/OVR_ThreadsPthread.cpp deleted file mode 100644 index 760e489..0000000 --- a/LibOVR/Src/Kernel/OVR_ThreadsPthread.cpp +++ /dev/null @@ -1,984 +0,0 @@ -/************************************************************************************ - -Filename : OVR_ThreadsPthread.cpp -Content : -Created : -Notes : - -Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); -you may not use the Oculus VR Rift SDK except in compliance with the License, -which is provided at the time of installation or download, or which -otherwise accompanies this software in either electronic or hard copy form. - -You may obtain a copy of the License at - -http://www.oculusvr.com/licenses/LICENSE-3.2 - -Unless required by applicable law or agreed to in writing, the Oculus VR SDK -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -************************************************************************************/ - -#include "OVR_Threads.h" -#include "OVR_Hash.h" - -#ifdef OVR_ENABLE_THREADS - -#include "OVR_Timer.h" -#include "OVR_Log.h" - -#include <pthread.h> -#include <sched.h> -#include <time.h> -#include <unistd.h> -#include <sys/time.h> -#include <errno.h> - -#if defined(OVR_OS_MAC) || defined(OVR_OS_BSD) - #include <sys/sysctl.h> - #include <sys/param.h> - #if !defined(OVR_OS_MAC) - #include <pthread_np.h> - #endif -#endif - - - -namespace OVR { - -// ***** Mutex implementation - - -// *** Internal Mutex implementation structure - -class MutexImpl : public NewOverrideBase -{ - // System mutex or semaphore - pthread_mutex_t SMutex; - bool Recursive; - unsigned LockCount; - pthread_t LockedBy; - - friend class WaitConditionImpl; - -public: - // Constructor/destructor - MutexImpl(Mutex* pmutex, bool recursive = 1); - ~MutexImpl(); - - // Locking functions - void DoLock(); - bool TryLock(); - void Unlock(Mutex* pmutex); - // Returns 1 if the mutes is currently locked - bool IsLockedByAnotherThread(Mutex* pmutex); - bool IsSignaled() const; -}; - -pthread_mutexattr_t Lock::RecursiveAttr; -bool Lock::RecursiveAttrInit = 0; - -// *** Constructor/destructor -MutexImpl::MutexImpl(Mutex* pmutex, bool recursive) -{ - OVR_UNUSED(pmutex); - Recursive = recursive; - LockCount = 0; - - if (Recursive) - { - if (!Lock::RecursiveAttrInit) - { - pthread_mutexattr_init(&Lock::RecursiveAttr); - pthread_mutexattr_settype(&Lock::RecursiveAttr, PTHREAD_MUTEX_RECURSIVE); - Lock::RecursiveAttrInit = 1; - } - - pthread_mutex_init(&SMutex, &Lock::RecursiveAttr); - } - else - pthread_mutex_init(&SMutex, 0); -} - -MutexImpl::~MutexImpl() -{ - pthread_mutex_destroy(&SMutex); -} - - -// Lock and try lock -void MutexImpl::DoLock() -{ - while (pthread_mutex_lock(&SMutex)) - ; - LockCount++; - LockedBy = pthread_self(); -} - -bool MutexImpl::TryLock() -{ - if (!pthread_mutex_trylock(&SMutex)) - { - LockCount++; - LockedBy = pthread_self(); - return 1; - } - - return 0; -} - -void MutexImpl::Unlock(Mutex* pmutex) -{ - OVR_UNUSED(pmutex); - OVR_ASSERT(pthread_self() == LockedBy && LockCount > 0); - - //unsigned lockCount; - LockCount--; - //lockCount = LockCount; - - pthread_mutex_unlock(&SMutex); -} - -bool MutexImpl::IsLockedByAnotherThread(Mutex* pmutex) -{ - OVR_UNUSED(pmutex); - // There could be multiple interpretations of IsLocked with respect to current thread - if (LockCount == 0) - return 0; - if (pthread_self() != LockedBy) - return 1; - return 0; -} - -bool MutexImpl::IsSignaled() const -{ - // An mutex is signaled if it is not locked ANYWHERE - // Note that this is different from IsLockedByAnotherThread function, - // that takes current thread into account - return LockCount == 0; -} - - -// *** Actual Mutex class implementation - -Mutex::Mutex(bool recursive) -{ - // NOTE: RefCount mode already thread-safe for all waitables. - pImpl = new MutexImpl(this, recursive); -} - -Mutex::~Mutex() -{ - delete pImpl; -} - -// Lock and try lock -void Mutex::DoLock() -{ - pImpl->DoLock(); -} -bool Mutex::TryLock() -{ - return pImpl->TryLock(); -} -void Mutex::Unlock() -{ - pImpl->Unlock(this); -} -bool Mutex::IsLockedByAnotherThread() -{ - return pImpl->IsLockedByAnotherThread(this); -} - - - -//----------------------------------------------------------------------------------- -// ***** Event - -bool Event::Wait(unsigned delay) -{ - Mutex::Locker lock(&StateMutex); - - // Do the correct amount of waiting - if (delay == OVR_WAIT_INFINITE) - { - while(!State) - StateWaitCondition.Wait(&StateMutex); - } - else if (delay) - { - if (!State) - StateWaitCondition.Wait(&StateMutex, delay); - } - - bool state = State; - // Take care of temporary 'pulsing' of a state - if (Temporary) - { - Temporary = false; - State = false; - } - return state; -} - -void Event::updateState(bool newState, bool newTemp, bool mustNotify) -{ - Mutex::Locker lock(&StateMutex); - State = newState; - Temporary = newTemp; - if (mustNotify) - StateWaitCondition.NotifyAll(); -} - - - -// ***** Wait Condition Implementation - -// Internal implementation class -class WaitConditionImpl : public NewOverrideBase -{ - pthread_mutex_t SMutex; - pthread_cond_t Condv; - -public: - - // Constructor/destructor - WaitConditionImpl(); - ~WaitConditionImpl(); - - // Release mutex and wait for condition. The mutex is re-aqured after the wait. - bool Wait(Mutex *pmutex, unsigned delay = OVR_WAIT_INFINITE); - - // Notify a condition, releasing at one object waiting - void Notify(); - // Notify a condition, releasing all objects waiting - void NotifyAll(); -}; - - -WaitConditionImpl::WaitConditionImpl() -{ - pthread_mutex_init(&SMutex, 0); - pthread_cond_init(&Condv, 0); -} - -WaitConditionImpl::~WaitConditionImpl() -{ - pthread_mutex_destroy(&SMutex); - pthread_cond_destroy(&Condv); -} - -bool WaitConditionImpl::Wait(Mutex *pmutex, unsigned delay) -{ - bool result = 1; - unsigned lockCount = pmutex->pImpl->LockCount; - - // Mutex must have been locked - if (lockCount == 0) - return 0; - - pthread_mutex_lock(&SMutex); - - // Finally, release a mutex or semaphore - if (pmutex->pImpl->Recursive) - { - // Release the recursive mutex N times - pmutex->pImpl->LockCount = 0; - for(unsigned i=0; i<lockCount; i++) - pthread_mutex_unlock(&pmutex->pImpl->SMutex); - } - else - { - pmutex->pImpl->LockCount = 0; - pthread_mutex_unlock(&pmutex->pImpl->SMutex); - } - - // Note that there is a gap here between mutex.Unlock() and Wait(). - // The other mutex protects this gap. - - if (delay == OVR_WAIT_INFINITE) - pthread_cond_wait(&Condv,&SMutex); - else - { - timespec ts; - - struct timeval tv; - gettimeofday(&tv, 0); - - ts.tv_sec = tv.tv_sec + (delay / 1000); - ts.tv_nsec = (tv.tv_usec + (delay % 1000) * 1000) * 1000; - - if (ts.tv_nsec > 999999999) - { - ts.tv_sec++; - ts.tv_nsec -= 1000000000; - } - int r = pthread_cond_timedwait(&Condv,&SMutex, &ts); - OVR_ASSERT(r == 0 || r == ETIMEDOUT); - if (r) - result = 0; - } - - pthread_mutex_unlock(&SMutex); - - // Re-aquire the mutex - for(unsigned i=0; i<lockCount; i++) - pmutex->DoLock(); - - // Return the result - return result; -} - -// Notify a condition, releasing the least object in a queue -void WaitConditionImpl::Notify() -{ - pthread_mutex_lock(&SMutex); - pthread_cond_signal(&Condv); - pthread_mutex_unlock(&SMutex); -} - -// Notify a condition, releasing all objects waiting -void WaitConditionImpl::NotifyAll() -{ - pthread_mutex_lock(&SMutex); - pthread_cond_broadcast(&Condv); - pthread_mutex_unlock(&SMutex); -} - - - -// *** Actual implementation of WaitCondition - -WaitCondition::WaitCondition() -{ - pImpl = new WaitConditionImpl; -} -WaitCondition::~WaitCondition() -{ - delete pImpl; -} - -bool WaitCondition::Wait(Mutex *pmutex, unsigned delay) -{ - return pImpl->Wait(pmutex, delay); -} -// Notification -void WaitCondition::Notify() -{ - pImpl->Notify(); -} -void WaitCondition::NotifyAll() -{ - pImpl->NotifyAll(); -} - - -// ***** Current thread - -// Per-thread variable -/* -static __thread Thread* pCurrentThread = 0; - -// Static function to return a pointer to the current thread -void Thread::InitCurrentThread(Thread *pthread) -{ - pCurrentThread = pthread; -} - -// Static function to return a pointer to the current thread -Thread* Thread::GetThread() -{ - return pCurrentThread; -} -*/ - - -// *** Thread constructors. - -Thread::Thread(UPInt stackSize, int processor) -{ - // NOTE: RefCount mode already thread-safe for all Waitable objects. - CreateParams params; - params.stackSize = stackSize; - params.processor = processor; - Init(params); -} - -Thread::Thread(Thread::ThreadFn threadFunction, void* userHandle, UPInt stackSize, - int processor, Thread::ThreadState initialState) -{ - CreateParams params(threadFunction, userHandle, stackSize, processor, initialState); - Init(params); -} - -Thread::Thread(const CreateParams& params) -{ - Init(params); -} - -void Thread::Init(const CreateParams& params) -{ - // Clear the variables - ThreadFlags = 0; - ThreadHandle = 0; - ExitCode = 0; - SuspendCount = 0; - StackSize = params.stackSize; - Processor = params.processor; - Priority = params.priority; - - // Clear Function pointers - ThreadFunction = params.threadFunction; - UserHandle = params.userHandle; - if (params.initialState != NotRunning) - Start(params.initialState); -} - -Thread::~Thread() -{ - // Thread should not running while object is being destroyed, - // this would indicate ref-counting issue. - //OVR_ASSERT(IsRunning() == 0); - - // Clean up thread. - ThreadHandle = 0; -} - - - -// *** Overridable User functions. - -// Default Run implementation -int Thread::Run() -{ - // Call pointer to function, if available. - return (ThreadFunction) ? ThreadFunction(this, UserHandle) : 0; -} -void Thread::OnExit() -{ -} - - -// Finishes the thread and releases internal reference to it. -void Thread::FinishAndRelease() -{ - // Note: thread must be US. - ThreadFlags &= (UInt32)~(OVR_THREAD_STARTED); - ThreadFlags |= OVR_THREAD_FINISHED; - - // Release our reference; this is equivalent to 'delete this' - // from the point of view of our thread. - Release(); -} - - - -// *** ThreadList - used to track all created threads - -class ThreadList : public NewOverrideBase -{ - //------------------------------------------------------------------------ - struct ThreadHashOp - { - size_t operator()(const Thread* ptr) - { - return (((size_t)ptr) >> 6) ^ (size_t)ptr; - } - }; - - HashSet<Thread*, ThreadHashOp> ThreadSet; - Mutex ThreadMutex; - WaitCondition ThreadsEmpty; - // Track the root thread that created us. - pthread_t RootThreadId; - - static ThreadList* volatile pRunningThreads; - - void addThread(Thread *pthread) - { - Mutex::Locker lock(&ThreadMutex); - ThreadSet.Add(pthread); - } - - void removeThread(Thread *pthread) - { - Mutex::Locker lock(&ThreadMutex); - ThreadSet.Remove(pthread); - if (ThreadSet.GetSize() == 0) - ThreadsEmpty.Notify(); - } - - void finishAllThreads() - { - // Only original root thread can call this. - OVR_ASSERT(pthread_self() == RootThreadId); - - Mutex::Locker lock(&ThreadMutex); - while (ThreadSet.GetSize() != 0) - ThreadsEmpty.Wait(&ThreadMutex); - } - -public: - - ThreadList() - { - RootThreadId = pthread_self(); - } - ~ThreadList() { } - - - static void AddRunningThread(Thread *pthread) - { - // Non-atomic creation ok since only the root thread - if (!pRunningThreads) - { - pRunningThreads = new ThreadList; - OVR_ASSERT(pRunningThreads); - } - pRunningThreads->addThread(pthread); - } - - // NOTE: 'pthread' might be a dead pointer when this is - // called so it should not be accessed; it is only used - // for removal. - static void RemoveRunningThread(Thread *pthread) - { - OVR_ASSERT(pRunningThreads); - pRunningThreads->removeThread(pthread); - } - - static void FinishAllThreads() - { - // This is ok because only root thread can wait for other thread finish. - if (pRunningThreads) - { - pRunningThreads->finishAllThreads(); - delete pRunningThreads; - pRunningThreads = 0; - } - } -}; - -// By default, we have no thread list. -ThreadList* volatile ThreadList::pRunningThreads = 0; - - -// FinishAllThreads - exposed publicly in Thread. -void Thread::FinishAllThreads() -{ - ThreadList::FinishAllThreads(); -} - -// *** Run override - -int Thread::PRun() -{ - // Suspend us on start, if requested - if (ThreadFlags & OVR_THREAD_START_SUSPENDED) - { - Suspend(); - ThreadFlags &= (UInt32)~OVR_THREAD_START_SUSPENDED; - } - - // Call the virtual run function - ExitCode = Run(); - return ExitCode; -} - - - - -// *** User overridables - -bool Thread::GetExitFlag() const -{ - return (ThreadFlags & OVR_THREAD_EXIT) != 0; -} - -void Thread::SetExitFlag(bool exitFlag) -{ - // The below is atomic since ThreadFlags is AtomicInt. - if (exitFlag) - ThreadFlags |= OVR_THREAD_EXIT; - else - ThreadFlags &= (UInt32) ~OVR_THREAD_EXIT; -} - - -// Determines whether the thread was running and is now finished -bool Thread::IsFinished() const -{ - return (ThreadFlags & OVR_THREAD_FINISHED) != 0; -} -// Determines whether the thread is suspended -bool Thread::IsSuspended() const -{ - return SuspendCount > 0; -} -// Returns current thread state -Thread::ThreadState Thread::GetThreadState() const -{ - if (IsSuspended()) - return Suspended; - if (ThreadFlags & OVR_THREAD_STARTED) - return Running; - return NotRunning; -} - -// Join thread -bool Thread::Join(int maxWaitMs) const -{ - // If polling, - if (maxWaitMs == 0) - { - // Just return if finished - return IsFinished(); - } - // If waiting forever, - else if (maxWaitMs > 0) - { - UInt32 t0 = Timer::GetTicksMs(); - - while (!IsFinished()) - { - UInt32 t1 = Timer::GetTicksMs(); - - // If the wait has expired, - int delta = (int)(t1 - t0); - if (delta >= maxWaitMs) - { - return false; - } - - Thread::MSleep(10); - } - - return true; - } - else - { - while (!IsFinished()) - { - pthread_join(ThreadHandle, NULL); - } - } - - return true; -} - -/* -static const char* mapsched_policy(int policy) -{ - switch(policy) - { - case SCHED_OTHER: - return "SCHED_OTHER"; - case SCHED_RR: - return "SCHED_RR"; - case SCHED_FIFO: - return "SCHED_FIFO"; - - } - return "UNKNOWN"; -} - int policy; - sched_param sparam; - pthread_getschedparam(pthread_self(), &policy, &sparam); - int max_prior = sched_get_priority_max(policy); - int min_prior = sched_get_priority_min(policy); - printf(" !!!! policy: %s, priority: %d, max priority: %d, min priority: %d\n", mapsched_policy(policy), sparam.sched_priority, max_prior, min_prior); -#include <stdio.h> -*/ -// ***** Thread management - -// The actual first function called on thread start -void* Thread_PthreadStartFn(void* phandle) -{ - Thread* pthread = (Thread*)phandle; - int result = pthread->PRun(); - // Signal the thread as done and release it atomically. - pthread->FinishAndRelease(); - // At this point Thread object might be dead; however we can still pass - // it to RemoveRunningThread since it is only used as a key there. - ThreadList::RemoveRunningThread(pthread); - return reinterpret_cast<void*>(result); -} - -int Thread::InitAttr = 0; -pthread_attr_t Thread::Attr; - -/* static */ -int Thread::GetOSPriority(ThreadPriority p) -{ - OVR_UNUSED(p); - return -1; -} - -/* static */ -Thread::ThreadPriority Thread::GetOVRPriority(int osPriority) -{ - #if defined(OVR_OS_LINUX) - return (ThreadPriority)(Thread::NormalPriority - osPriority); // This works for both SCHED_OTHER, SCHED_RR, and SCHED_FIFO. - #else - // Apple priorities are such that the min is a value less than the max. - static int minPriority = sched_get_priority_min(SCHED_FIFO); // We don't have a means to pass a policy type to this function. - static int maxPriority = sched_get_priority_max(SCHED_FIFO); - - return (ThreadPriority)(Thread::NormalPriority - (osPriority - ((minPriority + maxPriority) / 2))); - #endif -} - - -Thread::ThreadPriority Thread::GetPriority() -{ - int policy; - sched_param param; - - int result = pthread_getschedparam(ThreadHandle, &policy, ¶m); - - if(result == 0) - { - #if !defined(OVR_OS_LINUX) - if(policy == SCHED_OTHER) - { - return Thread::NormalPriority; //SCHED_OTHER allows only normal priority on BSD-style Unix and Mac OS X. - } - #endif - - return GetOVRPriority(param.sched_priority); - } - - return Thread::NormalPriority; -} - -/* static */ -Thread::ThreadPriority Thread::GetCurrentPriority() -{ - int policy; - sched_param param; - pthread_t currentThreadId = pthread_self(); - - int result = pthread_getschedparam(currentThreadId, &policy, ¶m); - - if(result == 0) - { - #if !defined(OVR_OS_LINUX) - if(policy == SCHED_OTHER) - { - return Thread::NormalPriority; //SCHED_OTHER allows only normal priority on BSD-style Unix and Mac OS X. - } - #endif - - return GetOVRPriority(param.sched_priority); - } - - return Thread::NormalPriority; -} - - -bool Thread::SetPriority(ThreadPriority) -{ - // We currently fail. To do: add code to support this via pthread_getschedparam/pthread_attr_setschedparam - // This won't work unless using SCHED_FIFO or SCHED_RR anyway, which require root privileges. - return false; -} - -/* static */ -bool Thread::SetCurrentPriority(ThreadPriority) -{ - // We currently fail. To do: add code to support this via pthread_getschedparam/pthread_attr_setschedparam - // This won't work unless using SCHED_FIFO or SCHED_RR anyway, which require root privileges. - return false; -} - -bool Thread::Start(ThreadState initialState) -{ - if (initialState == NotRunning) - return 0; - if (GetThreadState() != NotRunning) - { - OVR_DEBUG_LOG(("Thread::Start failed - thread %p already running", this)); - return 0; - } - - if (!InitAttr) - { - pthread_attr_init(&Attr); - pthread_attr_setdetachstate(&Attr, PTHREAD_CREATE_DETACHED); - pthread_attr_setstacksize(&Attr, 128 * 1024); - sched_param sparam; - sparam.sched_priority = Thread::GetOSPriority(NormalPriority); - pthread_attr_setschedparam(&Attr, &sparam); - InitAttr = 1; - } - - ExitCode = 0; - SuspendCount = 0; - ThreadFlags = (initialState == Running) ? 0 : OVR_THREAD_START_SUSPENDED; - - // AddRef to us until the thread is finished - AddRef(); - ThreadList::AddRunningThread(this); - - int result; - if (StackSize != 128 * 1024 || Priority != NormalPriority) - { - pthread_attr_t attr; - - pthread_attr_init(&attr); - pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); - pthread_attr_setstacksize(&attr, StackSize); - sched_param sparam; - sparam.sched_priority = Thread::GetOSPriority(Priority); - pthread_attr_setschedparam(&attr, &sparam); - result = pthread_create(&ThreadHandle, &attr, Thread_PthreadStartFn, this); - pthread_attr_destroy(&attr); - } - else - result = pthread_create(&ThreadHandle, &Attr, Thread_PthreadStartFn, this); - - if (result) - { - ThreadFlags = 0; - Release(); - ThreadList::RemoveRunningThread(this); - return 0; - } - return 1; -} - - -// Suspend the thread until resumed -bool Thread::Suspend() -{ - OVR_DEBUG_LOG(("Thread::Suspend - cannot suspend threads on this system")); - return 0; -} - -// Resumes currently suspended thread -bool Thread::Resume() -{ - return 0; -} - - -// Quits with an exit code -void Thread::Exit(int exitCode) -{ - // Can only exist the current thread - // if (GetThread() != this) - // return; - - // Call the virtual OnExit function - OnExit(); - - // Signal this thread object as done and release it's references. - FinishAndRelease(); - ThreadList::RemoveRunningThread(this); - - pthread_exit(reinterpret_cast<void*>(exitCode)); -} - -ThreadId GetCurrentThreadId() -{ - return (void*)pthread_self(); -} - -// *** Sleep functions - -/* static */ -bool Thread::Sleep(unsigned secs) -{ - sleep(secs); - return 1; -} -/* static */ -bool Thread::MSleep(unsigned msecs) -{ - usleep(msecs*1000); - return 1; -} - -/* static */ -int Thread::GetCPUCount() -{ - #if defined(OVR_OS_MAC) || defined(OVR_OS_BSD) - // http://developer.apple.com/mac/library/documentation/Darwin/Reference/ManPages/man3/sysctlbyname.3.html - int cpuCount = 0; - size_t len = sizeof(cpuCount); - - if(sysctlbyname("hw.logicalcpu", &cpuCount, &len, NULL, 0) != 0) - cpuCount = 1; - - return cpuCount; - - #else // Linux, Android - - // Alternative: read /proc/cpuinfo - #ifdef _SC_NPROCESSORS_ONLN - return (int)sysconf(_SC_NPROCESSORS_ONLN); - #else - return 1; - #endif - #endif -} - - -void Thread::SetThreadName( const char* name ) -{ - #if defined (OVR_OS_APPLE) - if(ThreadHandle == pthread_self()) - pthread_setname_np(name); - // Else there's nothing we can do. - #else - if(ThreadHandle != 0) - pthread_setname_np(ThreadHandle, name); - // Else we can possibly save this name and set it later when the thread starts. - #endif -} - - -void Thread::SetThreadName(const char* name, ThreadId threadId) -{ - #if defined (OVR_OS_APPLE) - if(pthread_equal((pthread_t)threadId, pthread_self())) - pthread_setname_np(name); - // Else there's no way to set the name of another thread. - #else - pthread_setname_np((pthread_t)threadId, name); - #endif -} - - -void Thread::SetCurrentThreadName(const char* name) -{ - #if defined (OVR_OS_APPLE) - pthread_setname_np(name); - #else - pthread_setname_np(pthread_self(), name); - #endif -} - - -void Thread::GetThreadName(char* name, size_t nameCapacity, ThreadId threadId) -{ - name[0] = 0; - pthread_getname_np((pthread_t)threadId, name, nameCapacity); -} - - -void Thread::GetCurrentThreadName(char* name, size_t nameCapacity) -{ - name[0] = 0; - pthread_getname_np(pthread_self(), name, nameCapacity); -} - - -} // namespace OVR - -#endif // OVR_ENABLE_THREADS diff --git a/LibOVR/Src/Kernel/OVR_ThreadsWinAPI.cpp b/LibOVR/Src/Kernel/OVR_ThreadsWinAPI.cpp deleted file mode 100644 index 4786435..0000000 --- a/LibOVR/Src/Kernel/OVR_ThreadsWinAPI.cpp +++ /dev/null @@ -1,1146 +0,0 @@ -/************************************************************************************
-
-Filename : OVR_ThreadsWinAPI.cpp
-Platform : WinAPI
-Content : Windows specific thread-related (safe) functionality
-Created : September 19, 2012
-Notes :
-
-Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved.
-
-Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License");
-you may not use the Oculus VR Rift SDK except in compliance with the License,
-which is provided at the time of installation or download, or which
-otherwise accompanies this software in either electronic or hard copy form.
-
-You may obtain a copy of the License at
-
-http://www.oculusvr.com/licenses/LICENSE-3.2
-
-Unless required by applicable law or agreed to in writing, the Oculus VR SDK
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-
-************************************************************************************/
-
-#include "OVR_Threads.h"
-#include "OVR_Hash.h"
-#include "OVR_Log.h"
-#include "OVR_Timer.h"
-
-#ifdef OVR_ENABLE_THREADS
-
-// For _beginthreadex / _endtheadex
-#include <process.h>
-
-namespace OVR {
-
-
-//-----------------------------------------------------------------------------------
-// *** Internal Mutex implementation class
-
-class MutexImpl : public NewOverrideBase
-{
- // System mutex or semaphore
- HANDLE hMutexOrSemaphore;
- bool Recursive;
- volatile unsigned LockCount;
-
- friend class WaitConditionImpl;
-
-public:
- // Constructor/destructor
- MutexImpl(bool recursive = 1);
- ~MutexImpl();
-
- // Locking functions
- void DoLock();
- bool TryLock();
- void Unlock(Mutex* pmutex);
- // Returns 1 if the mutes is currently locked
- bool IsLockedByAnotherThread(Mutex* pmutex);
-};
-
-// *** Constructor/destructor
-MutexImpl::MutexImpl(bool recursive)
-{
- Recursive = recursive;
- LockCount = 0;
-#if defined(OVR_OS_WIN32) // Older versions of Windows don't support CreateSemaphoreEx, so stick with CreateSemaphore for portability.
- hMutexOrSemaphore = Recursive ? CreateMutex(NULL, 0, NULL) : CreateSemaphore(NULL, 1, 1, NULL);
-#else
- // No CreateSemaphore() call, so emulate it.
- hMutexOrSemaphore = Recursive ? CreateMutex(NULL, 0, NULL) : CreateSemaphoreEx(NULL, 1, 1, NULL, 0, SEMAPHORE_ALL_ACCESS);
-#endif
-}
-MutexImpl::~MutexImpl()
-{
- CloseHandle(hMutexOrSemaphore);
-}
-
-
-// Lock and try lock
-void MutexImpl::DoLock()
-{
- if (::WaitForSingleObject(hMutexOrSemaphore, INFINITE) != WAIT_OBJECT_0)
- return;
- LockCount++;
-}
-
-bool MutexImpl::TryLock()
-{
- DWORD ret;
- if ((ret=::WaitForSingleObject(hMutexOrSemaphore, 0)) != WAIT_OBJECT_0)
- return 0;
- LockCount++;
- return 1;
-}
-
-void MutexImpl::Unlock(Mutex* pmutex)
-{
- OVR_UNUSED(pmutex);
-
- unsigned lockCount;
- LockCount--;
- lockCount = LockCount;
-
- // Release mutex
- if ((Recursive ? ReleaseMutex(hMutexOrSemaphore) :
- ReleaseSemaphore(hMutexOrSemaphore, 1, NULL)) != 0)
- {
- // This used to call Wait handlers if lockCount == 0.
- }
-}
-
-bool MutexImpl::IsLockedByAnotherThread(Mutex* pmutex)
-{
- // There could be multiple interpretations of IsLocked with respect to current thread
- if (LockCount == 0)
- return 0;
- if (!TryLock())
- return 1;
- Unlock(pmutex);
- return 0;
-}
-
-/*
-bool MutexImpl::IsSignaled() const
-{
- // An mutex is signaled if it is not locked ANYWHERE
- // Note that this is different from IsLockedByAnotherThread function,
- // that takes current thread into account
- return LockCount == 0;
-}
-*/
-
-
-// *** Actual Mutex class implementation
-
-Mutex::Mutex(bool recursive)
-{
- pImpl = new MutexImpl(recursive);
-}
-Mutex::~Mutex()
-{
- delete pImpl;
-}
-
-// Lock and try lock
-void Mutex::DoLock()
-{
- pImpl->DoLock();
-}
-bool Mutex::TryLock()
-{
- return pImpl->TryLock();
-}
-void Mutex::Unlock()
-{
- pImpl->Unlock(this);
-}
-bool Mutex::IsLockedByAnotherThread()
-{
- return pImpl->IsLockedByAnotherThread(this);
-}
-
-//-----------------------------------------------------------------------------------
-// ***** Event
-
-bool Event::Wait(unsigned delay)
-{
- Mutex::Locker lock(&StateMutex);
-
- // Do the correct amount of waiting
- if (delay == OVR_WAIT_INFINITE)
- {
- while(!State)
- StateWaitCondition.Wait(&StateMutex);
- }
- else if (delay)
- {
- if (!State)
- StateWaitCondition.Wait(&StateMutex, delay);
- }
-
- bool state = State;
- // Take care of temporary 'pulsing' of a state
- if (Temporary)
- {
- Temporary = false;
- State = false;
- }
- return state;
-}
-
-void Event::updateState(bool newState, bool newTemp, bool mustNotify)
-{
- Mutex::Locker lock(&StateMutex);
- State = newState;
- Temporary = newTemp;
- if (mustNotify)
- StateWaitCondition.NotifyAll();
-}
-
-
-//-----------------------------------------------------------------------------------
-// ***** Win32 Wait Condition Implementation
-
-// Internal implementation class
-class WaitConditionImpl : public NewOverrideBase
-{
- // Event pool entries for extra events
- struct EventPoolEntry : public NewOverrideBase
- {
- HANDLE hEvent;
- EventPoolEntry *pNext;
- EventPoolEntry *pPrev;
- };
-
- Lock WaitQueueLoc;
- // Stores free events that can be used later
- EventPoolEntry * pFreeEventList;
-
- // A queue of waiting objects to be signaled
- EventPoolEntry* pQueueHead;
- EventPoolEntry* pQueueTail;
-
- // Allocation functions for free events
- EventPoolEntry* GetNewEvent();
- void ReleaseEvent(EventPoolEntry* pevent);
-
- // Queue operations
- void QueuePush(EventPoolEntry* pentry);
- EventPoolEntry* QueuePop();
- void QueueFindAndRemove(EventPoolEntry* pentry);
-
-public:
-
- // Constructor/destructor
- WaitConditionImpl();
- ~WaitConditionImpl();
-
- // Release mutex and wait for condition. The mutex is re-acqured after the wait.
- bool Wait(Mutex *pmutex, unsigned delay = OVR_WAIT_INFINITE);
-
- // Notify a condition, releasing at one object waiting
- void Notify();
- // Notify a condition, releasing all objects waiting
- void NotifyAll();
-};
-
-
-
-WaitConditionImpl::WaitConditionImpl()
-{
- pFreeEventList = 0;
- pQueueHead =
- pQueueTail = 0;
-}
-
-WaitConditionImpl::~WaitConditionImpl()
-{
- // Free all the resources
- EventPoolEntry* p = pFreeEventList;
- EventPoolEntry* pentry;
-
- while(p)
- {
- // Move to next
- pentry = p;
- p = p->pNext;
- // Delete old
- ::CloseHandle(pentry->hEvent);
- delete pentry;
- }
- // Shouldn't we also consider the queue?
-
- // To be safe
- pFreeEventList = 0;
- pQueueHead =
- pQueueTail = 0;
-}
-
-
-// Allocation functions for free events
-WaitConditionImpl::EventPoolEntry* WaitConditionImpl::GetNewEvent()
-{
- EventPoolEntry* pentry;
-
- // If there are any free nodes, use them
- if (pFreeEventList)
- {
- pentry = pFreeEventList;
- pFreeEventList = pFreeEventList->pNext;
- }
- else
- {
- // Allocate a new node
- pentry = new EventPoolEntry;
- pentry->pNext = 0;
- pentry->pPrev = 0;
- // Non-signaled manual event
- pentry->hEvent = ::CreateEvent(NULL, TRUE, 0, NULL);
- }
-
- return pentry;
-}
-
-void WaitConditionImpl::ReleaseEvent(EventPoolEntry* pevent)
-{
- // Mark event as non-signaled
- ::ResetEvent(pevent->hEvent);
- // And add it to free pool
- pevent->pNext = pFreeEventList;
- pevent->pPrev = 0;
- pFreeEventList = pevent;
-}
-
-// Queue operations
-void WaitConditionImpl::QueuePush(EventPoolEntry* pentry)
-{
- // Items already exist? Just add to tail
- if (pQueueTail)
- {
- pentry->pPrev = pQueueTail;
- pQueueTail->pNext = pentry;
- pentry->pNext = 0;
- pQueueTail = pentry;
- }
- else
- {
- // No items in queue
- pentry->pNext =
- pentry->pPrev = 0;
- pQueueHead =
- pQueueTail = pentry;
- }
-}
-
-WaitConditionImpl::EventPoolEntry* WaitConditionImpl::QueuePop()
-{
- EventPoolEntry* pentry = pQueueHead;
-
- // No items, null pointer
- if (pentry)
- {
- // More items after this one? just grab the first item
- if (pQueueHead->pNext)
- {
- pQueueHead = pentry->pNext;
- pQueueHead->pPrev = 0;
- }
- else
- {
- // Last item left
- pQueueTail =
- pQueueHead = 0;
- }
- }
- return pentry;
-}
-
-void WaitConditionImpl::QueueFindAndRemove(EventPoolEntry* pentry)
-{
- // Do an exhaustive search looking for an entry
- EventPoolEntry* p = pQueueHead;
-
- while(p)
- {
- // Entry found? Remove.
- if (p == pentry)
- {
-
- // Remove the node form the list
- // Prev link
- if (pentry->pPrev)
- pentry->pPrev->pNext = pentry->pNext;
- else
- pQueueHead = pentry->pNext;
- // Next link
- if (pentry->pNext)
- pentry->pNext->pPrev = pentry->pPrev;
- else
- pQueueTail = pentry->pPrev;
- // Done
- return;
- }
-
- // Move to next item
- p = p->pNext;
- }
-}
-
-
-bool WaitConditionImpl::Wait(Mutex *pmutex, unsigned delay)
-{
- bool result = 0;
- unsigned i;
- unsigned lockCount = pmutex->pImpl->LockCount;
- EventPoolEntry* pentry;
-
- // Mutex must have been locked
- if (lockCount == 0)
- return 0;
-
- // Add an object to the wait queue
- WaitQueueLoc.DoLock();
- QueuePush(pentry = GetNewEvent());
- WaitQueueLoc.Unlock();
-
- // Finally, release a mutex or semaphore
- if (pmutex->pImpl->Recursive)
- {
- // Release the recursive mutex N times
- pmutex->pImpl->LockCount = 0;
- for(i=0; i<lockCount; i++)
- ::ReleaseMutex(pmutex->pImpl->hMutexOrSemaphore);
- }
- else
- {
- pmutex->pImpl->LockCount = 0;
- ::ReleaseSemaphore(pmutex->pImpl->hMutexOrSemaphore, 1, NULL);
- }
-
- // Note that there is a gap here between mutex.Unlock() and Wait(). However,
- // if notify() comes in at this point in the other thread it will set our
- // corresponding event so wait will just fall through, as expected.
-
- // Block and wait on the event
- DWORD waitResult = ::WaitForSingleObject(pentry->hEvent,
- (delay == OVR_WAIT_INFINITE) ? INFINITE : delay);
- /*
-repeat_wait:
- DWORD waitResult =
-
- ::MsgWaitForMultipleObjects(1, &pentry->hEvent, FALSE,
- (delay == OVR_WAIT_INFINITE) ? INFINITE : delay,
- QS_ALLINPUT);
- */
-
- WaitQueueLoc.DoLock();
- switch(waitResult)
- {
- case WAIT_ABANDONED:
- case WAIT_OBJECT_0:
- result = 1;
- // Wait was successful, therefore the event entry should already be removed
- // So just add entry back to a free list
- ReleaseEvent(pentry);
- break;
- /*
- case WAIT_OBJECT_0 + 1:
- // Messages in WINDOWS queue
- {
- MSG msg;
- PeekMessage(&msg, NULL, 0U, 0U, PM_NOREMOVE);
- WaitQueueLoc.Unlock();
- goto repeat_wait;
- }
- break; */
- default:
- // Timeout, our entry should still be in a queue
- QueueFindAndRemove(pentry);
- ReleaseEvent(pentry);
- }
- WaitQueueLoc.Unlock();
-
- // Re-aquire the mutex
- for(i=0; i<lockCount; i++)
- pmutex->DoLock();
-
- // Return the result
- return result;
-}
-
-// Notify a condition, releasing the least object in a queue
-void WaitConditionImpl::Notify()
-{
- Lock::Locker lock(&WaitQueueLoc);
-
- // Pop last entry & signal it
- EventPoolEntry* pentry = QueuePop();
- if (pentry)
- ::SetEvent(pentry->hEvent);
-}
-
-// Notify a condition, releasing all objects waiting
-void WaitConditionImpl::NotifyAll()
-{
- Lock::Locker lock(&WaitQueueLoc);
-
- // Pop and signal all events
- // NOTE : There is no need to release the events, it's the waiters job to do so
- EventPoolEntry* pentry = QueuePop();
- while (pentry)
- {
- ::SetEvent(pentry->hEvent);
- pentry = QueuePop();
- }
-}
-
-
-
-// *** Actual implementation of WaitCondition
-
-WaitCondition::WaitCondition()
-{
- pImpl = new WaitConditionImpl;
-}
-WaitCondition::~WaitCondition()
-{
- delete pImpl;
-}
-
-// Wait without a mutex
-bool WaitCondition::Wait(Mutex *pmutex, unsigned delay)
-{
- return pImpl->Wait(pmutex, delay);
-}
-// Notification
-void WaitCondition::Notify()
-{
- pImpl->Notify();
-}
-void WaitCondition::NotifyAll()
-{
- pImpl->NotifyAll();
-}
-
-
-
-//-----------------------------------------------------------------------------------
-// ***** Thread Class
-
-// Per-thread variable
-// MA: Don't use TLS for now - portability issues with DLLs, etc.
-/*
-#if !defined(OVR_CC_MSVC) || (OVR_CC_MSVC < 1300)
-__declspec(thread) Thread* pCurrentThread = 0;
-#else
-#pragma data_seg(".tls$")
-__declspec(thread) Thread* pCurrentThread = 0;
-#pragma data_seg(".rwdata")
-#endif
-*/
-
-// *** Thread constructors.
-
-Thread::Thread(size_t stackSize, int processor)
-{
- CreateParams params;
- params.stackSize = stackSize;
- params.processor = processor;
- Init(params);
-}
-
-Thread::Thread(Thread::ThreadFn threadFunction, void* userHandle, size_t stackSize,
- int processor, Thread::ThreadState initialState)
-{
- CreateParams params(threadFunction, userHandle, stackSize, processor, initialState);
- Init(params);
-}
-
-Thread::Thread(const CreateParams& params)
-{
- Init(params);
-}
-void Thread::Init(const CreateParams& params)
-{
- // Clear the variables
- ThreadFlags = 0;
- ThreadHandle = 0;
- IdValue = 0;
- ExitCode = 0;
- SuspendCount = 0;
- StackSize = params.stackSize;
- Processor = params.processor;
- Priority = params.priority;
-
- // Clear Function pointers
- ThreadFunction = params.threadFunction;
- UserHandle = params.userHandle;
- if (params.initialState != NotRunning)
- Start(params.initialState);
-
-}
-
-Thread::~Thread()
-{
- // Thread should not running while object is being destroyed,
- // this would indicate ref-counting issue.
- //OVR_ASSERT(IsRunning() == 0);
-
- // Clean up thread.
- CleanupSystemThread();
- ThreadHandle = 0;
-}
-
-
-// *** Overridable User functions.
-
-// Default Run implementation
-int Thread::Run()
-{
- if (!ThreadFunction)
- return 0;
-
- int ret = ThreadFunction(this, UserHandle);
-
- return ret;
-}
-
-void Thread::OnExit()
-{
-}
-
-// Finishes the thread and releases internal reference to it.
-void Thread::FinishAndRelease()
-{
- // Note: thread must be US.
- ThreadFlags &= (uint32_t)~(OVR_THREAD_STARTED);
- ThreadFlags |= OVR_THREAD_FINISHED;
-
- // Release our reference; this is equivalent to 'delete this'
- // from the point of view of our thread.
- Release();
-}
-
-
-// *** ThreadList - used to tack all created threads
-
-class ThreadList : public NewOverrideBase
-{
- //------------------------------------------------------------------------
- struct ThreadHashOp
- {
- size_t operator()(const Thread* ptr)
- {
- return (((size_t)ptr) >> 6) ^ (size_t)ptr;
- }
- };
-
- HashSet<Thread*, ThreadHashOp> ThreadSet;
- Mutex ThreadMutex;
- WaitCondition ThreadsEmpty;
- // Track the root thread that created us.
- ThreadId RootThreadId;
-
- static ThreadList* volatile pRunningThreads;
-
- void addThread(Thread *pthread)
- {
- Mutex::Locker lock(&ThreadMutex);
- ThreadSet.Add(pthread);
- }
-
- void removeThread(Thread *pthread)
- {
- Mutex::Locker lock(&ThreadMutex);
- ThreadSet.Remove(pthread);
- if (ThreadSet.GetSize() == 0)
- ThreadsEmpty.Notify();
- }
-
- void finishAllThreads()
- {
- // Only original root thread can call this.
- OVR_ASSERT(GetCurrentThreadId() == RootThreadId);
-
- Mutex::Locker lock(&ThreadMutex);
- while (ThreadSet.GetSize() != 0)
- ThreadsEmpty.Wait(&ThreadMutex);
- }
-
-public:
-
- ThreadList()
- {
- RootThreadId = GetCurrentThreadId();
- }
- ~ThreadList() { }
-
-
- static void AddRunningThread(Thread *pthread)
- {
- // Non-atomic creation ok since only the root thread
- if (!pRunningThreads)
- {
- pRunningThreads = new ThreadList;
- OVR_ASSERT(pRunningThreads);
- }
- pRunningThreads->addThread(pthread);
- }
-
- // NOTE: 'pthread' might be a dead pointer when this is
- // called so it should not be accessed; it is only used
- // for removal.
- static void RemoveRunningThread(Thread *pthread)
- {
- OVR_ASSERT(pRunningThreads);
- pRunningThreads->removeThread(pthread);
- }
-
- static void FinishAllThreads()
- {
- // This is ok because only root thread can wait for other thread finish.
- if (pRunningThreads)
- {
- pRunningThreads->finishAllThreads();
- delete pRunningThreads;
- pRunningThreads = 0;
- }
- }
-};
-
-// By default, we have no thread list.
-ThreadList* volatile ThreadList::pRunningThreads = 0;
-
-
-// FinishAllThreads - exposed publicly in Thread.
-void Thread::FinishAllThreads()
-{
- ThreadList::FinishAllThreads();
-}
-
-
-// *** Run override
-
-int Thread::PRun()
-{
- // Suspend us on start, if requested
- if (ThreadFlags & OVR_THREAD_START_SUSPENDED)
- {
- Suspend();
- ThreadFlags &= (uint32_t)~OVR_THREAD_START_SUSPENDED;
- }
-
- // Call the virtual run function
- ExitCode = Run();
-
- return ExitCode;
-}
-
-
-
-/* MA: Don't use TLS for now.
-
-// Static function to return a pointer to the current thread
-void Thread::InitCurrentThread(Thread *pthread)
-{
- pCurrentThread = pthread;
-}
-
-// Static function to return a pointer to the current thread
-Thread* Thread::GetThread()
-{
- return pCurrentThread;
-}
-*/
-
-
-// *** User overridables
-
-bool Thread::GetExitFlag() const
-{
- return (ThreadFlags & OVR_THREAD_EXIT) != 0;
-}
-
-void Thread::SetExitFlag(bool exitFlag)
-{
- // The below is atomic since ThreadFlags is AtomicInt.
- if (exitFlag)
- ThreadFlags |= OVR_THREAD_EXIT;
- else
- ThreadFlags &= (uint32_t) ~OVR_THREAD_EXIT;
-}
-
-
-// Determines whether the thread was running and is now finished
-bool Thread::IsFinished() const
-{
- return (ThreadFlags & OVR_THREAD_FINISHED) != 0;
-}
-// Determines whether the thread is suspended
-bool Thread::IsSuspended() const
-{
- return SuspendCount > 0;
-}
-// Returns current thread state
-Thread::ThreadState Thread::GetThreadState() const
-{
- if (IsSuspended())
- return Suspended;
- if (ThreadFlags & OVR_THREAD_STARTED)
- return Running;
- return NotRunning;
-}
-// Join thread
-bool Thread::Join(int maxWaitMs) const
-{
- // If polling,
- if (maxWaitMs == 0)
- {
- // Just return if finished
- return IsFinished();
- }
- // If waiting forever,
- else if (maxWaitMs > 0)
- {
- // Try waiting once
- WaitForSingleObject(ThreadHandle, maxWaitMs);
-
- // Return if the wait succeeded
- return IsFinished();
- }
-
- // While not finished,
- while (!IsFinished())
- {
- // Wait for the thread handle to signal
- WaitForSingleObject(ThreadHandle, INFINITE);
- }
-
- return true;
-}
-
-
-// ***** Thread management
-/* static */
-int Thread::GetOSPriority(ThreadPriority p)
-{
- switch(p)
- {
- // If the process is REALTIME_PRIORITY_CLASS then it could have priority values 3 through14 and -3 through -14.
- case Thread::CriticalPriority: return THREAD_PRIORITY_TIME_CRITICAL; // 15
- case Thread::HighestPriority: return THREAD_PRIORITY_HIGHEST; // 2
- case Thread::AboveNormalPriority: return THREAD_PRIORITY_ABOVE_NORMAL; // 1
- case Thread::NormalPriority: return THREAD_PRIORITY_NORMAL; // 0
- case Thread::BelowNormalPriority: return THREAD_PRIORITY_BELOW_NORMAL; // -1
- case Thread::LowestPriority: return THREAD_PRIORITY_LOWEST; // -2
- case Thread::IdlePriority: return THREAD_PRIORITY_IDLE; // -15
- }
- return THREAD_PRIORITY_NORMAL;
-}
-
-/* static */
-Thread::ThreadPriority Thread::GetOVRPriority(int osPriority)
-{
- // If the process is REALTIME_PRIORITY_CLASS then it could have priority values 3 through14 and -3 through -14.
- // As a result, it's possible for those cases that an unknown/invalid ThreadPriority enum be returned. However,
- // in practice we don't expect to be using such processes.
-
- // The ThreadPriority types aren't linearly distributed, so we need to check for some values explicitly.
- if(osPriority == THREAD_PRIORITY_TIME_CRITICAL)
- return Thread::CriticalPriority;
- if(osPriority == THREAD_PRIORITY_IDLE)
- return Thread::IdlePriority;
- return (ThreadPriority)(Thread::NormalPriority - osPriority);
-}
-
-Thread::ThreadPriority Thread::GetPriority()
-{
- int osPriority = ::GetThreadPriority(ThreadHandle);
-
- if(osPriority != THREAD_PRIORITY_ERROR_RETURN)
- {
- return GetOVRPriority(osPriority);
- }
-
- return NormalPriority;
-}
-
-/* static */
-Thread::ThreadPriority Thread::GetCurrentPriority()
-{
- int osPriority = ::GetThreadPriority(::GetCurrentThread());
-
- if(osPriority != THREAD_PRIORITY_ERROR_RETURN)
- {
- return GetOVRPriority(osPriority);
- }
-
- return NormalPriority;
-}
-
-bool Thread::SetPriority(ThreadPriority p)
-{
- BOOL ret = ::SetThreadPriority(ThreadHandle, Thread::GetOSPriority(p));
- return (ret != FALSE);
-}
-
-/* static */
-bool Thread::SetCurrentPriority(ThreadPriority p)
-{
- BOOL ret = ::SetThreadPriority(::GetCurrentThread(), Thread::GetOSPriority(p));
- return (ret != FALSE);
-}
-
-
-
-// The actual first function called on thread start
-#if defined(OVR_OS_WIN32)
-unsigned WINAPI Thread_Win32StartFn(void * phandle)
-#else // Other Micorosft OSs...
-DWORD WINAPI Thread_Win32StartFn(void *phandle)
-#endif
-{
- Thread * pthread = (Thread*)phandle;
- if (pthread->Processor != -1)
- {
- DWORD_PTR ret = SetThreadAffinityMask(GetCurrentThread(), (DWORD)pthread->Processor);
- if (ret == 0)
- OVR_DEBUG_LOG(("Could not set hardware processor for the thread"));
- }
- BOOL ret = ::SetThreadPriority(GetCurrentThread(), Thread::GetOSPriority(pthread->Priority));
- if (ret == 0)
- OVR_DEBUG_LOG(("Could not set thread priority"));
- OVR_UNUSED(ret);
-
- // Ensure that ThreadId is assigned once thread is running, in case
- // beginthread hasn't filled it in yet.
- pthread->IdValue = (ThreadId)::GetCurrentThreadId();
-
- DWORD result = pthread->PRun();
- // Signal the thread as done and release it atomically.
- pthread->FinishAndRelease();
- // At this point Thread object might be dead; however we can still pass
- // it to RemoveRunningThread since it is only used as a key there.
- ThreadList::RemoveRunningThread(pthread);
- return (unsigned) result;
-}
-
-bool Thread::Start(ThreadState initialState)
-{
- if (initialState == NotRunning)
- return 0;
- if (GetThreadState() != NotRunning)
- {
- OVR_DEBUG_LOG(("Thread::Start failed - thread %p already running", this));
- return 0;
- }
-
- // Free old thread handle before creating the new one
- CleanupSystemThread();
-
- // AddRef to us until the thread is finished.
- AddRef();
- ThreadList::AddRunningThread(this);
-
- ExitCode = 0;
- SuspendCount = 0;
- ThreadFlags = (initialState == Running) ? 0 : OVR_THREAD_START_SUSPENDED;
-#if defined(OVR_OS_WIN32)
- ThreadHandle = (HANDLE) _beginthreadex(0, (unsigned)StackSize,
- Thread_Win32StartFn, this, 0, (unsigned*)&IdValue);
-#else // Other Micorosft OSs...
- DWORD TheThreadId;
- ThreadHandle = CreateThread(0, (unsigned)StackSize,
- Thread_Win32StartFn, this, 0, &TheThreadId);
- IdValue = (ThreadId)TheThreadId;
-#endif
-
- // Failed? Fail the function
- if (ThreadHandle == 0)
- {
- ThreadFlags = 0;
- Release();
- ThreadList::RemoveRunningThread(this);
- return 0;
- }
- return 1;
-}
-
-
-// Suspend the thread until resumed
-bool Thread::Suspend()
-{
- // Can't suspend a thread that wasn't started
- if (!(ThreadFlags & OVR_THREAD_STARTED))
- return 0;
-
- if (::SuspendThread(ThreadHandle) != 0xFFFFFFFF)
- {
- SuspendCount++;
- return 1;
- }
- return 0;
-}
-
-// Resumes currently suspended thread
-bool Thread::Resume()
-{
- // Can't suspend a thread that wasn't started
- if (!(ThreadFlags & OVR_THREAD_STARTED))
- return 0;
-
- // Decrement count, and resume thread if it is 0
- int32_t oldCount = SuspendCount.ExchangeAdd_Acquire(-1);
- if (oldCount >= 1)
- {
- if (oldCount == 1)
- {
- if (::ResumeThread(ThreadHandle) != 0xFFFFFFFF)
- {
- return 1;
- }
- }
- else
- {
- return 1;
- }
- }
- return 0;
-}
-
-
-// Quits with an exit code
-void Thread::Exit(int exitCode)
-{
- // Can only exist the current thread.
- // MA: Don't use TLS for now.
- //if (GetThread() != this)
- // return;
-
- // Call the virtual OnExit function.
- OnExit();
-
- // Signal this thread object as done and release it's references.
- FinishAndRelease();
- ThreadList::RemoveRunningThread(this);
-
- // Call the exit function.
-#if defined(OVR_OS_WIN32) // _endthreadex doesn't exist on other Microsoft OSs and instead we need to call ExitThread directly.
- _endthreadex((unsigned)exitCode);
-#else
- ExitThread((unsigned)exitCode);
-#endif
-}
-
-
-void Thread::CleanupSystemThread()
-{
- if (ThreadHandle != 0)
- {
- ::CloseHandle(ThreadHandle);
- ThreadHandle = 0;
- }
-}
-
-// *** Sleep functions
-// static
-bool Thread::Sleep(unsigned secs)
-{
- ::Sleep(secs*1000);
- return 1;
-}
-
-// static
-bool Thread::MSleep(unsigned msecs)
-{
- ::Sleep(msecs);
- return 1;
-}
-
-
-
-void Thread::SetThreadName( const char* name )
-{
- if(IdValue)
- SetThreadName(name, IdValue);
- // Else we don't know what thread to name. We can save the name and wait until the thread is created.
-}
-
-
-void Thread::SetThreadName(const char* name, ThreadId threadId)
-{
- #if !defined(OVR_BUILD_SHIPPING) || defined(OVR_BUILD_PROFILING)
- // http://msdn.microsoft.com/en-us/library/xcb2z8hs.aspx
- #pragma pack(push,8)
- struct THREADNAME_INFO {
- DWORD dwType; // Must be 0x1000
- LPCSTR szName; // Pointer to name (in user address space)
- DWORD dwThreadID; // Thread ID (-1 for caller thread)
- DWORD dwFlags; // Reserved for future use; must be zero
- };
- #pragma pack(pop)
-
- THREADNAME_INFO info = { 0x1000, name, (DWORD)threadId, 0 };
-
- __try
- {
- RaiseException( 0x406D1388, 0, sizeof(info)/sizeof(ULONG_PTR), reinterpret_cast<ULONG_PTR*>(&info));
- }
- __except( GetExceptionCode()==0x406D1388 ? EXCEPTION_CONTINUE_EXECUTION : EXCEPTION_EXECUTE_HANDLER )
- {
- return;
- }
- #endif // OVR_BUILD_SHIPPING
-}
-
-
-void Thread::SetCurrentThreadName( const char* name )
-{
- SetThreadName(name, (ThreadId)::GetCurrentThreadId());
-}
-
-
-void Thread::GetThreadName(char* name, size_t /*nameCapacity*/, ThreadId /*threadId*/)
-{
- // Not possible on Windows.
- name[0] = 0;
-}
-
-
-void Thread::GetCurrentThreadName(char* name, size_t /*nameCapacity*/)
-{
- // Not possible on Windows.
- name[0] = 0;
-}
-
-
-// static
-int Thread::GetCPUCount()
-{
- SYSTEM_INFO sysInfo;
-
- #if defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0501) // GetNativeSystemInfo requires WinXP+ and a corresponding SDK (0x0501) or later.
- GetNativeSystemInfo(&sysInfo);
- #else
- GetSystemInfo(&sysInfo);
- #endif
-
- return (int) sysInfo.dwNumberOfProcessors;
-}
-
-// Returns the unique Id of a thread it is called on, intended for
-// comparison purposes.
-ThreadId GetCurrentThreadId()
-{
- return (ThreadId)::GetCurrentThreadId();
-}
-
-} // OVR
-
-#endif
diff --git a/LibOVR/Src/Kernel/OVR_Timer.cpp b/LibOVR/Src/Kernel/OVR_Timer.cpp deleted file mode 100644 index 3a75ec2..0000000 --- a/LibOVR/Src/Kernel/OVR_Timer.cpp +++ /dev/null @@ -1,551 +0,0 @@ -/************************************************************************************ - -Filename : OVR_Timer.cpp -Content : Provides static functions for precise timing -Created : September 19, 2012 -Notes : - -Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); -you may not use the Oculus VR Rift SDK except in compliance with the License, -which is provided at the time of installation or download, or which -otherwise accompanies this software in either electronic or hard copy form. - -You may obtain a copy of the License at - -http://www.oculusvr.com/licenses/LICENSE-3.2 - -Unless required by applicable law or agreed to in writing, the Oculus VR SDK -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -************************************************************************************/ - -#include "OVR_Timer.h" -#include "OVR_Log.h" - -#if defined(OVR_OS_MS) && !defined(OVR_OS_MS_MOBILE) -#define WIN32_LEAN_AND_MEAN -#include <windows.h> -#include <MMSystem.h> -#elif defined(OVR_OS_ANDROID) -#include <time.h> -#include <android/log.h> -#elif defined(OVR_OS_MAC) -#include <mach/mach_time.h> -#else -#include <time.h> -#include <sys/time.h> -#include <errno.h> -#endif - - -#if defined(OVR_BUILD_DEBUG) && defined(OVR_OS_WIN32) - #ifndef NTSTATUS - #define NTSTATUS DWORD - #endif - - typedef NTSTATUS (NTAPI* NtQueryTimerResolutionType)(PULONG MaximumTime, PULONG MinimumTime, PULONG CurrentTime); - NtQueryTimerResolutionType pNtQueryTimerResolution; -#endif - - - -#if defined(OVR_OS_MS) && !defined(OVR_OS_WIN32) // Non-desktop Microsoft platforms... - -// Add this alias here because we're not going to include OVR_CAPI.cpp -extern "C" { - double ovr_GetTimeInSeconds() - { - return Timer::GetSeconds(); - } -} - -#endif - - - - -namespace OVR { - -// For recorded data playback -bool Timer::useFakeSeconds = false; -double Timer::FakeSeconds = 0; - - - - -//------------------------------------------------------------------------ -// *** Android Specific Timer - -#if defined(OVR_OS_ANDROID) // To consider: This implementation can also work on most Linux distributions - -//------------------------------------------------------------------------ -// *** Timer - Platform Independent functions - -// Returns global high-resolution application timer in seconds. -double Timer::GetSeconds() -{ - if(useFakeSeconds) - return FakeSeconds; - - // Choreographer vsync timestamp is based on. - struct timespec tp; - const int status = clock_gettime(CLOCK_MONOTONIC, &tp); - -#ifdef OVR_BUILD_DEBUG - if (status != 0) - { - OVR_DEBUG_LOG(("clock_gettime status=%i", status )); - } -#else - OVR_UNUSED(status); -#endif - - return (double)tp.tv_sec; -} - - - -uint64_t Timer::GetTicksNanos() -{ - if (useFakeSeconds) - return (uint64_t) (FakeSeconds * NanosPerSecond); - - // Choreographer vsync timestamp is based on. - struct timespec tp; - const int status = clock_gettime(CLOCK_MONOTONIC, &tp); - -#ifdef OVR_BUILD_DEBUG - if (status != 0) - { - OVR_DEBUG_LOG(("clock_gettime status=%i", status )); - } -#else - OVR_UNUSED(status); -#endif - - const uint64_t result = (uint64_t)tp.tv_sec * (uint64_t)(1000 * 1000 * 1000) + uint64_t(tp.tv_nsec); - return result; -} - - -void Timer::initializeTimerSystem() -{ - // Empty for this platform. -} - -void Timer::shutdownTimerSystem() -{ - // Empty for this platform. -} - - - - - -//------------------------------------------------------------------------ -// *** Win32 Specific Timer - -#elif defined (OVR_OS_MS) - - -// This helper class implements high-resolution wrapper that combines timeGetTime() output -// with QueryPerformanceCounter. timeGetTime() is lower precision but drives the high bits, -// as it's tied to the system clock. -struct PerformanceTimer -{ - PerformanceTimer() - : UsingVistaOrLater(false), - TimeCS(), - OldMMTimeMs(0), - MMTimeWrapCounter(0), - PerfFrequency(0), - PerfFrequencyInverse(0), - PerfFrequencyInverseNanos(0), - PerfMinusTicksDeltaNanos(0), - LastResultNanos(0) - { } - - enum { - MMTimerResolutionNanos = 1000000 - }; - - void Initialize(); - void Shutdown(); - - uint64_t GetTimeSeconds(); - double GetTimeSecondsDouble(); - uint64_t GetTimeNanos(); - - UINT64 getFrequency() - { - if (PerfFrequency == 0) - { - LARGE_INTEGER freq; - QueryPerformanceFrequency(&freq); - PerfFrequency = freq.QuadPart; - PerfFrequencyInverse = 1.0 / (double)PerfFrequency; - PerfFrequencyInverseNanos = 1000000000.0 / (double)PerfFrequency; - } - return PerfFrequency; - } - - double GetFrequencyInverse() - { - OVR_ASSERT(PerfFrequencyInverse != 0.0); // Assert that the frequency has been initialized. - return PerfFrequencyInverse; - } - - bool UsingVistaOrLater; - - CRITICAL_SECTION TimeCS; - // timeGetTime() support with wrap. - uint32_t OldMMTimeMs; - uint32_t MMTimeWrapCounter; - // Cached performance frequency result. - uint64_t PerfFrequency; // cycles per second, typically a large value like 3000000, but usually not the same as the CPU clock rate. - double PerfFrequencyInverse; // seconds per cycle (will be a small fractional value). - double PerfFrequencyInverseNanos; // nanoseconds per cycle. - - // Computed as (perfCounterNanos - ticksCounterNanos) initially, - // and used to adjust timing. - uint64_t PerfMinusTicksDeltaNanos; - // Last returned value in nanoseconds, to ensure we don't back-step in time. - uint64_t LastResultNanos; -}; - -static PerformanceTimer Win32_PerfTimer; - - -void PerformanceTimer::Initialize() -{ - #if defined(OVR_OS_WIN32) // Desktop Windows only - // The following has the effect of setting the NT timer resolution (NtSetTimerResolution) to 1 millisecond. - MMRESULT mmr = timeBeginPeriod(1); - OVR_ASSERT(TIMERR_NOERROR == mmr); - OVR_UNUSED(mmr); - #endif - - InitializeCriticalSection(&TimeCS); - MMTimeWrapCounter = 0; - getFrequency(); - - #if defined(OVR_OS_WIN32) // Desktop Windows only - // Set Vista flag. On Vista, we can just use QPC() without all the extra work - OSVERSIONINFOEX ver; - ZeroMemory(&ver, sizeof(OSVERSIONINFOEX)); - ver.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX); - ver.dwMajorVersion = 6; // Vista+ - - DWORDLONG condMask = 0; - VER_SET_CONDITION(condMask, VER_MAJORVERSION, VER_GREATER_EQUAL); - - // VerifyVersionInfo returns true if the OS meets the conditions set above - UsingVistaOrLater = VerifyVersionInfo(&ver, VER_MAJORVERSION, condMask) != 0; - #else - UsingVistaOrLater = true; - #endif - - OVR_DEBUG_LOG(("PerformanceTimer UsingVistaOrLater = %d", (int)UsingVistaOrLater)); - - #if defined(OVR_BUILD_DEBUG) && defined(OVR_OS_WIN32) - HMODULE hNtDll = LoadLibrary(L"NtDll.dll"); - if (hNtDll) - { - pNtQueryTimerResolution = (NtQueryTimerResolutionType)GetProcAddress(hNtDll, "NtQueryTimerResolution"); - //pNtSetTimerResolution = (NtSetTimerResolutionType)GetProcAddress(hNtDll, "NtSetTimerResolution"); - - if(pNtQueryTimerResolution) - { - ULONG MinimumResolution; // in 100-ns units - ULONG MaximumResolution; - ULONG ActualResolution; - pNtQueryTimerResolution(&MinimumResolution, &MaximumResolution, &ActualResolution); - OVR_DEBUG_LOG(("NtQueryTimerResolution = Min %ld us, Max %ld us, Current %ld us", MinimumResolution / 10, MaximumResolution / 10, ActualResolution / 10)); - } - - FreeLibrary(hNtDll); - } - #endif -} - -void PerformanceTimer::Shutdown() -{ - DeleteCriticalSection(&TimeCS); - - #if defined(OVR_OS_WIN32) // Desktop Windows only - MMRESULT mmr = timeEndPeriod(1); - OVR_ASSERT(TIMERR_NOERROR == mmr); - OVR_UNUSED(mmr); - #endif -} - - -uint64_t PerformanceTimer::GetTimeSeconds() -{ - if (UsingVistaOrLater) - { - LARGE_INTEGER li; - QueryPerformanceCounter(&li); - OVR_ASSERT(PerfFrequencyInverse != 0); // Initialize should have been called earlier. - return (uint64_t)(li.QuadPart * PerfFrequencyInverse); - } - - return (uint64_t)(GetTimeNanos() * .0000000001); -} - - -double PerformanceTimer::GetTimeSecondsDouble() -{ - if (UsingVistaOrLater) - { - LARGE_INTEGER li; - QueryPerformanceCounter(&li); - OVR_ASSERT(PerfFrequencyInverse != 0); - return (li.QuadPart * PerfFrequencyInverse); - } - - return (GetTimeNanos() * .0000000001); -} - - -uint64_t PerformanceTimer::GetTimeNanos() -{ - uint64_t resultNanos; - LARGE_INTEGER li; - - OVR_ASSERT(PerfFrequencyInverseNanos != 0); // Initialize should have been called earlier. - - if (UsingVistaOrLater) // Includes non-desktop platforms - { - // Then we can use QPC() directly without all that extra work - QueryPerformanceCounter(&li); - resultNanos = (uint64_t)(li.QuadPart * PerfFrequencyInverseNanos); - } - else - { - // On Win32 QueryPerformanceFrequency is unreliable due to SMP and - // performance levels, so use this logic to detect wrapping and track - // high bits. - ::EnterCriticalSection(&TimeCS); - - // Get raw value and perf counter "At the same time". - QueryPerformanceCounter(&li); - - DWORD mmTimeMs = timeGetTime(); - if (OldMMTimeMs > mmTimeMs) - MMTimeWrapCounter++; - OldMMTimeMs = mmTimeMs; - - // Normalize to nanoseconds. - uint64_t perfCounterNanos = (uint64_t)(li.QuadPart * PerfFrequencyInverseNanos); - uint64_t mmCounterNanos = ((uint64_t(MMTimeWrapCounter) << 32) | mmTimeMs) * 1000000; - if (PerfMinusTicksDeltaNanos == 0) - PerfMinusTicksDeltaNanos = perfCounterNanos - mmCounterNanos; - - // Compute result before snapping. - // - // On first call, this evaluates to: - // resultNanos = mmCounterNanos. - // Next call, assuming no wrap: - // resultNanos = prev_mmCounterNanos + (perfCounterNanos - prev_perfCounterNanos). - // After wrap, this would be: - // resultNanos = snapped(prev_mmCounterNanos +/- 1ms) + (perfCounterNanos - prev_perfCounterNanos). - // - resultNanos = perfCounterNanos - PerfMinusTicksDeltaNanos; - - // Snap the range so that resultNanos never moves further apart then its target resolution. - // It's better to allow more slack on the high side as timeGetTime() may be updated at sporadically - // larger then 1 ms intervals even when 1 ms resolution is requested. - if (resultNanos > (mmCounterNanos + MMTimerResolutionNanos*2)) - { - resultNanos = mmCounterNanos + MMTimerResolutionNanos*2; - if (resultNanos < LastResultNanos) - resultNanos = LastResultNanos; - PerfMinusTicksDeltaNanos = perfCounterNanos - resultNanos; - } - else if (resultNanos < (mmCounterNanos - MMTimerResolutionNanos)) - { - resultNanos = mmCounterNanos - MMTimerResolutionNanos; - if (resultNanos < LastResultNanos) - resultNanos = LastResultNanos; - PerfMinusTicksDeltaNanos = perfCounterNanos - resultNanos; - } - - LastResultNanos = resultNanos; - ::LeaveCriticalSection(&TimeCS); - } - - //Tom's addition, to keep precision - //static uint64_t initial_time = 0; - //if (!initial_time) initial_time = resultNanos; - //resultNanos -= initial_time; - // FIXME: This cannot be used for cross-process timestamps - - return resultNanos; -} - - -//------------------------------------------------------------------------ -// *** Timer - Platform Independent functions - -// Returns global high-resolution application timer in seconds. -double Timer::GetSeconds() -{ - if(useFakeSeconds) - return FakeSeconds; - - return Win32_PerfTimer.GetTimeSecondsDouble(); -} - - - -// Delegate to PerformanceTimer. -uint64_t Timer::GetTicksNanos() -{ - if (useFakeSeconds) - return (uint64_t) (FakeSeconds * NanosPerSecond); - - return Win32_PerfTimer.GetTimeNanos(); -} -void Timer::initializeTimerSystem() -{ - Win32_PerfTimer.Initialize(); -} -void Timer::shutdownTimerSystem() -{ - Win32_PerfTimer.Shutdown(); -} - - - -#elif defined(OVR_OS_MAC) - - -double Timer::TimeConvertFactorNanos = 0.0; -double Timer::TimeConvertFactorSeconds = 0.0; - - -//------------------------------------------------------------------------ -// *** Standard OS Timer - -// Returns global high-resolution application timer in seconds. -double Timer::GetSeconds() -{ - if(useFakeSeconds) - return FakeSeconds; - - OVR_ASSERT(TimeConvertFactorNanos != 0.0); - return (double)mach_absolute_time() * TimeConvertFactorNanos; -} - - -uint64_t Timer::GetTicksNanos() -{ - if (useFakeSeconds) - return (uint64_t) (FakeSeconds * NanosPerSecond); - - OVR_ASSERT(TimeConvertFactorSeconds != 0.0); - return (uint64_t)(mach_absolute_time() * TimeConvertFactorSeconds); -} - -void Timer::initializeTimerSystem() -{ - mach_timebase_info_data_t timeBase; - mach_timebase_info(&timeBase); - TimeConvertFactorSeconds = ((double)timeBase.numer / (double)timeBase.denom); - TimeConvertFactorNanos = TimeConvertFactorSeconds / 1000000000.0; -} - -void Timer::shutdownTimerSystem() -{ - // Empty for this platform. -} - - -#else // Posix platforms (e.g. Linux, BSD Unix) - - -bool Timer::MonotonicClockAvailable = false; - - -// Returns global high-resolution application timer in seconds. -double Timer::GetSeconds() -{ - if(useFakeSeconds) - return FakeSeconds; - - // http://linux/die/netman3/clock_gettime - #if defined(CLOCK_MONOTONIC) // If we can use clock_gettime, which has nanosecond precision... - if(MonotonicClockAvailable) - { - timespec ts; - clock_gettime(CLOCK_MONOTONIC, &ts); // Better to use CLOCK_MONOTONIC than CLOCK_REALTIME. - return static_cast<double>(ts.tv_sec) + static_cast<double>(ts.tv_nsec) / 1E9; - } - #endif - - // We cannot use rdtsc because its frequency changes at runtime. - struct timeval tv; - gettimeofday(&tv, 0); - - return static_cast<double>(tv.tv_sec) + static_cast<double>(tv.tv_usec) / 1E6; -} - - -uint64_t Timer::GetTicksNanos() -{ - if (useFakeSeconds) - return (uint64_t) (FakeSeconds * NanosPerSecond); - - #if defined(CLOCK_MONOTONIC) // If we can use clock_gettime, which has nanosecond precision... - if(MonotonicClockAvailable) - { - timespec ts; - clock_gettime(CLOCK_MONOTONIC, &ts); - return ((uint64_t)ts.tv_sec * 1000000000ULL) + (uint64_t)ts.tv_nsec; - } - #endif - - - // We cannot use rdtsc because its frequency changes at runtime. - uint64_t result; - - // Return microseconds. - struct timeval tv; - - gettimeofday(&tv, 0); - - result = (uint64_t)tv.tv_sec * 1000000; - result += tv.tv_usec; - - return result * 1000; -} - - -void Timer::initializeTimerSystem() -{ - #if defined(CLOCK_MONOTONIC) - timespec ts; // We could also check for the availability of CLOCK_MONOTONIC with sysconf(_SC_MONOTONIC_CLOCK) - int result = clock_gettime(CLOCK_MONOTONIC, &ts); - MonotonicClockAvailable = (result == 0); - #endif -} - -void Timer::shutdownTimerSystem() -{ - // Empty for this platform. -} - - - -#endif // OS-specific - - - -} // OVR - diff --git a/LibOVR/Src/Kernel/OVR_Timer.h b/LibOVR/Src/Kernel/OVR_Timer.h deleted file mode 100644 index 6c8dbb7..0000000 --- a/LibOVR/Src/Kernel/OVR_Timer.h +++ /dev/null @@ -1,99 +0,0 @@ -/************************************************************************************ - -PublicHeader: OVR -Filename : OVR_Timer.h -Content : Provides static functions for precise timing -Created : September 19, 2012 -Notes : - -Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); -you may not use the Oculus VR Rift SDK except in compliance with the License, -which is provided at the time of installation or download, or which -otherwise accompanies this software in either electronic or hard copy form. - -You may obtain a copy of the License at - -http://www.oculusvr.com/licenses/LICENSE-3.2 - -Unless required by applicable law or agreed to in writing, the Oculus VR SDK -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -************************************************************************************/ - -#ifndef OVR_Timer_h -#define OVR_Timer_h - -#include "OVR_Types.h" - -namespace OVR { - -//----------------------------------------------------------------------------------- -// ***** Timer - -// Timer class defines a family of static functions used for application -// timing and profiling. - -class Timer -{ -public: - enum { - MsPerSecond = 1000, // Milliseconds in one second. - MksPerSecond = 1000 * 1000, // Microseconds in one second. - NanosPerSecond = 1000 * 1000 * 1000, // Nanoseconds in one second. - }; - - // ***** Timing APIs for Application - - // These APIs should be used to guide animation and other program functions - // that require precision. - - // Returns global high-resolution application timer in seconds. - static double OVR_STDCALL GetSeconds(); - - // Returns time in Nanoseconds, using highest possible system resolution. - static uint64_t OVR_STDCALL GetTicksNanos(); - - // Kept for compatibility. - // Returns ticks in milliseconds, as a 32-bit number. May wrap around every 49.2 days. - // Use either time difference of two values of GetTicks to avoid wrap-around. - static uint32_t OVR_STDCALL GetTicksMs() - { return uint32_t(GetTicksNanos() / 1000000); } - - // for recorded data playback - static void SetFakeSeconds(double fakeSeconds, bool enable = true) - { - FakeSeconds = fakeSeconds; - useFakeSeconds = enable; - } - -private: - friend class System; - // System called during program startup/shutdown. - static void initializeTimerSystem(); - static void shutdownTimerSystem(); - - // for recorded data playback - static double FakeSeconds; - static bool useFakeSeconds; - - #if defined(OVR_OS_ANDROID) - // Android-specific data - #elif defined (OVR_OS_MS) - // Microsoft-specific data - #elif defined(OVR_OS_MAC) - static double TimeConvertFactorNanos; // Conversion factor for GetTicksNanos - static double TimeConvertFactorSeconds; // Conversion factor for GetSeconds. - #else - static bool MonotonicClockAvailable; // True if clock_gettime supports CLOCK_MONOTONIC - #endif -}; - - -} // OVR::Timer - -#endif diff --git a/LibOVR/Src/Kernel/OVR_Types.h b/LibOVR/Src/Kernel/OVR_Types.h deleted file mode 100644 index d42d131..0000000 --- a/LibOVR/Src/Kernel/OVR_Types.h +++ /dev/null @@ -1,909 +0,0 @@ -/************************************************************************************ - -PublicHeader: OVR_Kernel.h -Filename : OVR_Types.h -Content : Standard library defines and simple types -Created : September 19, 2012 -Notes : - -Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); -you may not use the Oculus VR Rift SDK except in compliance with the License, -which is provided at the time of installation or download, or which -otherwise accompanies this software in either electronic or hard copy form. - -You may obtain a copy of the License at - -http://www.oculusvr.com/licenses/LICENSE-3.2 - -Unless required by applicable law or agreed to in writing, the Oculus VR SDK -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -************************************************************************************/ - -#ifndef OVR_Types_H -#define OVR_Types_H - -#include "OVR_Compiler.h" - - -// Unsupported compiler configurations -#if _MSC_VER == 0x1600 -# if _MSC_FULL_VER < 160040219 -# error "Oculus does not support VS2010 without SP1 installed: It will crash in Release mode" -# endif -#endif - - -//----------------------------------------------------------------------------------- -// ****** Operating system identification -// -// Try to use the most generic version of these defines as possible in order to achieve -// the simplest portable code. For example, instead of using #if (defined(OVR_OS_IPHONE) || defined(OVR_OS_MAC)), -// consider using #if defined(OVR_OS_APPLE). -// -// Type definitions exist for the following operating systems: (OVR_OS_x) -// -// WIN32 - Win32 and Win64 (Windows XP and later) Does not include Microsoft phone and console platforms, despite that Microsoft's _WIN32 may be defined by the compiler for them. -// WIN64 - Win64 (Windows XP and later) -// MAC - Mac OS X (may be defined in addition to BSD) -// LINUX - Linux -// BSD - BSD Unix -// ANDROID - Android (may be defined in addition to LINUX) -// IPHONE - iPhone -// MS_MOBILE - Microsoft mobile OS. -// -// Meta platforms -// MS - Any OS by Microsoft (e.g. Win32, Win64, phone, console) -// APPLE - Any OS by Apple (e.g. iOS, OS X) -// UNIX - Linux, BSD, Mac OS X. -// MOBILE - iOS, Android, Microsoft phone -// CONSOLE - Console platforms -// - -#if (defined(__APPLE__) && (defined(__GNUC__) ||\ - defined(__xlC__) || defined(__xlc__))) || defined(__MACOS__) -# if (defined(__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__) || defined(__IPHONE_OS_VERSION_MIN_REQUIRED)) -# define OVR_OS_IPHONE -# else -# define OVR_OS_DARWIN -# define OVR_OS_MAC -# define OVR_OS_BSD -# endif -#elif (defined(WIN64) || defined(_WIN64) || defined(__WIN64__)) -# define OVR_OS_WIN64 -# define OVR_OS_WIN32 // Defined for compatibility and because the Win64 API supports the Win32 API. -#elif (defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__NT__)) -# define OVR_OS_WIN32 -#elif defined(ANDROID) || defined(__ANDROID__) -# define OVR_OS_ANDROID -# define OVR_OS_LINUX -#elif defined(__linux__) || defined(__linux) -# define OVR_OS_LINUX -#elif defined(_BSD_) || defined(__FreeBSD__) -# define OVR_OS_BSD -#else -# define OVR_OS_OTHER -#endif - -#if !defined(OVR_OS_MS_MOBILE) -# if (defined(_M_ARM) || defined(_M_IX86) || defined(_M_AMD64)) && !defined(OVR_OS_WIN32) && !defined(OVR_OS_CONSOLE) -# define OVR_OS_MS_MOBILE -# endif -#endif - -#if !defined(OVR_OS_MS) -# if defined(OVR_OS_WIN32) || defined(OVR_OS_WIN64) || defined(OVR_OS_MS_MOBILE) -# define OVR_OS_MS -# endif -#endif - -#if !defined(OVR_OS_APPLE) -# if defined(OVR_OS_MAC) || defined(OVR_OS_IPHONE) -# define OVR_OS_APPLE -# endif -#endif - -#if !defined(OVR_OS_UNIX) -# if defined(OVR_OS_ANDROID) || defined(OVR_OS_BSD) || defined(OVR_OS_LINUX) || defined(OVR_OS_MAC) -# define OVR_OS_UNIX -# endif -#endif - -#if !defined(OVR_OS_MOBILE) -# if defined(OVR_OS_ANDROID) || defined(OVR_OS_IPHONE) || defined(OVR_OS_MS_MOBILE) -# define OVR_OS_MOBILE -# endif -#endif - - - - -//----------------------------------------------------------------------------------- -// ***** CPU Architecture -// -// The following CPUs are defined: (OVR_CPU_x) -// -// X86 - x86 (IA-32) -// X86_64 - x86_64 (amd64) -// PPC - PowerPC -// PPC64 - PowerPC64 -// MIPS - MIPS -// OTHER - CPU for which no special support is present or needed - - -#if defined(__x86_64__) || defined(WIN64) || defined(_WIN64) || defined(__WIN64__) || defined(_M_AMD64) -# define OVR_CPU_X86_64 -# define OVR_64BIT_POINTERS -#elif defined(__i386__) || defined(OVR_OS_WIN32) -# define OVR_CPU_X86 -#elif defined(__powerpc64__) -# define OVR_CPU_PPC64 -#elif defined(__ppc__) -# define OVR_CPU_PPC -#elif defined(__mips__) || defined(__MIPSEL__) -# define OVR_CPU_MIPS -#elif defined(__arm__) -# define OVR_CPU_ARM -#else -# define OVR_CPU_OTHER -#endif - -//----------------------------------------------------------------------------------- -// ***** Co-Processor Architecture -// -// The following co-processors are defined: (OVR_CPU_x) -// -// SSE - Available on all modern x86 processors. -// Altivec - Available on all modern ppc processors. -// Neon - Available on some armv7+ processors. - -#if defined(__SSE__) || defined(_M_IX86) || defined(_M_AMD64) // _M_IX86 and _M_AMD64 are Microsoft identifiers for Intel-based platforms. -# define OVR_CPU_SSE -#endif // __SSE__ - -#if defined( __ALTIVEC__ ) -# define OVR_CPU_ALTIVEC -#endif // __ALTIVEC__ - -#if defined(__ARM_NEON__) -# define OVR_CPU_ARM_NEON -#endif // __ARM_NEON__ - - -//----------------------------------------------------------------------------------- -// ***** Compiler Warnings - -// Disable MSVC warnings -#if defined(OVR_CC_MSVC) -# pragma warning(disable : 4127) // Inconsistent dll linkage -# pragma warning(disable : 4530) // Exception handling -# if (OVR_CC_MSVC<1300) -# pragma warning(disable : 4514) // Unreferenced inline function has been removed -# pragma warning(disable : 4710) // Function not inlined -# pragma warning(disable : 4714) // _force_inline not inlined -# pragma warning(disable : 4786) // Debug variable name longer than 255 chars -# endif // (OVR_CC_MSVC<1300) -#endif // (OVR_CC_MSVC) - - - -// *** Linux Unicode - must come before Standard Includes - -#ifdef OVR_OS_LINUX -// Use glibc unicode functions on linux. -# ifndef _GNU_SOURCE -# define _GNU_SOURCE -# endif -#endif - -//----------------------------------------------------------------------------------- -// ***** Standard Includes -// -#include <stddef.h> -#include <limits.h> -#include <float.h> - - -// MSVC Based Memory Leak checking - for now -#if defined(OVR_CC_MSVC) && defined(OVR_BUILD_DEBUG) -# define _CRTDBG_MAP_ALLOC -# include <stdlib.h> -# include <crtdbg.h> -#endif - - -//----------------------------------------------------------------------------------- -// ***** int8_t, int16_t, etc. - -#if defined(OVR_CC_MSVC) && (OVR_CC_VER <= 1500) // VS2008 and earlier - typedef signed char int8_t; - typedef unsigned char uint8_t; - typedef signed short int16_t; - typedef unsigned short uint16_t; - typedef signed int int32_t; - typedef unsigned int uint32_t; - typedef signed __int64 int64_t; - typedef unsigned __int64 uint64_t; -#else - #include <stdint.h> -#endif - - -//----------------------------------------------------------------------------------- -// ***** Type definitions for Common Systems - -namespace OVR { - -typedef char Char; - -// Pointer-sized integer -typedef size_t UPInt; -typedef ptrdiff_t SPInt; - - -#if defined(OVR_OS_MS) - -typedef char SByte; // 8 bit Integer (Byte) -typedef unsigned char UByte; -typedef short SInt16; // 16 bit Integer (Word) -typedef unsigned short UInt16; -typedef long SInt32; // 32 bit Integer -typedef unsigned long UInt32; -typedef __int64 SInt64; // 64 bit Integer (QWord) -typedef unsigned __int64 UInt64; - - -#elif defined(OVR_OS_MAC) || defined(OVR_OS_IPHONE) || defined(OVR_CC_GNU) - -typedef int SByte __attribute__((__mode__ (__QI__))); -typedef unsigned int UByte __attribute__((__mode__ (__QI__))); -typedef int SInt16 __attribute__((__mode__ (__HI__))); -typedef unsigned int UInt16 __attribute__((__mode__ (__HI__))); -typedef int SInt32 __attribute__((__mode__ (__SI__))); -typedef unsigned int UInt32 __attribute__((__mode__ (__SI__))); -typedef int SInt64 __attribute__((__mode__ (__DI__))); -typedef unsigned int UInt64 __attribute__((__mode__ (__DI__))); - -#else - -#include <sys/types.h> -typedef int8_t SByte; -typedef uint8_t UByte; -typedef int16_t SInt16; -typedef uint16_t UInt16; -typedef int32_t SInt32; -typedef uint32_t UInt32; -typedef int64_t SInt64; -typedef uint64_t UInt64; - -#endif - - -//osx PID is a signed int32 (already defined to pid_t in OSX framework) -//linux PID is a signed int32 (already defined) -//win32 PID is an unsigned int64 -#ifdef OVR_OS_WIN32 -//process ID representation -typedef unsigned long pid_t; -#endif - -struct OVR_GUID -{ - uint32_t Data1; - uint16_t Data2; - uint16_t Data3; - uint8_t Data4[8]; -}; - - - -} // OVR - - - -//----------------------------------------------------------------------------------- -// ****** Standard C/C++ Library -// -// Identifies which standard library is currently being used. -// -// LIBSTDCPP - GNU libstdc++, used by GCC. -// LIBCPP - LLVM libc++, typically used by clang and GCC. -// DINKUMWARE - Used by Microsoft and various non-Microsoft compilers (e.g. Sony clang). - -#if !defined(OVR_STDLIB_LIBSTDCPP) - #if defined(__GLIBCXX__) - #define OVR_STDLIB_LIBSTDCPP 1 - #endif -#endif - -#if !defined(OVR_STDLIB_LIBCPP) - #if defined(__clang__) - #if defined(__cplusplus) && __has_include(<__config>) - #define OVR_STDLIB_LIBCPP 1 - #endif - #endif -#endif - -#if !defined(OVR_STDLIB_DINKUMWARE) - #if defined(_YVALS) // Dinkumware globally #defines _YVALS from the #includes above. - #define OVR_STDLIB_DINKUMWARE 1 - #endif -#endif - - -//----------------------------------------------------------------------------------- -// ***** Macro Definitions -// -// We define the following: -// -// OVR_BYTE_ORDER - Defined to either OVR_LITTLE_ENDIAN or OVR_BIG_ENDIAN -// OVR_FORCE_INLINE - Forces inline expansion of function -// OVR_ASM - Assembly language prefix -// OVR_STR - Prefixes string with L"" if building unicode -// -// OVR_STDCALL - Use stdcall calling convention (Pascal arg order) -// OVR_CDECL - Use cdecl calling convention (C argument order) -// OVR_FASTCALL - Use fastcall calling convention (registers) -// - -// Byte order constants, OVR_BYTE_ORDER is defined to be one of these. -#define OVR_LITTLE_ENDIAN 1 -#define OVR_BIG_ENDIAN 2 - - -#if defined(OVR_OS_MS) - - // ***** Windows and non-desktop platforms - - // Byte order - #define OVR_BYTE_ORDER OVR_LITTLE_ENDIAN - - // Calling convention - goes after function return type but before function name - #ifdef __cplusplus_cli - # define OVR_FASTCALL __stdcall - #else - # define OVR_FASTCALL __fastcall - #endif - - #define OVR_STDCALL __stdcall - #define OVR_CDECL __cdecl - - - // Assembly macros - #if defined(OVR_CC_MSVC) - # define OVR_ASM _asm - #else - # define OVR_ASM asm - #endif // (OVR_CC_MSVC) - - #ifdef UNICODE - # define OVR_STR(str) L##str - #else - # define OVR_STR(str) str - #endif // UNICODE - -#else - - // **** Standard systems - - #if (defined(BYTE_ORDER) && (BYTE_ORDER == BIG_ENDIAN))|| \ - (defined(_BYTE_ORDER) && (_BYTE_ORDER == _BIG_ENDIAN)) - # define OVR_BYTE_ORDER OVR_BIG_ENDIAN - #elif (defined(__ARMEB__) || defined(OVR_CPU_PPC) || defined(OVR_CPU_PPC64)) - # define OVR_BYTE_ORDER OVR_BIG_ENDIAN - #else - # define OVR_BYTE_ORDER OVR_LITTLE_ENDIAN - #endif - - // Assembly macros - #define OVR_ASM __asm__ - #define OVR_ASM_PROC(procname) OVR_ASM - #define OVR_ASM_END OVR_ASM - - // Calling convention - goes after function return type but before function name - #define OVR_FASTCALL - #define OVR_STDCALL - #define OVR_CDECL - -#endif // defined(OVR_OS_WIN32) - - -//----------------------------------------------------------------------------------- -// ***** OVR_PTR_SIZE -// -// Specifies the byte size of pointers (same as sizeof void*). - -#if !defined(OVR_PTR_SIZE) - #if defined(__WORDSIZE) - #define OVR_PTR_SIZE ((__WORDSIZE) / 8) - #elif defined(_WIN64) || defined(__LP64__) || defined(_LP64) || defined(_M_IA64) || defined(__ia64__) || defined(__arch64__) || defined(__64BIT__) || defined(__Ptr_Is_64) - #define OVR_PTR_SIZE 8 - #elif defined(__CC_ARM) && (__sizeof_ptr == 8) - #define OVR_PTR_SIZE 8 - #else - #define OVR_PTR_SIZE 4 - #endif -#endif - - -//----------------------------------------------------------------------------------- -// ***** OVR_WORD_SIZE -// -// Specifies the byte size of a machine word/register. Not necessarily the same as -// the size of pointers, but usually >= the size of pointers. - -#if !defined(OVR_WORD_SIZE) - #define OVR_WORD_SIZE OVR_PTR_SIZE // For our currently supported platforms these are equal. -#endif - - -// ------------------------------------------------------------------------ -// ***** OVR_FORCE_INLINE -// -// Force inline substitute - goes before function declaration -// Example usage: -// OVR_FORCE_INLINE void Test(); - -#if !defined(OVR_FORCE_INLINE) - #if defined(OVR_CC_MSVC) - #define OVR_FORCE_INLINE __forceinline - #elif defined(OVR_CC_GNU) - #define OVR_FORCE_INLINE __attribute__((always_inline)) inline - #else - #define OVR_FORCE_INLINE inline - #endif // OVR_CC_MSVC -#endif - - -// ------------------------------------------------------------------------ -// ***** OVR_NO_INLINE -// -// Cannot be used with inline or OVR_FORCE_INLINE. -// Example usage: -// OVR_NO_INLINE void Test(); - -#if !defined(OVR_NO_INLINE) - #if defined(OVR_CC_MSVC) && (_MSC_VER >= 1500) // VS2008+ - #define OVR_NO_INLINE __declspec(noinline) - #elif !defined(OVR_CC_MSVC) - #define OVR_NO_INLINE __attribute__((noinline)) - #endif -#endif - - -// ----------------------------------------------------------------------------------- -// ***** OVR_STRINGIZE -// -// Converts a preprocessor symbol to a string. -// -// Example usage: -// printf("Line: %s", OVR_STRINGIZE(__LINE__)); -// -#if !defined(OVR_STRINGIFY) - #define OVR_STRINGIZEIMPL(x) #x - #define OVR_STRINGIZE(x) OVR_STRINGIZEIMPL(x) -#endif - - -// ----------------------------------------------------------------------------------- -// ***** OVR_JOIN -// -// Joins two preprocessing symbols together. Supports the case when either or the -// the symbols are macros themselves. -// -// Example usage: -// char OVR_JOIN(unique_, __LINE__); // Results in (e.g.) char unique_123; -// -#if !defined(OVR_JOIN) - #define OVR_JOIN(a, b) OVR_JOIN1(a, b) - #define OVR_JOIN1(a, b) OVR_JOIN2(a, b) - #define OVR_JOIN2(a, b) a##b -#endif - - -//----------------------------------------------------------------------------------- -// ***** OVR_OFFSETOF -// -// Portable implementation of offsetof for structs and classes. offsetof and GCC's -// __builtin_offsetof work only with POD types (standard-layout types under C++11), -// despite that it can safely work with a number of types that aren't POD. This -// version works with more types without generating compiler warnings or errors. -// Returns the offset as a size_t, as per offsetof. -// -// Example usage: -// struct Test{ int i; float f; }; -// size_t fPos = OVR_OFFSETOF(Test, f); - -#if defined(OVR_CC_GNU) - #define OVR_OFFSETOF(class_, member_) ((size_t)(((uintptr_t)&reinterpret_cast<const volatile char&>((((class_*)65536)->member_))) - 65536)) -#else - #define OVR_OFFSETOF(class_, member_) offsetof(class_, member_) -#endif - - -//----------------------------------------------------------------------------------- -// ***** OVR_SIZEOF_MEMBER -// -// Implements a portable way to determine the size of struct or class data member. -// C++11 allows this directly via sizeof (see OVR_CPP_NO_EXTENDED_SIZEOF), and this -// macro exists to handle pre-C++11 compilers. -// Returns the offset as a size_t, as per sizeof. -// -// Example usage: -// struct Test{ int i; float f; }; -// size_t fSize = OVR_SIZEOF_MEMBER(Test, f); -// -#if defined(OVR_CPP_NO_EXTENDED_SIZEOF) - #define OVR_SIZEOF_MEMBER(class_, member_) (sizeof(((class_*)0)->member_)) -#else - #define OVR_SIZEOF_MEMBER(class_, member_) (sizeof(class_::member_)) -#endif - - -//----------------------------------------------------------------------------------- -// ***** OVR_DEBUG_BREAK, OVR_DEBUG_CODE, -// OVR_ASSERT, OVR_ASSERT_M, OVR_ASSERT_AND_UNUSED -// -// Macros have effect only in debug builds. -// -// Example OVR_DEBUG_BREAK usage (note the lack of parentheses): -// #define MY_ASSERT(expression) do { if (!(expression)) { OVR_DEBUG_BREAK; } } while(0) -// -// Example OVR_DEBUG_CODE usage: -// OVR_DEBUG_CODE(printf("debug test\n");) -// or -// OVR_DEBUG_CODE(printf("debug test\n")); -// -// Example OVR_ASSERT usage: -// OVR_ASSERT(count < 100); -// OVR_ASSERT_M(count < 100, "count is too high"); -// -#if defined(OVR_BUILD_DEBUG) - // Causes a debugger breakpoint in debug builds. Has no effect in release builds. - // Microsoft Win32 specific debugging support - #if defined(OVR_CC_MSVC) - #define OVR_DEBUG_BREAK __debugbreak() - #elif defined(OVR_CC_GNU) || defined(OVR_CC_CLANG) - #if defined(OVR_CPU_X86) || defined(OVR_CPU_X86_64) - #define OVR_DEBUG_BREAK do { OVR_ASM("int $3\n\t"); } while(0) - #else - #define OVR_DEBUG_BREAK __builtin_trap() - #endif - #else - #define OVR_DEBUG_BREAK do { *((int *) 0) = 1; } while(0) - #endif - - // The expresssion is defined only in debug builds. It is defined away in release builds. - #define OVR_DEBUG_CODE(c) c - - // In debug builds this tests the given expression; if false then executes OVR_DEBUG_BREAK, - // if true then no action. Has no effect in release builds. - #if defined(__clang_analyzer__) // During static analysis, make it so the analyzer thinks that failed asserts result in program exit. Reduced false positives. - #include <stdlib.h> - #define OVR_ASSERT_M(p, message) do { if (!(p)) { OVR_DEBUG_BREAK; exit(0); } } while(0) - #define OVR_ASSERT(p) do { if (!(p)) { OVR_DEBUG_BREAK; exit(0); } } while(0) - #else - // void OVR_ASSERT_M(bool expression, const char message); - // Note: The expresion below is expanded into all usage of this assertion macro. - // We should try to minimize the size of the expanded code to the extent possible. - #define OVR_ASSERT_M(p, message) do \ - { \ - if (!(p)) \ - { \ - intptr_t ovrAssertUserParam; \ - OVRAssertionHandler ovrAssertUserHandler = OVR::GetAssertionHandler(&ovrAssertUserParam); \ - \ - if(ovrAssertUserHandler && !OVRIsDebuggerPresent()) \ - { \ - ovrAssertUserHandler(ovrAssertUserParam, "Assertion failure", message); \ - } \ - else \ - { \ - OVR_DEBUG_BREAK; \ - } \ - } \ - } while(0) - - // void OVR_ASSERT(bool expression); - #define OVR_ASSERT(p) OVR_ASSERT_M((p), (#p)) - #endif - - // Acts the same as OVR_ASSERT in debug builds. Acts the same as OVR_UNUSED in release builds. - // Example usage: OVR_ASSERT_AND_UNUSED(x < 30, x); - #define OVR_ASSERT_AND_UNUSED(expression, value) OVR_ASSERT(expression); OVR_UNUSED(value) - -#else - - // The expresssion is defined only in debug builds. It is defined away in release builds. - #define OVR_DEBUG_CODE(c) - - // Causes a debugger breakpoint in debug builds. Has no effect in release builds. - #define OVR_DEBUG_BREAK ((void)0) - - // In debug builds this tests the given expression; if false then executes OVR_DEBUG_BREAK, - // if true then no action. Has no effect in release builds. - #define OVR_ASSERT(p) ((void)0) - #define OVR_ASSERT_M(p, m) ((void)0) - - // Acts the same as OVR_ASSERT in debug builds. Acts the same as OVR_UNUSED in release builds. - // Example usage: OVR_ASSERT_AND_UNUSED(x < 30, x); - #define OVR_ASSERT_AND_UNUSED(expression, value) OVR_UNUSED(value) - -#endif // OVR_BUILD_DEBUG - - - -// Assert handler -// The user of this library can override the default assertion handler and provide their own. -namespace OVR -{ - // The return value meaning is reserved for future definition and currently has no effect. - typedef intptr_t (*OVRAssertionHandler)(intptr_t userParameter, const char* title, const char* message); - - // Returns the current assertion handler. - OVRAssertionHandler GetAssertionHandler(intptr_t* userParameter = NULL); - - // Sets the current assertion handler. - // The default assertion handler if none is set simply issues a debug break. - // Example usage: - // intptr_t CustomAssertionHandler(intptr_t /*userParameter*/, const char* title, const char* message)) { - // MessageBox(title, message); - // OVR_DEBUG_BREAK; - // } - void SetAssertionHandler(OVRAssertionHandler assertionHandler, intptr_t userParameter = 0); - - // Implements the default assertion handler. - intptr_t DefaultAssertionHandler(intptr_t userParameter, const char* title, const char* message); - - // Currently defined in OVR_DebugHelp.cpp - bool OVRIsDebuggerPresent(); -} - - -// ------------------------------------------------------------------------ -// ***** static_assert -// -// Portable support for C++11 static_assert. -// Acts as if the following were declared: -// void static_assert(bool const_expression, const char* msg); -// -// Example usage: -// static_assert(sizeof(int32_t) == 4, "int32_t expected to be 4 bytes."); - -#if defined(OVR_CPP_NO_STATIC_ASSERT) // If the compiler doesn't provide it intrinsically... - #if !defined(OVR_SA_UNUSED) - #if defined(OVR_CC_GNU) || defined(OVR_CC_CLANG) - #define OVR_SA_UNUSED __attribute__((unused)) - #else - #define OVR_SA_UNUSED - #endif - #define OVR_SA_PASTE(a,b) a##b - #define OVR_SA_HELP(a,b) OVR_SA_PASTE(a,b) - #endif - - #if defined(__COUNTER__) - #define static_assert(expression, msg) typedef char OVR_SA_HELP(compileTimeAssert, __COUNTER__) [((expression) != 0) ? 1 : -1] OVR_SA_UNUSED - #else - #define static_assert(expression, msg) typedef char OVR_SA_HELP(compileTimeAssert, __LINE__) [((expression) != 0) ? 1 : -1] OVR_SA_UNUSED - #endif -#endif - - -// ------------------------------------------------------------------------ -// ***** OVR_COMPILER_ASSERT -// -// Compile-time assert; produces compiler error if condition is false. -// The expression must be a compile-time constant expression. -// This macro is deprecated in favor of static_assert, which provides better -// compiler output and works in a broader range of contexts. -// -// Example usage: -// OVR_COMPILER_ASSERT(sizeof(int32_t == 4)); - -#if !defined(OVR_COMPILER_ASSERT) - #define OVR_COMPILER_ASSERT(expression) static_assert(expression, #expression) - #define OVR_COMPILER_ASSERT_M(expression, msg) static_assert(expression, msg) -#endif - - -// ***** OVR_PROCESSOR_PAUSE -// -// Yields the processor for other hyperthreads, usually for the purpose of implementing spins and spin locks. -// -// Example usage: -// while(!finished()) -// OVR_PROCESSOR_PAUSE(); - -#if defined(OVR_CPU_X86) || defined(OVR_CPU_X86_64) - #if defined(OVR_CC_GNU) || defined(OVR_CC_CLANG) - #define OVR_PROCESSOR_PAUSE() asm volatile("pause" ::: "memory") // Consumes 38-40 clocks on current Intel x86 and x64 hardware. - #elif defined(OVR_CC_MSVC) - #include <emmintrin.h> - #pragma intrinsic(_mm_pause) // Maps to asm pause. - #define OVR_PROCESSOR_PAUSE _mm_pause - #else - #define OVR_PROCESSOR_PAUSE() - #endif -#else - #define OVR_PROCESSOR_PAUSE() -#endif - - -// ------------------------------------------------------------------------ -// ***** OVR_ARRAY_COUNT -// -// Returns the element count of a C array. -// -// Example usage: -// float itemArray[16]; -// for(size_t i = 0; i < OVR_ARRAY_COUNT(itemArray); i++) { ... } - -#if defined(OVR_CPP_NO_CONSTEXPR) - #ifndef OVR_ARRAY_COUNT - #define OVR_ARRAY_COUNT(x) (sizeof(x) / sizeof(x[0])) - #endif -#else - // Smarter C++11 version which knows the difference between arrays and pointers. - template <typename T, size_t N> - char (&OVRArrayCountHelper(T (&x)[N]))[N]; - #define OVR_ARRAY_COUNT(x) (sizeof(OVRArrayCountHelper(x))) -#endif - - -// ------------------------------------------------------------------------ -// ***** OVR_CURRENT_FUNCTION -// -// Portable wrapper for __PRETTY_FUNCTION__, C99 __func__, __FUNCTION__. -// This represents the most expressive version available. -// Acts as if the following were declared: -// static const char OVR_CURRENT_FUNCTION[] = "function-name"; -// -// Example usage: -// void Test() { printf("%s", OVR_CURRENT_FUNCTION); } - -#if defined(OVR_CC_GNU) || defined(OVR_CC_CLANG) || (defined(__ICC) && (__ICC >= 600)) // GCC, clang, Intel - #define OVR_CURRENT_FUNCTION __PRETTY_FUNCTION__ -#elif defined(__FUNCSIG__) // VC++ - #define OVR_CURRENT_FUNCTION __FUNCSIG__ -#elif defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901) // C99 compilers - #define OVR_CURRENT_FUNCTION __func__ -#else - #define OVR_CURRENT_FUNCTION __FUNCTION__ -#endif - - -//----------------------------------------------------------------------------------- -// ***** OVR_DEPRECATED / OVR_DEPRECATED_MSG -// -// Portably annotates a function or struct as deprecated. -// Note that clang supports __deprecated_enum_msg, which may be useful to support. -// -// Example usage: -// OVR_DEPRECATED void Test(); // Use on the function declaration, as opposed to definition. -// -// struct OVR_DEPRECATED Test{ ... }; -// -// OVR_DEPRECATED_MSG("Test is deprecated") -// void Test(); - -#if !defined(OVR_DEPRECATED) - #if defined(OVR_CC_MSVC) && (OVR_CC_VERSION > 1400) // VS2005+ - #define OVR_DEPRECATED __declspec(deprecated) - #define OVR_DEPRECATED_MSG(msg) __declspec(deprecated(msg)) - #elif defined(OVR_CC_CLANG) && OVR_CC_HAS_FEATURE(attribute_deprecated_with_message) - #define OVR_DEPRECATED __declspec(deprecated) - #define OVR_DEPRECATED_MSG(msg) __attribute__((deprecated(msg))) - #elif defined(OVR_CC_GNU) && (OVR_CC_VERSION >= 405) - #define OVR_DEPRECATED __declspec(deprecated) - #define OVR_DEPRECATED_MSG(msg) __attribute__((deprecated(msg))) - #elif !defined(OVR_CC_MSVC) - #define OVR_DEPRECATED __attribute__((deprecated)) - #define OVR_DEPRECATED_MSG(msg) __attribute__((deprecated)) - #else - #define OVR_DEPRECATED - #define OVR_DEPRECATED_MSG(msg) - #endif -#endif - - -//----------------------------------------------------------------------------------- -// ***** OVR_UNUSED - Unused Argument handling -// Macro to quiet compiler warnings about unused parameters/variables. -// -// Example usage: -// void Test() { -// int x = SomeFunction(); -// OVR_UNUSED(x); -// } -// - -#if defined(OVR_CC_GNU) -# define OVR_UNUSED(a) do {__typeof__ (&a) __attribute__ ((unused)) __tmp = &a; } while(0) -#else -# define OVR_UNUSED(a) (a) -#endif - -#define OVR_UNUSED1(a1) OVR_UNUSED(a1) -#define OVR_UNUSED2(a1,a2) OVR_UNUSED(a1); OVR_UNUSED(a2) -#define OVR_UNUSED3(a1,a2,a3) OVR_UNUSED2(a1,a2); OVR_UNUSED(a3) -#define OVR_UNUSED4(a1,a2,a3,a4) OVR_UNUSED3(a1,a2,a3); OVR_UNUSED(a4) -#define OVR_UNUSED5(a1,a2,a3,a4,a5) OVR_UNUSED4(a1,a2,a3,a4); OVR_UNUSED(a5) -#define OVR_UNUSED6(a1,a2,a3,a4,a5,a6) OVR_UNUSED4(a1,a2,a3,a4); OVR_UNUSED2(a5,a6) -#define OVR_UNUSED7(a1,a2,a3,a4,a5,a6,a7) OVR_UNUSED4(a1,a2,a3,a4); OVR_UNUSED3(a5,a6,a7) -#define OVR_UNUSED8(a1,a2,a3,a4,a5,a6,a7,a8) OVR_UNUSED4(a1,a2,a3,a4); OVR_UNUSED4(a5,a6,a7,a8) -#define OVR_UNUSED9(a1,a2,a3,a4,a5,a6,a7,a8,a9) OVR_UNUSED4(a1,a2,a3,a4); OVR_UNUSED5(a5,a6,a7,a8,a9) - - -//----------------------------------------------------------------------------------- -// ***** Configuration Macros -// -// Expands to the current build type as a const char string literal. -// Acts as the following declaration: const char OVR_BUILD_STRING[]; - -#ifdef OVR_BUILD_DEBUG -# define OVR_BUILD_STRING "Debug" -#else -# define OVR_BUILD_STRING "Release" -#endif - - -//// Enables SF Debugging information -//# define OVR_BUILD_DEBUG - -// OVR_DEBUG_STATEMENT injects a statement only in debug builds. -// OVR_DEBUG_SELECT injects first argument in debug builds, second argument otherwise. -#ifdef OVR_BUILD_DEBUG -#define OVR_DEBUG_STATEMENT(s) s -#define OVR_DEBUG_SELECT(d, nd) d -#else -#define OVR_DEBUG_STATEMENT(s) -#define OVR_DEBUG_SELECT(d, nd) nd -#endif - - -#define OVR_ENABLE_THREADS -// -// Prevents OVR from defining new within -// type macros, so developers can override -// new using the #define new new(...) trick -// - used with OVR_DEFINE_NEW macro -//# define OVR_BUILD_DEFINE_NEW -// - - -//----------------------------------------------------------------------------------- -// ***** Find normal allocations -// -// Our allocations are all supposed to go through the OVR System Allocator, so that -// they can be run through a game's own preferred allocator. Occasionally we will -// accidentally introduce new code that doesn't adhere to this contract. And it -// then becomes difficult to track down these normal allocations. This piece of -// code makes it easy to check for normal allocations by asserting whenever they -// happen in our code. - -//#define OVR_FIND_NORMAL_ALLOCATIONS -#ifdef OVR_FIND_NORMAL_ALLOCATIONS - -inline void* operator new (size_t size, const char* filename, int line) -{ - void* ptr = new char[size]; - OVR_ASSERT(false); - return ptr; -} - -#define new new(__FILE__, __LINE__) - -#endif // OVR_FIND_NORMAL_ALLOCATIONS - - -#include "OVR_Nullptr.h" - - - - -#endif // OVR_Types_h diff --git a/LibOVR/Src/Kernel/OVR_UTF8Util.cpp b/LibOVR/Src/Kernel/OVR_UTF8Util.cpp deleted file mode 100644 index 68e58ea..0000000 --- a/LibOVR/Src/Kernel/OVR_UTF8Util.cpp +++ /dev/null @@ -1,556 +0,0 @@ -/************************************************************************** - -Filename : OVR_UTF8Util.cpp -Content : UTF8 Unicode character encoding/decoding support -Created : September 19, 2012 -Notes : -Notes : Much useful info at "UTF-8 and Unicode FAQ" - http://www.cl.cam.ac.uk/~mgk25/unicode.html - -Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); -you may not use the Oculus VR Rift SDK except in compliance with the License, -which is provided at the time of installation or download, or which -otherwise accompanies this software in either electronic or hard copy form. - -You may obtain a copy of the License at - -http://www.oculusvr.com/licenses/LICENSE-3.2 - -Unless required by applicable law or agreed to in writing, the Oculus VR SDK -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -************************************************************************************/ - -#include "OVR_UTF8Util.h" - -namespace OVR { namespace UTF8Util { - -intptr_t OVR_STDCALL GetLength(const char* buf, intptr_t buflen) -{ - const char* p = buf; - intptr_t length = 0; - - if (buflen != -1) - { - while (p - buf < buflen) - { - // We should be able to have ASStrings with 0 in the middle. - UTF8Util::DecodeNextChar_Advance0(&p); - length++; - } - } - else - { - while (UTF8Util::DecodeNextChar_Advance0(&p)) - length++; - } - - return length; -} - -uint32_t OVR_STDCALL GetCharAt(intptr_t index, const char* putf8str, intptr_t length) -{ - const char* buf = putf8str; - uint32_t c = 0; - - if (length != -1) - { - while (buf - putf8str < length) - { - c = UTF8Util::DecodeNextChar_Advance0(&buf); - if (index == 0) - return c; - index--; - } - - return c; - } - - do - { - c = UTF8Util::DecodeNextChar_Advance0(&buf); - index--; - - if (c == 0) - { - // We've hit the end of the string; don't go further. - OVR_ASSERT(index == 0); - return c; - } - } while (index >= 0); - - return c; -} - -intptr_t OVR_STDCALL GetByteIndex(intptr_t index, const char *putf8str, intptr_t length) -{ - const char* buf = putf8str; - - if (length != -1) - { - while ((buf - putf8str) < length && index > 0) - { - UTF8Util::DecodeNextChar_Advance0(&buf); - index--; - } - - return buf-putf8str; - } - - while (index > 0) - { - uint32_t c = UTF8Util::DecodeNextChar_Advance0(&buf); - index--; - - if (c == 0) - return buf-putf8str; - }; - - return buf-putf8str; -} - -int OVR_STDCALL GetEncodeCharSize(uint32_t ucs_character) -{ - if (ucs_character <= 0x7F) - return 1; - else if (ucs_character <= 0x7FF) - return 2; - else if (ucs_character <= 0xFFFF) - return 3; - else if (ucs_character <= 0x1FFFFF) - return 4; - else if (ucs_character <= 0x3FFFFFF) - return 5; - else if (ucs_character <= 0x7FFFFFFF) - return 6; - else - return 0; -} - -uint32_t OVR_STDCALL DecodeNextChar_Advance0(const char** putf8Buffer) -{ - uint32_t uc; - char c; - - // Security considerations: - // - // Changed, this is now only the case for DecodeNextChar: - // - If we hit a zero byte, we want to return 0 without stepping - // the buffer pointer past the 0. th - // - // If we hit an "overlong sequence"; i.e. a character encoded - // in a longer multibyte string than is necessary, then we - // need to discard the character. This is so attackers can't - // disguise dangerous characters or character sequences -- - // there is only one valid encoding for each character. - // - // If we decode characters { 0xD800 .. 0xDFFF } or { 0xFFFE, - // 0xFFFF } then we ignore them; they are not valid in UTF-8. - - // This isn't actually an invalid character; it's a valid char that - // looks like an inverted question mark. -#define INVALID_CHAR 0x0FFFD - -#define FIRST_BYTE(mask, shift) \ - uc = (c & (mask)) << (shift); - -#define NEXT_BYTE(shift) \ - c = **putf8Buffer; \ - if (c == 0) return 0; /* end of buffer, do not advance */ \ - if ((c & 0xC0) != 0x80) return INVALID_CHAR; /* standard check */ \ - (*putf8Buffer)++; \ - uc |= (c & 0x3F) << shift; - - c = **putf8Buffer; - (*putf8Buffer)++; - if (c == 0) - return 0; // End of buffer. - - if ((c & 0x80) == 0) return (uint32_t) c; // Conventional 7-bit ASCII. - - // Multi-byte sequences. - if ((c & 0xE0) == 0xC0) - { - // Two-byte sequence. - FIRST_BYTE(0x1F, 6); - NEXT_BYTE(0); - if (uc < 0x80) return INVALID_CHAR; // overlong - return uc; - } - else if ((c & 0xF0) == 0xE0) - { - // Three-byte sequence. - FIRST_BYTE(0x0F, 12); - NEXT_BYTE(6); - NEXT_BYTE(0); - if (uc < 0x800) return INVALID_CHAR; // overlong - // Not valid ISO 10646, but Flash requires these to work - // see AS3 test e15_5_3_2_3 for String.fromCharCode().charCodeAt(0) - // if (uc >= 0x0D800 && uc <= 0x0DFFF) return INVALID_CHAR; - // if (uc == 0x0FFFE || uc == 0x0FFFF) return INVALID_CHAR; // not valid ISO 10646 - return uc; - } - else if ((c & 0xF8) == 0xF0) - { - // Four-byte sequence. - FIRST_BYTE(0x07, 18); - NEXT_BYTE(12); - NEXT_BYTE(6); - NEXT_BYTE(0); - if (uc < 0x010000) return INVALID_CHAR; // overlong - return uc; - } - else if ((c & 0xFC) == 0xF8) - { - // Five-byte sequence. - FIRST_BYTE(0x03, 24); - NEXT_BYTE(18); - NEXT_BYTE(12); - NEXT_BYTE(6); - NEXT_BYTE(0); - if (uc < 0x0200000) return INVALID_CHAR; // overlong - return uc; - } - else if ((c & 0xFE) == 0xFC) - { - // Six-byte sequence. - FIRST_BYTE(0x01, 30); - NEXT_BYTE(24); - NEXT_BYTE(18); - NEXT_BYTE(12); - NEXT_BYTE(6); - NEXT_BYTE(0); - if (uc < 0x04000000) return INVALID_CHAR; // overlong - return uc; - } - else - { - // Invalid. - return INVALID_CHAR; - } -} - - -void OVR_STDCALL EncodeChar(char* pbuffer, intptr_t* pindex, uint32_t ucs_character) -{ - if (ucs_character <= 0x7F) - { - // Plain single-byte ASCII. - pbuffer[(*pindex)++] = (char) ucs_character; - } - else if (ucs_character <= 0x7FF) - { - // Two bytes. - pbuffer[(*pindex)++] = 0xC0 | (char)(ucs_character >> 6); - pbuffer[(*pindex)++] = 0x80 | (char)((ucs_character >> 0) & 0x3F); - } - else if (ucs_character <= 0xFFFF) - { - // Three bytes. - pbuffer[(*pindex)++] = 0xE0 | (char)(ucs_character >> 12); - pbuffer[(*pindex)++] = 0x80 | (char)((ucs_character >> 6) & 0x3F); - pbuffer[(*pindex)++] = 0x80 | (char)((ucs_character >> 0) & 0x3F); - } - else if (ucs_character <= 0x1FFFFF) - { - // Four bytes. - pbuffer[(*pindex)++] = 0xF0 | (char)(ucs_character >> 18); - pbuffer[(*pindex)++] = 0x80 | (char)((ucs_character >> 12) & 0x3F); - pbuffer[(*pindex)++] = 0x80 | (char)((ucs_character >> 6) & 0x3F); - pbuffer[(*pindex)++] = 0x80 | (char)((ucs_character >> 0) & 0x3F); - } - else if (ucs_character <= 0x3FFFFFF) - { - // Five bytes. - pbuffer[(*pindex)++] = 0xF8 | (char)(ucs_character >> 24); - pbuffer[(*pindex)++] = 0x80 | (char)((ucs_character >> 18) & 0x3F); - pbuffer[(*pindex)++] = 0x80 | (char)((ucs_character >> 12) & 0x3F); - pbuffer[(*pindex)++] = 0x80 | (char)((ucs_character >> 6) & 0x3F); - pbuffer[(*pindex)++] = 0x80 | (char)((ucs_character >> 0) & 0x3F); - } - else if (ucs_character <= 0x7FFFFFFF) - { - // Six bytes. - pbuffer[(*pindex)++] = 0xFC | (char)(ucs_character >> 30); - pbuffer[(*pindex)++] = 0x80 | (char)((ucs_character >> 24) & 0x3F); - pbuffer[(*pindex)++] = 0x80 | (char)((ucs_character >> 18) & 0x3F); - pbuffer[(*pindex)++] = 0x80 | (char)((ucs_character >> 12) & 0x3F); - pbuffer[(*pindex)++] = 0x80 | (char)((ucs_character >> 6) & 0x3F); - pbuffer[(*pindex)++] = 0x80 | (char)((ucs_character >> 0) & 0x3F); - } - else - { - // Invalid char; don't encode anything. - } -} - -intptr_t OVR_STDCALL GetEncodeStringSize(const wchar_t* pchar, intptr_t length) -{ - intptr_t len = 0; - if (length != -1) - for (int i = 0; i < length; i++) - { - len += GetEncodeCharSize(pchar[i]); - } - else - for (int i = 0;; i++) - { - if (pchar[i] == 0) - return len; - len += GetEncodeCharSize(pchar[i]); - } - return len; -} - -void OVR_STDCALL EncodeString(char *pbuff, const wchar_t* pchar, intptr_t length) -{ - intptr_t ofs = 0; - if (length != -1) - { - for (int i = 0; i < length; i++) - { - EncodeChar(pbuff, &ofs, pchar[i]); - } - } - else - { - for (int i = 0;; i++) - { - if (pchar[i] == 0) - break; - EncodeChar(pbuff, &ofs, pchar[i]); - } - } - pbuff[ofs] = 0; -} - -size_t OVR_STDCALL DecodeString(wchar_t *pbuff, const char* putf8str, intptr_t bytesLen) -{ - wchar_t *pbegin = pbuff; - if (bytesLen == -1) - { - while (1) - { - uint32_t ch = DecodeNextChar_Advance0(&putf8str); - if (ch == 0) - break; - else if (ch >= 0xFFFF) - ch = 0xFFFD; - *pbuff++ = wchar_t(ch); - } - } - else - { - const char* p = putf8str; - while ((p - putf8str) < bytesLen) - { - uint32_t ch = DecodeNextChar_Advance0(&p); - if (ch >= 0xFFFF) - ch = 0xFFFD; - *pbuff++ = wchar_t(ch); - } - } - - *pbuff = 0; - return pbuff - pbegin; -} - - -#ifdef UTF8_UNIT_TEST - -// Compile this test case with something like: -// -// gcc utf8.cpp -g -I.. -DUTF8_UNIT_TEST -lstdc++ -o utf8_test -// -// or -// -// cl utf8.cpp -Zi -Od -DUTF8_UNIT_TEST -I.. -// -// If possible, try running the test program with the first arg -// pointing at the file: -// -// http://www.cl.cam.ac.uk/~mgk25/ucs/examples/UTF-8-test.txt -// -// and examine the results by eye to make sure they are acceptable to -// you. - - -#include "base/utility.h" -#include <stdio.h> - - -bool check_equal(const char* utf8_in, const uint32_t* ucs_in) -{ - for (;;) - { - uint32_t next_ucs = *ucs_in++; - uint32_t next_ucs_from_utf8 = utf8::decode_next_unicode_character(&utf8_in); - if (next_ucs != next_ucs_from_utf8) - { - return false; - } - if (next_ucs == 0) - { - OVR_ASSERT(next_ucs_from_utf8 == 0); - break; - } - } - - return true; -} - - -void log_ascii(const char* line) -{ - for (;;) - { - unsigned char c = (unsigned char) *line++; - if (c == 0) - { - // End of line. - return; - } - else if (c != '\n' - && (c < 32 || c > 127)) - { - // Non-printable as plain ASCII. - printf("<0x%02X>", (int) c); - } - else - { - printf("%c", c); - } - } -} - - -void log_ucs(const uint32_t* line) -{ - for (;;) - { - uint32_t uc = *line++; - if (uc == 0) - { - // End of line. - return; - } - else if (uc != '\n' - && (uc < 32 || uc > 127)) - { - // Non-printable as plain ASCII. - printf("<U-%04X>", uc); - } - else - { - printf("%c", (char) uc); - } - } -} - - -// Simple canned test. -int main(int argc, const char* argv[]) -{ - { - const char* test8 = "Ignacio Castaño"; - const uint32_t test32[] = - { - 0x49, 0x67, 0x6E, 0x61, 0x63, - 0x69, 0x6F, 0x20, 0x43, 0x61, - 0x73, 0x74, 0x61, 0xF1, 0x6F, - 0x00 - }; - - OVR_ASSERT(check_equal(test8, test32)); - } - - // If user passed an arg, try reading the file as UTF-8 encoded text. - if (argc > 1) - { - const char* filename = argv[1]; - FILE* fp = fopen(filename, "rb"); - if (fp == NULL) - { - printf("Can't open file '%s'\n", filename); - return 1; - } - - // Read lines from the file, encode/decode them, and highlight discrepancies. - const int LINE_SIZE = 200; // max line size - char line_buffer_utf8[LINE_SIZE]; - char reencoded_utf8[6 * LINE_SIZE]; - uint32_t line_buffer_ucs[LINE_SIZE]; - - int byte_counter = 0; - for (;;) - { - int c = fgetc(fp); - if (c == EOF) - { - // Done. - break; - } - line_buffer_utf8[byte_counter++] = c; - if (c == '\n' || byte_counter >= LINE_SIZE - 2) - { - // End of line. Process the line. - line_buffer_utf8[byte_counter++] = 0; // terminate. - - // Decode into UCS. - const char* p = line_buffer_utf8; - uint32_t* q = line_buffer_ucs; - for (;;) - { - uint32_t uc = UTF8Util::DecodeNextChar(&p); - *q++ = uc; - - OVR_ASSERT(q < line_buffer_ucs + LINE_SIZE); - OVR_ASSERT(p < line_buffer_utf8 + LINE_SIZE); - - if (uc == 0) break; - } - - // Encode back into UTF-8. - q = line_buffer_ucs; - int index = 0; - for (;;) - { - uint32_t uc = *q++; - OVR_ASSERT(index < LINE_SIZE * 6 - 6); - int last_index = index; - UTF8Util::EncodeChar(reencoded_utf8, &index, uc); - OVR_ASSERT(index <= last_index + 6); - if (uc == 0) break; - } - - // This can be useful for debugging. -#if 0 - // Show the UCS and the re-encoded UTF-8. - log_ucs(line_buffer_ucs); - log_ascii(reencoded_utf8); -#endif // 0 - - OVR_ASSERT(check_equal(line_buffer_utf8, line_buffer_ucs)); - OVR_ASSERT(check_equal(reencoded_utf8, line_buffer_ucs)); - - // Start next line. - byte_counter = 0; - } - } - - fclose(fp); - } - - return 0; -} - - -#endif // UTF8_UNIT_TEST - -}} // namespace UTF8Util::OVR - diff --git a/LibOVR/Src/Kernel/OVR_UTF8Util.h b/LibOVR/Src/Kernel/OVR_UTF8Util.h deleted file mode 100644 index 3b640f0..0000000 --- a/LibOVR/Src/Kernel/OVR_UTF8Util.h +++ /dev/null @@ -1,99 +0,0 @@ -/************************************************************************************ - -PublicHeader: OVR_Kernel.h -Filename : OVR_UTF8Util.h -Content : UTF8 Unicode character encoding/decoding support -Created : September 19, 2012 -Notes : - -Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); -you may not use the Oculus VR Rift SDK except in compliance with the License, -which is provided at the time of installation or download, or which -otherwise accompanies this software in either electronic or hard copy form. - -You may obtain a copy of the License at - -http://www.oculusvr.com/licenses/LICENSE-3.2 - -Unless required by applicable law or agreed to in writing, the Oculus VR SDK -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -************************************************************************************/ - -#ifndef OVR_UTF8Util_h -#define OVR_UTF8Util_h - -#include "OVR_Types.h" - -namespace OVR { namespace UTF8Util { - -//----------------------------------------------------------------------------------- - -// *** UTF8 string length and indexing. - -// Determines the length of UTF8 string in characters. -// If source length is specified (in bytes), null 0 character is counted properly. -intptr_t OVR_STDCALL GetLength(const char* putf8str, intptr_t length = -1); - -// Gets a decoded UTF8 character at index; you can access up to the index returned -// by GetLength. 0 will be returned for out of bounds access. -uint32_t OVR_STDCALL GetCharAt(intptr_t index, const char* putf8str, intptr_t length = -1); - -// Converts UTF8 character index into byte offset. -// -1 is returned if index was out of bounds. -intptr_t OVR_STDCALL GetByteIndex(intptr_t index, const char* putf8str, intptr_t length = -1); - - -// *** 16-bit Unicode string Encoding/Decoding routines. - -// Determines the number of bytes necessary to encode a string. -// Does not count the terminating 0 (null) character. -intptr_t OVR_STDCALL GetEncodeStringSize(const wchar_t* pchar, intptr_t length = -1); - -// Encodes a unicode (UCS-2 only) string into a buffer. The size of buffer must be at -// least GetEncodeStringSize() + 1. -void OVR_STDCALL EncodeString(char *pbuff, const wchar_t* pchar, intptr_t length = -1); - -// Decode UTF8 into a wchar_t buffer. Must have GetLength()+1 characters available. -// Characters over 0xFFFF are replaced with 0xFFFD. -// Returns the length of resulting string (number of characters) -size_t OVR_STDCALL DecodeString(wchar_t *pbuff, const char* putf8str, intptr_t bytesLen = -1); - - -// *** Individual character Encoding/Decoding. - -// Determined the number of bytes necessary to encode a UCS character. -int OVR_STDCALL GetEncodeCharSize(uint32_t ucsCharacter); - -// Encodes the given UCS character into the given UTF-8 buffer. -// Writes the data starting at buffer[offset], and -// increments offset by the number of bytes written. -// May write up to 6 bytes, so make sure there's room in the buffer -void OVR_STDCALL EncodeChar(char* pbuffer, intptr_t* poffset, uint32_t ucsCharacter); - -// Return the next Unicode character in the UTF-8 encoded buffer. -// Invalid UTF-8 sequences produce a U+FFFD character as output. -// Advances *utf8_buffer past the character returned. Pointer advance -// occurs even if the terminating 0 character is hit, since that allows -// strings with middle '\0' characters to be supported. -uint32_t OVR_STDCALL DecodeNextChar_Advance0(const char** putf8Buffer); - -// Safer version of DecodeNextChar, which doesn't advance pointer if -// null character is hit. -inline uint32_t DecodeNextChar(const char** putf8Buffer) -{ - uint32_t ch = DecodeNextChar_Advance0(putf8Buffer); - if (ch == 0) - (*putf8Buffer)--; - return ch; -} - - -}} // OVR::UTF8Util - -#endif diff --git a/LibOVR/Src/Kernel/OVR_mach_exc_OSX.c b/LibOVR/Src/Kernel/OVR_mach_exc_OSX.c deleted file mode 100644 index 142faf1..0000000 --- a/LibOVR/Src/Kernel/OVR_mach_exc_OSX.c +++ /dev/null @@ -1,2955 +0,0 @@ -/* This file was generated by the MIG utility with: - mig /usr/include/mach/mach_exc.defs - We pre-generate them instead of generate them at compile-time because we - need to rename some of the functions to append _OVR so we don't get conflicts - with any other versions of these functions the application may have. -*/ - -/* Begin mach_excUser.c */ - -#define __MIG_check__Reply__mach_exc_subsystem__ 1 -#define __NDR_convert__Reply__mach_exc_subsystem__ 1 -#define __NDR_convert__mig_reply_error_subsystem__ 1 - -#include "OVR_mach_exc_OSX.h" - -#if defined(__cplusplus) - extern "C" { -#endif - -#ifndef mig_internal -#define mig_internal static __inline__ -#endif /* mig_internal */ - -#ifndef mig_external -#define mig_external -#endif /* mig_external */ - -#if !defined(__MigTypeCheck) && defined(TypeCheck) -#define __MigTypeCheck TypeCheck /* Legacy setting */ -#endif /* !defined(__MigTypeCheck) */ - -#if !defined(__MigKernelSpecificCode) && defined(_MIG_KERNEL_SPECIFIC_CODE_) -#define __MigKernelSpecificCode _MIG_KERNEL_SPECIFIC_CODE_ /* Legacy setting */ -#endif /* !defined(__MigKernelSpecificCode) */ - -#ifndef LimitCheck -#define LimitCheck 0 -#endif /* LimitCheck */ - -#ifndef min -#define min(a,b) ( ((a) < (b))? (a): (b) ) -#endif /* min */ - -#if !defined(_WALIGN_) -#define _WALIGN_(x) (((x) + 3) & ~3) -#endif /* !defined(_WALIGN_) */ - -#if !defined(_WALIGNSZ_) -#define _WALIGNSZ_(x) _WALIGN_(sizeof(x)) -#endif /* !defined(_WALIGNSZ_) */ - -#ifndef UseStaticTemplates -#define UseStaticTemplates 0 -#endif /* UseStaticTemplates */ - -#ifndef __MachMsgErrorWithTimeout -#define __MachMsgErrorWithTimeout(_R_) { \ - switch (_R_) { \ - case MACH_SEND_INVALID_DATA: \ - case MACH_SEND_INVALID_DEST: \ - case MACH_SEND_INVALID_HEADER: \ - mig_put_reply_port(InP->Head.msgh_reply_port); \ - break; \ - case MACH_SEND_TIMED_OUT: \ - case MACH_RCV_TIMED_OUT: \ - default: \ - mig_dealloc_reply_port(InP->Head.msgh_reply_port); \ - } \ -} -#endif /* __MachMsgErrorWithTimeout */ - -#ifndef __MachMsgErrorWithoutTimeout -#define __MachMsgErrorWithoutTimeout(_R_) { \ - switch (_R_) { \ - case MACH_SEND_INVALID_DATA: \ - case MACH_SEND_INVALID_DEST: \ - case MACH_SEND_INVALID_HEADER: \ - mig_put_reply_port(InP->Head.msgh_reply_port); \ - break; \ - default: \ - mig_dealloc_reply_port(InP->Head.msgh_reply_port); \ - } \ -} -#endif /* __MachMsgErrorWithoutTimeout */ - -#ifndef __DeclareSendRpc -#define __DeclareSendRpc(_NUM_, _NAME_) -#endif /* __DeclareSendRpc */ - -#ifndef __BeforeSendRpc -#define __BeforeSendRpc(_NUM_, _NAME_) -#endif /* __BeforeSendRpc */ - -#ifndef __AfterSendRpc -#define __AfterSendRpc(_NUM_, _NAME_) -#endif /* __AfterSendRpc */ - -#ifndef __DeclareSendSimple -#define __DeclareSendSimple(_NUM_, _NAME_) -#endif /* __DeclareSendSimple */ - -#ifndef __BeforeSendSimple -#define __BeforeSendSimple(_NUM_, _NAME_) -#endif /* __BeforeSendSimple */ - -#ifndef __AfterSendSimple -#define __AfterSendSimple(_NUM_, _NAME_) -#endif /* __AfterSendSimple */ - -#ifndef msgh_request_port - #define msgh_request_port msgh_remote_port -#endif - -#ifndef msgh_reply_port - #define msgh_reply_port msgh_local_port -#endif - - -#if ( __MigTypeCheck || __NDR_convert__ ) -#if __MIG_check__Reply__mach_exc_subsystem__ -#if !defined(__MIG_check__Reply__mach_exception_raise_t__defined) -#define __MIG_check__Reply__mach_exception_raise_t__defined -#ifndef __NDR_convert__int_rep__Reply__mach_exception_raise_t__RetCode__defined -#if defined(__NDR_convert__int_rep__mach_exc__kern_return_t__defined) -#define __NDR_convert__int_rep__Reply__mach_exception_raise_t__RetCode__defined -#define __NDR_convert__int_rep__Reply__mach_exception_raise_t__RetCode(a, f) \ - __NDR_convert__int_rep__mach_exc__kern_return_t((kern_return_t *)(a), f) -#elif defined(__NDR_convert__int_rep__kern_return_t__defined) -#define __NDR_convert__int_rep__Reply__mach_exception_raise_t__RetCode__defined -#define __NDR_convert__int_rep__Reply__mach_exception_raise_t__RetCode(a, f) \ - __NDR_convert__int_rep__kern_return_t((kern_return_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__int_rep__Reply__mach_exception_raise_t__RetCode__defined */ - - - - - -mig_internal kern_return_t __MIG_check__Reply__mach_exception_raise_t_OVR(__Reply__mach_exception_raise_t *Out0P) -{ - - typedef __Reply__mach_exception_raise_t __Reply; - if (Out0P->Head.msgh_id != 2505) { - if (Out0P->Head.msgh_id == MACH_NOTIFY_SEND_ONCE) - { return MIG_SERVER_DIED; } - else - { return MIG_REPLY_MISMATCH; } - } - - #if __MigTypeCheck - if ((Out0P->Head.msgh_bits & MACH_MSGH_BITS_COMPLEX) || - (Out0P->Head.msgh_size != (mach_msg_size_t)sizeof(__Reply))) - { return MIG_TYPE_ERROR ; } - #endif /* __MigTypeCheck */ - - #if defined(__NDR_convert__int_rep__Reply__mach_exception_raise_t__RetCode__defined) - if (Out0P->NDR.int_rep != NDR_record.int_rep) - __NDR_convert__int_rep__Reply__mach_exception_raise_t__RetCode(&Out0P->RetCode, Out0P->NDR.int_rep); - #endif /* __NDR_convert__int_rep__Reply__mach_exception_raise_t__RetCode__defined */ - { - return Out0P->RetCode; - } -} -#endif /* !defined(__MIG_check__Reply__mach_exception_raise_t__defined) */ -#endif /* __MIG_check__Reply__mach_exc_subsystem__ */ -#endif /* ( __MigTypeCheck || __NDR_convert__ ) */ - - -/* Routine mach_exception_raise_OVR */ -mig_external kern_return_t mach_exception_raise_OVR -( - mach_port_t exception_port, - mach_port_t thread, - mach_port_t task, - exception_type_t exception, - mach_exception_data_t code, - mach_msg_type_number_t codeCnt -) -{ - - #ifdef __MigPackStructs - #pragma pack(4) - #endif - typedef struct { - mach_msg_header_t Head; - /* start of the kernel processed data */ - mach_msg_body_t msgh_body; - mach_msg_port_descriptor_t thread; - mach_msg_port_descriptor_t task; - /* end of the kernel processed data */ - NDR_record_t NDR; - exception_type_t exception; - mach_msg_type_number_t codeCnt; - int64_t code[2]; - } Request; - #ifdef __MigPackStructs - #pragma pack() - #endif - - #ifdef __MigPackStructs - #pragma pack(4) - #endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - kern_return_t RetCode; - mach_msg_trailer_t trailer; - } Reply; - #ifdef __MigPackStructs - #pragma pack() - #endif - - #ifdef __MigPackStructs - #pragma pack(4) - #endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - kern_return_t RetCode; - } __Reply; - #ifdef __MigPackStructs - #pragma pack() - #endif - /* - * typedef struct { - * mach_msg_header_t Head; - * NDR_record_t NDR; - * kern_return_t RetCode; - * } mig_reply_error_t; - */ - - union { - Request In; - Reply Out; - } Mess; - - Request *InP = &Mess.In; - Reply *Out0P = &Mess.Out; - - mach_msg_return_t msg_result; - unsigned int msgh_size; - - #ifdef __MIG_check__Reply__mach_exception_raise_t__defined - kern_return_t check_result; - #endif /* __MIG_check__Reply__mach_exception_raise_t__defined */ - - __DeclareSendRpc(2405, "mach_exception_raise_OVR") - - #if UseStaticTemplates - const static mach_msg_port_descriptor_t threadTemplate = { - /* name = */ MACH_PORT_NULL, - /* pad1 = */ 0, - /* pad2 = */ 0, - /* disp = */ 19, - /* type = */ MACH_MSG_PORT_DESCRIPTOR, - }; - #endif /* UseStaticTemplates */ - - #if UseStaticTemplates - const static mach_msg_port_descriptor_t taskTemplate = { - /* name = */ MACH_PORT_NULL, - /* pad1 = */ 0, - /* pad2 = */ 0, - /* disp = */ 19, - /* type = */ MACH_MSG_PORT_DESCRIPTOR, - }; - #endif /* UseStaticTemplates */ - - InP->msgh_body.msgh_descriptor_count = 2; - #if UseStaticTemplates - InP->thread = threadTemplate; - InP->thread.name = thread; - #else /* UseStaticTemplates */ - InP->thread.name = thread; - InP->thread.disposition = 19; - InP->thread.type = MACH_MSG_PORT_DESCRIPTOR; - #endif /* UseStaticTemplates */ - - #if UseStaticTemplates - InP->task = taskTemplate; - InP->task.name = task; - #else /* UseStaticTemplates */ - InP->task.name = task; - InP->task.disposition = 19; - InP->task.type = MACH_MSG_PORT_DESCRIPTOR; - #endif /* UseStaticTemplates */ - - InP->NDR = NDR_record; - - InP->exception = exception; - - if (codeCnt > 2) { - { return MIG_ARRAY_TOO_LARGE; } - } - (void)memcpy((char *) InP->code, (const char *) code, 8 * codeCnt); - - InP->codeCnt = codeCnt; - - msgh_size = (mach_msg_size_t)(sizeof(Request) - 16) + ((8 * codeCnt)); - InP->Head.msgh_bits = MACH_MSGH_BITS_COMPLEX| - MACH_MSGH_BITS(19, MACH_MSG_TYPE_MAKE_SEND_ONCE); - /* msgh_size passed as argument */ - InP->Head.msgh_request_port = exception_port; - InP->Head.msgh_reply_port = mig_get_reply_port(); - InP->Head.msgh_id = 2405; - - __BeforeSendRpc(2405, "mach_exception_raise_OVR") - msg_result = mach_msg(&InP->Head, MACH_SEND_MSG|MACH_RCV_MSG|MACH_MSG_OPTION_NONE, msgh_size, (mach_msg_size_t)sizeof(Reply), InP->Head.msgh_reply_port, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL); - __AfterSendRpc(2405, "mach_exception_raise_OVR") - if (msg_result != MACH_MSG_SUCCESS) { - __MachMsgErrorWithoutTimeout(msg_result); - { return msg_result; } - } - - - #if defined(__MIG_check__Reply__mach_exception_raise_t__defined) - check_result = __MIG_check__Reply__mach_exception_raise_t_OVR((__Reply__mach_exception_raise_t *)Out0P); - if (check_result != MACH_MSG_SUCCESS) - { return check_result; } - #endif /* defined(__MIG_check__Reply__mach_exception_raise_t__defined) */ - - return KERN_SUCCESS; -} - -#if ( __MigTypeCheck || __NDR_convert__ ) -#if __MIG_check__Reply__mach_exc_subsystem__ -#if !defined(__MIG_check__Reply__mach_exception_raise_state_t__defined) -#define __MIG_check__Reply__mach_exception_raise_state_t__defined -#ifndef __NDR_convert__int_rep__Reply__mach_exception_raise_state_t__RetCode__defined -#if defined(__NDR_convert__int_rep__mach_exc__kern_return_t__defined) -#define __NDR_convert__int_rep__Reply__mach_exception_raise_state_t__RetCode__defined -#define __NDR_convert__int_rep__Reply__mach_exception_raise_state_t__RetCode(a, f) \ - __NDR_convert__int_rep__mach_exc__kern_return_t((kern_return_t *)(a), f) -#elif defined(__NDR_convert__int_rep__kern_return_t__defined) -#define __NDR_convert__int_rep__Reply__mach_exception_raise_state_t__RetCode__defined -#define __NDR_convert__int_rep__Reply__mach_exception_raise_state_t__RetCode(a, f) \ - __NDR_convert__int_rep__kern_return_t((kern_return_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__int_rep__Reply__mach_exception_raise_state_t__RetCode__defined */ - - -#ifndef __NDR_convert__int_rep__Reply__mach_exception_raise_state_t__flavor__defined -#if defined(__NDR_convert__int_rep__mach_exc__int__defined) -#define __NDR_convert__int_rep__Reply__mach_exception_raise_state_t__flavor__defined -#define __NDR_convert__int_rep__Reply__mach_exception_raise_state_t__flavor(a, f) \ - __NDR_convert__int_rep__mach_exc__int((int *)(a), f) -#elif defined(__NDR_convert__int_rep__int__defined) -#define __NDR_convert__int_rep__Reply__mach_exception_raise_state_t__flavor__defined -#define __NDR_convert__int_rep__Reply__mach_exception_raise_state_t__flavor(a, f) \ - __NDR_convert__int_rep__int((int *)(a), f) -#elif defined(__NDR_convert__int_rep__mach_exc__int32_t__defined) -#define __NDR_convert__int_rep__Reply__mach_exception_raise_state_t__flavor__defined -#define __NDR_convert__int_rep__Reply__mach_exception_raise_state_t__flavor(a, f) \ - __NDR_convert__int_rep__mach_exc__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__int_rep__int32_t__defined) -#define __NDR_convert__int_rep__Reply__mach_exception_raise_state_t__flavor__defined -#define __NDR_convert__int_rep__Reply__mach_exception_raise_state_t__flavor(a, f) \ - __NDR_convert__int_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__int_rep__Reply__mach_exception_raise_state_t__flavor__defined */ - - -#ifndef __NDR_convert__int_rep__Reply__mach_exception_raise_state_t__new_state__defined -#if defined(__NDR_convert__int_rep__mach_exc__thread_state_t__defined) -#define __NDR_convert__int_rep__Reply__mach_exception_raise_state_t__new_state__defined -#define __NDR_convert__int_rep__Reply__mach_exception_raise_state_t__new_state(a, f, c) \ - __NDR_convert__int_rep__mach_exc__thread_state_t((thread_state_t *)(a), f, c) -#elif defined(__NDR_convert__int_rep__thread_state_t__defined) -#define __NDR_convert__int_rep__Reply__mach_exception_raise_state_t__new_state__defined -#define __NDR_convert__int_rep__Reply__mach_exception_raise_state_t__new_state(a, f, c) \ - __NDR_convert__int_rep__thread_state_t((thread_state_t *)(a), f, c) -#elif defined(__NDR_convert__int_rep__mach_exc__natural_t__defined) -#define __NDR_convert__int_rep__Reply__mach_exception_raise_state_t__new_state__defined -#define __NDR_convert__int_rep__Reply__mach_exception_raise_state_t__new_state(a, f, c) \ - __NDR_convert__ARRAY((natural_t *)(a), f, c, __NDR_convert__int_rep__mach_exc__natural_t) -#elif defined(__NDR_convert__int_rep__natural_t__defined) -#define __NDR_convert__int_rep__Reply__mach_exception_raise_state_t__new_state__defined -#define __NDR_convert__int_rep__Reply__mach_exception_raise_state_t__new_state(a, f, c) \ - __NDR_convert__ARRAY((natural_t *)(a), f, c, __NDR_convert__int_rep__natural_t) -#elif defined(__NDR_convert__int_rep__mach_exc__uint32_t__defined) -#define __NDR_convert__int_rep__Reply__mach_exception_raise_state_t__new_state__defined -#define __NDR_convert__int_rep__Reply__mach_exception_raise_state_t__new_state(a, f, c) \ - __NDR_convert__ARRAY((uint32_t *)(a), f, c, __NDR_convert__int_rep__mach_exc__uint32_t) -#elif defined(__NDR_convert__int_rep__uint32_t__defined) -#define __NDR_convert__int_rep__Reply__mach_exception_raise_state_t__new_state__defined -#define __NDR_convert__int_rep__Reply__mach_exception_raise_state_t__new_state(a, f, c) \ - __NDR_convert__ARRAY((uint32_t *)(a), f, c, __NDR_convert__int_rep__uint32_t) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__int_rep__Reply__mach_exception_raise_state_t__new_state__defined */ - - -#ifndef __NDR_convert__int_rep__Reply__mach_exception_raise_state_t__new_stateCnt__defined -#if defined(__NDR_convert__int_rep__mach_exc__mach_msg_type_number_t__defined) -#define __NDR_convert__int_rep__Reply__mach_exception_raise_state_t__new_stateCnt__defined -#define __NDR_convert__int_rep__Reply__mach_exception_raise_state_t__new_stateCnt(a, f) \ - __NDR_convert__int_rep__mach_exc__mach_msg_type_number_t((mach_msg_type_number_t *)(a), f) -#elif defined(__NDR_convert__int_rep__mach_msg_type_number_t__defined) -#define __NDR_convert__int_rep__Reply__mach_exception_raise_state_t__new_stateCnt__defined -#define __NDR_convert__int_rep__Reply__mach_exception_raise_state_t__new_stateCnt(a, f) \ - __NDR_convert__int_rep__mach_msg_type_number_t((mach_msg_type_number_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__int_rep__Reply__mach_exception_raise_state_t__new_stateCnt__defined */ - - - -#ifndef __NDR_convert__char_rep__Reply__mach_exception_raise_state_t__flavor__defined -#if defined(__NDR_convert__char_rep__mach_exc__int__defined) -#define __NDR_convert__char_rep__Reply__mach_exception_raise_state_t__flavor__defined -#define __NDR_convert__char_rep__Reply__mach_exception_raise_state_t__flavor(a, f) \ - __NDR_convert__char_rep__mach_exc__int((int *)(a), f) -#elif defined(__NDR_convert__char_rep__int__defined) -#define __NDR_convert__char_rep__Reply__mach_exception_raise_state_t__flavor__defined -#define __NDR_convert__char_rep__Reply__mach_exception_raise_state_t__flavor(a, f) \ - __NDR_convert__char_rep__int((int *)(a), f) -#elif defined(__NDR_convert__char_rep__mach_exc__int32_t__defined) -#define __NDR_convert__char_rep__Reply__mach_exception_raise_state_t__flavor__defined -#define __NDR_convert__char_rep__Reply__mach_exception_raise_state_t__flavor(a, f) \ - __NDR_convert__char_rep__mach_exc__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__char_rep__int32_t__defined) -#define __NDR_convert__char_rep__Reply__mach_exception_raise_state_t__flavor__defined -#define __NDR_convert__char_rep__Reply__mach_exception_raise_state_t__flavor(a, f) \ - __NDR_convert__char_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__char_rep__Reply__mach_exception_raise_state_t__flavor__defined */ - - -#ifndef __NDR_convert__char_rep__Reply__mach_exception_raise_state_t__new_state__defined -#if defined(__NDR_convert__char_rep__mach_exc__thread_state_t__defined) -#define __NDR_convert__char_rep__Reply__mach_exception_raise_state_t__new_state__defined -#define __NDR_convert__char_rep__Reply__mach_exception_raise_state_t__new_state(a, f, c) \ - __NDR_convert__char_rep__mach_exc__thread_state_t((thread_state_t *)(a), f, c) -#elif defined(__NDR_convert__char_rep__thread_state_t__defined) -#define __NDR_convert__char_rep__Reply__mach_exception_raise_state_t__new_state__defined -#define __NDR_convert__char_rep__Reply__mach_exception_raise_state_t__new_state(a, f, c) \ - __NDR_convert__char_rep__thread_state_t((thread_state_t *)(a), f, c) -#elif defined(__NDR_convert__char_rep__mach_exc__natural_t__defined) -#define __NDR_convert__char_rep__Reply__mach_exception_raise_state_t__new_state__defined -#define __NDR_convert__char_rep__Reply__mach_exception_raise_state_t__new_state(a, f, c) \ - __NDR_convert__ARRAY((natural_t *)(a), f, c, __NDR_convert__char_rep__mach_exc__natural_t) -#elif defined(__NDR_convert__char_rep__natural_t__defined) -#define __NDR_convert__char_rep__Reply__mach_exception_raise_state_t__new_state__defined -#define __NDR_convert__char_rep__Reply__mach_exception_raise_state_t__new_state(a, f, c) \ - __NDR_convert__ARRAY((natural_t *)(a), f, c, __NDR_convert__char_rep__natural_t) -#elif defined(__NDR_convert__char_rep__mach_exc__uint32_t__defined) -#define __NDR_convert__char_rep__Reply__mach_exception_raise_state_t__new_state__defined -#define __NDR_convert__char_rep__Reply__mach_exception_raise_state_t__new_state(a, f, c) \ - __NDR_convert__ARRAY((uint32_t *)(a), f, c, __NDR_convert__char_rep__mach_exc__uint32_t) -#elif defined(__NDR_convert__char_rep__uint32_t__defined) -#define __NDR_convert__char_rep__Reply__mach_exception_raise_state_t__new_state__defined -#define __NDR_convert__char_rep__Reply__mach_exception_raise_state_t__new_state(a, f, c) \ - __NDR_convert__ARRAY((uint32_t *)(a), f, c, __NDR_convert__char_rep__uint32_t) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__char_rep__Reply__mach_exception_raise_state_t__new_state__defined */ - - - - -#ifndef __NDR_convert__float_rep__Reply__mach_exception_raise_state_t__flavor__defined -#if defined(__NDR_convert__float_rep__mach_exc__int__defined) -#define __NDR_convert__float_rep__Reply__mach_exception_raise_state_t__flavor__defined -#define __NDR_convert__float_rep__Reply__mach_exception_raise_state_t__flavor(a, f) \ - __NDR_convert__float_rep__mach_exc__int((int *)(a), f) -#elif defined(__NDR_convert__float_rep__int__defined) -#define __NDR_convert__float_rep__Reply__mach_exception_raise_state_t__flavor__defined -#define __NDR_convert__float_rep__Reply__mach_exception_raise_state_t__flavor(a, f) \ - __NDR_convert__float_rep__int((int *)(a), f) -#elif defined(__NDR_convert__float_rep__mach_exc__int32_t__defined) -#define __NDR_convert__float_rep__Reply__mach_exception_raise_state_t__flavor__defined -#define __NDR_convert__float_rep__Reply__mach_exception_raise_state_t__flavor(a, f) \ - __NDR_convert__float_rep__mach_exc__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__float_rep__int32_t__defined) -#define __NDR_convert__float_rep__Reply__mach_exception_raise_state_t__flavor__defined -#define __NDR_convert__float_rep__Reply__mach_exception_raise_state_t__flavor(a, f) \ - __NDR_convert__float_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__float_rep__Reply__mach_exception_raise_state_t__flavor__defined */ - - -#ifndef __NDR_convert__float_rep__Reply__mach_exception_raise_state_t__new_state__defined -#if defined(__NDR_convert__float_rep__mach_exc__thread_state_t__defined) -#define __NDR_convert__float_rep__Reply__mach_exception_raise_state_t__new_state__defined -#define __NDR_convert__float_rep__Reply__mach_exception_raise_state_t__new_state(a, f, c) \ - __NDR_convert__float_rep__mach_exc__thread_state_t((thread_state_t *)(a), f, c) -#elif defined(__NDR_convert__float_rep__thread_state_t__defined) -#define __NDR_convert__float_rep__Reply__mach_exception_raise_state_t__new_state__defined -#define __NDR_convert__float_rep__Reply__mach_exception_raise_state_t__new_state(a, f, c) \ - __NDR_convert__float_rep__thread_state_t((thread_state_t *)(a), f, c) -#elif defined(__NDR_convert__float_rep__mach_exc__natural_t__defined) -#define __NDR_convert__float_rep__Reply__mach_exception_raise_state_t__new_state__defined -#define __NDR_convert__float_rep__Reply__mach_exception_raise_state_t__new_state(a, f, c) \ - __NDR_convert__ARRAY((natural_t *)(a), f, c, __NDR_convert__float_rep__mach_exc__natural_t) -#elif defined(__NDR_convert__float_rep__natural_t__defined) -#define __NDR_convert__float_rep__Reply__mach_exception_raise_state_t__new_state__defined -#define __NDR_convert__float_rep__Reply__mach_exception_raise_state_t__new_state(a, f, c) \ - __NDR_convert__ARRAY((natural_t *)(a), f, c, __NDR_convert__float_rep__natural_t) -#elif defined(__NDR_convert__float_rep__mach_exc__uint32_t__defined) -#define __NDR_convert__float_rep__Reply__mach_exception_raise_state_t__new_state__defined -#define __NDR_convert__float_rep__Reply__mach_exception_raise_state_t__new_state(a, f, c) \ - __NDR_convert__ARRAY((uint32_t *)(a), f, c, __NDR_convert__float_rep__mach_exc__uint32_t) -#elif defined(__NDR_convert__float_rep__uint32_t__defined) -#define __NDR_convert__float_rep__Reply__mach_exception_raise_state_t__new_state__defined -#define __NDR_convert__float_rep__Reply__mach_exception_raise_state_t__new_state(a, f, c) \ - __NDR_convert__ARRAY((uint32_t *)(a), f, c, __NDR_convert__float_rep__uint32_t) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__float_rep__Reply__mach_exception_raise_state_t__new_state__defined */ - - - - -mig_internal kern_return_t __MIG_check__Reply__mach_exception_raise_state_t_OVR(__Reply__mach_exception_raise_state_t *Out0P) -{ - - typedef __Reply__mach_exception_raise_state_t __Reply; - #if __MigTypeCheck - unsigned int msgh_size; - #endif /* __MigTypeCheck */ - - if (Out0P->Head.msgh_id != 2506) { - if (Out0P->Head.msgh_id == MACH_NOTIFY_SEND_ONCE) - { return MIG_SERVER_DIED; } - else - { return MIG_REPLY_MISMATCH; } - } - - #if __MigTypeCheck - msgh_size = Out0P->Head.msgh_size; - - if ((Out0P->Head.msgh_bits & MACH_MSGH_BITS_COMPLEX) || - ((msgh_size > (mach_msg_size_t)sizeof(__Reply) || msgh_size < (mach_msg_size_t)(sizeof(__Reply) - 576)) && - (msgh_size != (mach_msg_size_t)sizeof(mig_reply_error_t) || - Out0P->RetCode == KERN_SUCCESS))) - { return MIG_TYPE_ERROR ; } - #endif /* __MigTypeCheck */ - - if (Out0P->RetCode != KERN_SUCCESS) { - #ifdef __NDR_convert__mig_reply_error_t__defined - __NDR_convert__mig_reply_error_t((mig_reply_error_t *)Out0P); - #endif /* __NDR_convert__mig_reply_error_t__defined */ - return ((mig_reply_error_t *)Out0P)->RetCode; - } - - #if defined(__NDR_convert__int_rep__Reply__mach_exception_raise_state_t__new_stateCnt__defined) - if (Out0P->NDR.int_rep != NDR_record.int_rep) - __NDR_convert__int_rep__Reply__mach_exception_raise_state_t__new_stateCnt(&Out0P->new_stateCnt, Out0P->NDR.int_rep); - #endif /* __NDR_convert__int_rep__Reply__mach_exception_raise_state_t__new_stateCnt__defined */ - #if __MigTypeCheck - if ( Out0P->new_stateCnt > 144 ) - return MIG_TYPE_ERROR; - if (((msgh_size - (mach_msg_size_t)(sizeof(__Reply) - 576)) / 4 != Out0P->new_stateCnt) || - (msgh_size != (mach_msg_size_t)(sizeof(__Reply) - 576) + Out0P->new_stateCnt * 4)) - { return MIG_TYPE_ERROR ; } - #endif /* __MigTypeCheck */ - - #if defined(__NDR_convert__int_rep__Reply__mach_exception_raise_state_t__RetCode__defined) || \ - defined(__NDR_convert__int_rep__Reply__mach_exception_raise_state_t__flavor__defined) || \ - defined(__NDR_convert__int_rep__Reply__mach_exception_raise_state_t__new_state__defined) || \ - defined(__NDR_convert__int_rep__Reply__mach_exception_raise_state_t__new_stateCnt__defined) - if (Out0P->NDR.int_rep != NDR_record.int_rep) { - #if defined(__NDR_convert__int_rep__Reply__mach_exception_raise_state_t__RetCode__defined) - __NDR_convert__int_rep__Reply__mach_exception_raise_state_t__RetCode(&Out0P->RetCode, Out0P->NDR.int_rep); - #endif /* __NDR_convert__int_rep__Reply__mach_exception_raise_state_t__RetCode__defined */ - #if defined(__NDR_convert__int_rep__Reply__mach_exception_raise_state_t__flavor__defined) - __NDR_convert__int_rep__Reply__mach_exception_raise_state_t__flavor(&Out0P->flavor, Out0P->NDR.int_rep); - #endif /* __NDR_convert__int_rep__Reply__mach_exception_raise_state_t__flavor__defined */ - #if defined(__NDR_convert__int_rep__Reply__mach_exception_raise_state_t__new_state__defined) - __NDR_convert__int_rep__Reply__mach_exception_raise_state_t__new_state(&Out0P->new_state, Out0P->NDR.int_rep, Out0P->new_stateCnt); - #endif /* __NDR_convert__int_rep__Reply__mach_exception_raise_state_t__new_state__defined */ - } - #endif /* defined(__NDR_convert__int_rep...) */ - - #if 0 || \ - defined(__NDR_convert__char_rep__Reply__mach_exception_raise_state_t__flavor__defined) || \ - defined(__NDR_convert__char_rep__Reply__mach_exception_raise_state_t__new_state__defined) || \ - 0 - if (Out0P->NDR.char_rep != NDR_record.char_rep) { - #if defined(__NDR_convert__char_rep__Reply__mach_exception_raise_state_t__flavor__defined) - __NDR_convert__char_rep__Reply__mach_exception_raise_state_t__flavor(&Out0P->flavor, Out0P->NDR.char_rep); - #endif /* __NDR_convert__char_rep__Reply__mach_exception_raise_state_t__flavor__defined */ - #if defined(__NDR_convert__char_rep__Reply__mach_exception_raise_state_t__new_state__defined) - __NDR_convert__char_rep__Reply__mach_exception_raise_state_t__new_state(&Out0P->new_state, Out0P->NDR.char_rep, Out0P->new_stateCnt); - #endif /* __NDR_convert__char_rep__Reply__mach_exception_raise_state_t__new_state__defined */ - } - #endif /* defined(__NDR_convert__char_rep...) */ - - #if 0 || \ - defined(__NDR_convert__float_rep__Reply__mach_exception_raise_state_t__flavor__defined) || \ - defined(__NDR_convert__float_rep__Reply__mach_exception_raise_state_t__new_state__defined) || \ - 0 - if (Out0P->NDR.float_rep != NDR_record.float_rep) { - #if defined(__NDR_convert__float_rep__Reply__mach_exception_raise_state_t__flavor__defined) - __NDR_convert__float_rep__Reply__mach_exception_raise_state_t__flavor(&Out0P->flavor, Out0P->NDR.float_rep); - #endif /* __NDR_convert__float_rep__Reply__mach_exception_raise_state_t__flavor__defined */ - #if defined(__NDR_convert__float_rep__Reply__mach_exception_raise_state_t__new_state__defined) - __NDR_convert__float_rep__Reply__mach_exception_raise_state_t__new_state(&Out0P->new_state, Out0P->NDR.float_rep, Out0P->new_stateCnt); - #endif /* __NDR_convert__float_rep__Reply__mach_exception_raise_state_t__new_state__defined */ - } - #endif /* defined(__NDR_convert__float_rep...) */ - - return MACH_MSG_SUCCESS; -} -#endif /* !defined(__MIG_check__Reply__mach_exception_raise_state_t__defined) */ -#endif /* __MIG_check__Reply__mach_exc_subsystem__ */ -#endif /* ( __MigTypeCheck || __NDR_convert__ ) */ - - -/* Routine mach_exception_raise_state_OVR */ -mig_external kern_return_t mach_exception_raise_state_OVR -( - mach_port_t exception_port, - exception_type_t exception, - const mach_exception_data_t code, - mach_msg_type_number_t codeCnt, - int *flavor, - const thread_state_t old_state, - mach_msg_type_number_t old_stateCnt, - thread_state_t new_state, - mach_msg_type_number_t *new_stateCnt -) -{ - - #ifdef __MigPackStructs - #pragma pack(4) - #endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - exception_type_t exception; - mach_msg_type_number_t codeCnt; - int64_t code[2]; - int flavor; - mach_msg_type_number_t old_stateCnt; - natural_t old_state[144]; - } Request; - #ifdef __MigPackStructs - #pragma pack() - #endif - - #ifdef __MigPackStructs - #pragma pack(4) - #endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - kern_return_t RetCode; - int flavor; - mach_msg_type_number_t new_stateCnt; - natural_t new_state[144]; - mach_msg_trailer_t trailer; - } Reply; - #ifdef __MigPackStructs - #pragma pack() - #endif - - #ifdef __MigPackStructs - #pragma pack(4) - #endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - kern_return_t RetCode; - int flavor; - mach_msg_type_number_t new_stateCnt; - natural_t new_state[144]; - } __Reply; - #ifdef __MigPackStructs - #pragma pack() - #endif - /* - * typedef struct { - * mach_msg_header_t Head; - * NDR_record_t NDR; - * kern_return_t RetCode; - * } mig_reply_error_t; - */ - - union { - Request In; - Reply Out; - } Mess; - - Request *InP = &Mess.In; - Reply *Out0P = &Mess.Out; - - mach_msg_return_t msg_result; - unsigned int msgh_size; - unsigned int msgh_size_delta; - - - #ifdef __MIG_check__Reply__mach_exception_raise_state_t__defined - kern_return_t check_result; - #endif /* __MIG_check__Reply__mach_exception_raise_state_t__defined */ - - __DeclareSendRpc(2406, "mach_exception_raise_state_OVR") - - InP->NDR = NDR_record; - - InP->exception = exception; - - if (codeCnt > 2) { - { return MIG_ARRAY_TOO_LARGE; } - } - (void)memcpy((char *) InP->code, (const char *) code, 8 * codeCnt); - - InP->codeCnt = codeCnt; - - msgh_size_delta = (8 * codeCnt); - msgh_size = (mach_msg_size_t)(sizeof(Request) - 592) + msgh_size_delta; - InP = (Request *) ((pointer_t) InP + msgh_size_delta - 16); - - InP->flavor = *flavor; - - if (old_stateCnt > 144) { - { return MIG_ARRAY_TOO_LARGE; } - } - (void)memcpy((char *) InP->old_state, (const char *) old_state, 4 * old_stateCnt); - - InP->old_stateCnt = old_stateCnt; - - msgh_size += (4 * old_stateCnt); - InP = &Mess.In; - InP->Head.msgh_bits = - MACH_MSGH_BITS(19, MACH_MSG_TYPE_MAKE_SEND_ONCE); - /* msgh_size passed as argument */ - InP->Head.msgh_request_port = exception_port; - InP->Head.msgh_reply_port = mig_get_reply_port(); - InP->Head.msgh_id = 2406; - - __BeforeSendRpc(2406, "mach_exception_raise_state_OVR") - msg_result = mach_msg(&InP->Head, MACH_SEND_MSG|MACH_RCV_MSG|MACH_MSG_OPTION_NONE, msgh_size, (mach_msg_size_t)sizeof(Reply), InP->Head.msgh_reply_port, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL); - __AfterSendRpc(2406, "mach_exception_raise_state_OVR") - if (msg_result != MACH_MSG_SUCCESS) { - __MachMsgErrorWithoutTimeout(msg_result); - { return msg_result; } - } - - - #if defined(__MIG_check__Reply__mach_exception_raise_state_t__defined) - check_result = __MIG_check__Reply__mach_exception_raise_state_t_OVR((__Reply__mach_exception_raise_state_t *)Out0P); - if (check_result != MACH_MSG_SUCCESS) - { return check_result; } - #endif /* defined(__MIG_check__Reply__mach_exception_raise_state_t__defined) */ - - *flavor = Out0P->flavor; - - if (Out0P->new_stateCnt > 144) { - (void)memcpy((char *) new_state, (const char *) Out0P->new_state, 4 * 144); - *new_stateCnt = Out0P->new_stateCnt; - { return MIG_ARRAY_TOO_LARGE; } - } - (void)memcpy((char *) new_state, (const char *) Out0P->new_state, 4 * Out0P->new_stateCnt); - - *new_stateCnt = Out0P->new_stateCnt; - - return KERN_SUCCESS; -} - -#if ( __MigTypeCheck || __NDR_convert__ ) -#if __MIG_check__Reply__mach_exc_subsystem__ -#if !defined(__MIG_check__Reply__mach_exception_raise_state_identity_t__defined) -#define __MIG_check__Reply__mach_exception_raise_state_identity_t__defined -#ifndef __NDR_convert__int_rep__Reply__mach_exception_raise_state_identity_t__RetCode__defined -#if defined(__NDR_convert__int_rep__mach_exc__kern_return_t__defined) -#define __NDR_convert__int_rep__Reply__mach_exception_raise_state_identity_t__RetCode__defined -#define __NDR_convert__int_rep__Reply__mach_exception_raise_state_identity_t__RetCode(a, f) \ - __NDR_convert__int_rep__mach_exc__kern_return_t((kern_return_t *)(a), f) -#elif defined(__NDR_convert__int_rep__kern_return_t__defined) -#define __NDR_convert__int_rep__Reply__mach_exception_raise_state_identity_t__RetCode__defined -#define __NDR_convert__int_rep__Reply__mach_exception_raise_state_identity_t__RetCode(a, f) \ - __NDR_convert__int_rep__kern_return_t((kern_return_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__int_rep__Reply__mach_exception_raise_state_identity_t__RetCode__defined */ - - -#ifndef __NDR_convert__int_rep__Reply__mach_exception_raise_state_identity_t__flavor__defined -#if defined(__NDR_convert__int_rep__mach_exc__int__defined) -#define __NDR_convert__int_rep__Reply__mach_exception_raise_state_identity_t__flavor__defined -#define __NDR_convert__int_rep__Reply__mach_exception_raise_state_identity_t__flavor(a, f) \ - __NDR_convert__int_rep__mach_exc__int((int *)(a), f) -#elif defined(__NDR_convert__int_rep__int__defined) -#define __NDR_convert__int_rep__Reply__mach_exception_raise_state_identity_t__flavor__defined -#define __NDR_convert__int_rep__Reply__mach_exception_raise_state_identity_t__flavor(a, f) \ - __NDR_convert__int_rep__int((int *)(a), f) -#elif defined(__NDR_convert__int_rep__mach_exc__int32_t__defined) -#define __NDR_convert__int_rep__Reply__mach_exception_raise_state_identity_t__flavor__defined -#define __NDR_convert__int_rep__Reply__mach_exception_raise_state_identity_t__flavor(a, f) \ - __NDR_convert__int_rep__mach_exc__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__int_rep__int32_t__defined) -#define __NDR_convert__int_rep__Reply__mach_exception_raise_state_identity_t__flavor__defined -#define __NDR_convert__int_rep__Reply__mach_exception_raise_state_identity_t__flavor(a, f) \ - __NDR_convert__int_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__int_rep__Reply__mach_exception_raise_state_identity_t__flavor__defined */ - - -#ifndef __NDR_convert__int_rep__Reply__mach_exception_raise_state_identity_t__new_state__defined -#if defined(__NDR_convert__int_rep__mach_exc__thread_state_t__defined) -#define __NDR_convert__int_rep__Reply__mach_exception_raise_state_identity_t__new_state__defined -#define __NDR_convert__int_rep__Reply__mach_exception_raise_state_identity_t__new_state(a, f, c) \ - __NDR_convert__int_rep__mach_exc__thread_state_t((thread_state_t *)(a), f, c) -#elif defined(__NDR_convert__int_rep__thread_state_t__defined) -#define __NDR_convert__int_rep__Reply__mach_exception_raise_state_identity_t__new_state__defined -#define __NDR_convert__int_rep__Reply__mach_exception_raise_state_identity_t__new_state(a, f, c) \ - __NDR_convert__int_rep__thread_state_t((thread_state_t *)(a), f, c) -#elif defined(__NDR_convert__int_rep__mach_exc__natural_t__defined) -#define __NDR_convert__int_rep__Reply__mach_exception_raise_state_identity_t__new_state__defined -#define __NDR_convert__int_rep__Reply__mach_exception_raise_state_identity_t__new_state(a, f, c) \ - __NDR_convert__ARRAY((natural_t *)(a), f, c, __NDR_convert__int_rep__mach_exc__natural_t) -#elif defined(__NDR_convert__int_rep__natural_t__defined) -#define __NDR_convert__int_rep__Reply__mach_exception_raise_state_identity_t__new_state__defined -#define __NDR_convert__int_rep__Reply__mach_exception_raise_state_identity_t__new_state(a, f, c) \ - __NDR_convert__ARRAY((natural_t *)(a), f, c, __NDR_convert__int_rep__natural_t) -#elif defined(__NDR_convert__int_rep__mach_exc__uint32_t__defined) -#define __NDR_convert__int_rep__Reply__mach_exception_raise_state_identity_t__new_state__defined -#define __NDR_convert__int_rep__Reply__mach_exception_raise_state_identity_t__new_state(a, f, c) \ - __NDR_convert__ARRAY((uint32_t *)(a), f, c, __NDR_convert__int_rep__mach_exc__uint32_t) -#elif defined(__NDR_convert__int_rep__uint32_t__defined) -#define __NDR_convert__int_rep__Reply__mach_exception_raise_state_identity_t__new_state__defined -#define __NDR_convert__int_rep__Reply__mach_exception_raise_state_identity_t__new_state(a, f, c) \ - __NDR_convert__ARRAY((uint32_t *)(a), f, c, __NDR_convert__int_rep__uint32_t) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__int_rep__Reply__mach_exception_raise_state_identity_t__new_state__defined */ - - -#ifndef __NDR_convert__int_rep__Reply__mach_exception_raise_state_identity_t__new_stateCnt__defined -#if defined(__NDR_convert__int_rep__mach_exc__mach_msg_type_number_t__defined) -#define __NDR_convert__int_rep__Reply__mach_exception_raise_state_identity_t__new_stateCnt__defined -#define __NDR_convert__int_rep__Reply__mach_exception_raise_state_identity_t__new_stateCnt(a, f) \ - __NDR_convert__int_rep__mach_exc__mach_msg_type_number_t((mach_msg_type_number_t *)(a), f) -#elif defined(__NDR_convert__int_rep__mach_msg_type_number_t__defined) -#define __NDR_convert__int_rep__Reply__mach_exception_raise_state_identity_t__new_stateCnt__defined -#define __NDR_convert__int_rep__Reply__mach_exception_raise_state_identity_t__new_stateCnt(a, f) \ - __NDR_convert__int_rep__mach_msg_type_number_t((mach_msg_type_number_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__int_rep__Reply__mach_exception_raise_state_identity_t__new_stateCnt__defined */ - - - -#ifndef __NDR_convert__char_rep__Reply__mach_exception_raise_state_identity_t__flavor__defined -#if defined(__NDR_convert__char_rep__mach_exc__int__defined) -#define __NDR_convert__char_rep__Reply__mach_exception_raise_state_identity_t__flavor__defined -#define __NDR_convert__char_rep__Reply__mach_exception_raise_state_identity_t__flavor(a, f) \ - __NDR_convert__char_rep__mach_exc__int((int *)(a), f) -#elif defined(__NDR_convert__char_rep__int__defined) -#define __NDR_convert__char_rep__Reply__mach_exception_raise_state_identity_t__flavor__defined -#define __NDR_convert__char_rep__Reply__mach_exception_raise_state_identity_t__flavor(a, f) \ - __NDR_convert__char_rep__int((int *)(a), f) -#elif defined(__NDR_convert__char_rep__mach_exc__int32_t__defined) -#define __NDR_convert__char_rep__Reply__mach_exception_raise_state_identity_t__flavor__defined -#define __NDR_convert__char_rep__Reply__mach_exception_raise_state_identity_t__flavor(a, f) \ - __NDR_convert__char_rep__mach_exc__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__char_rep__int32_t__defined) -#define __NDR_convert__char_rep__Reply__mach_exception_raise_state_identity_t__flavor__defined -#define __NDR_convert__char_rep__Reply__mach_exception_raise_state_identity_t__flavor(a, f) \ - __NDR_convert__char_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__char_rep__Reply__mach_exception_raise_state_identity_t__flavor__defined */ - - -#ifndef __NDR_convert__char_rep__Reply__mach_exception_raise_state_identity_t__new_state__defined -#if defined(__NDR_convert__char_rep__mach_exc__thread_state_t__defined) -#define __NDR_convert__char_rep__Reply__mach_exception_raise_state_identity_t__new_state__defined -#define __NDR_convert__char_rep__Reply__mach_exception_raise_state_identity_t__new_state(a, f, c) \ - __NDR_convert__char_rep__mach_exc__thread_state_t((thread_state_t *)(a), f, c) -#elif defined(__NDR_convert__char_rep__thread_state_t__defined) -#define __NDR_convert__char_rep__Reply__mach_exception_raise_state_identity_t__new_state__defined -#define __NDR_convert__char_rep__Reply__mach_exception_raise_state_identity_t__new_state(a, f, c) \ - __NDR_convert__char_rep__thread_state_t((thread_state_t *)(a), f, c) -#elif defined(__NDR_convert__char_rep__mach_exc__natural_t__defined) -#define __NDR_convert__char_rep__Reply__mach_exception_raise_state_identity_t__new_state__defined -#define __NDR_convert__char_rep__Reply__mach_exception_raise_state_identity_t__new_state(a, f, c) \ - __NDR_convert__ARRAY((natural_t *)(a), f, c, __NDR_convert__char_rep__mach_exc__natural_t) -#elif defined(__NDR_convert__char_rep__natural_t__defined) -#define __NDR_convert__char_rep__Reply__mach_exception_raise_state_identity_t__new_state__defined -#define __NDR_convert__char_rep__Reply__mach_exception_raise_state_identity_t__new_state(a, f, c) \ - __NDR_convert__ARRAY((natural_t *)(a), f, c, __NDR_convert__char_rep__natural_t) -#elif defined(__NDR_convert__char_rep__mach_exc__uint32_t__defined) -#define __NDR_convert__char_rep__Reply__mach_exception_raise_state_identity_t__new_state__defined -#define __NDR_convert__char_rep__Reply__mach_exception_raise_state_identity_t__new_state(a, f, c) \ - __NDR_convert__ARRAY((uint32_t *)(a), f, c, __NDR_convert__char_rep__mach_exc__uint32_t) -#elif defined(__NDR_convert__char_rep__uint32_t__defined) -#define __NDR_convert__char_rep__Reply__mach_exception_raise_state_identity_t__new_state__defined -#define __NDR_convert__char_rep__Reply__mach_exception_raise_state_identity_t__new_state(a, f, c) \ - __NDR_convert__ARRAY((uint32_t *)(a), f, c, __NDR_convert__char_rep__uint32_t) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__char_rep__Reply__mach_exception_raise_state_identity_t__new_state__defined */ - - - - -#ifndef __NDR_convert__float_rep__Reply__mach_exception_raise_state_identity_t__flavor__defined -#if defined(__NDR_convert__float_rep__mach_exc__int__defined) -#define __NDR_convert__float_rep__Reply__mach_exception_raise_state_identity_t__flavor__defined -#define __NDR_convert__float_rep__Reply__mach_exception_raise_state_identity_t__flavor(a, f) \ - __NDR_convert__float_rep__mach_exc__int((int *)(a), f) -#elif defined(__NDR_convert__float_rep__int__defined) -#define __NDR_convert__float_rep__Reply__mach_exception_raise_state_identity_t__flavor__defined -#define __NDR_convert__float_rep__Reply__mach_exception_raise_state_identity_t__flavor(a, f) \ - __NDR_convert__float_rep__int((int *)(a), f) -#elif defined(__NDR_convert__float_rep__mach_exc__int32_t__defined) -#define __NDR_convert__float_rep__Reply__mach_exception_raise_state_identity_t__flavor__defined -#define __NDR_convert__float_rep__Reply__mach_exception_raise_state_identity_t__flavor(a, f) \ - __NDR_convert__float_rep__mach_exc__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__float_rep__int32_t__defined) -#define __NDR_convert__float_rep__Reply__mach_exception_raise_state_identity_t__flavor__defined -#define __NDR_convert__float_rep__Reply__mach_exception_raise_state_identity_t__flavor(a, f) \ - __NDR_convert__float_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__float_rep__Reply__mach_exception_raise_state_identity_t__flavor__defined */ - - -#ifndef __NDR_convert__float_rep__Reply__mach_exception_raise_state_identity_t__new_state__defined -#if defined(__NDR_convert__float_rep__mach_exc__thread_state_t__defined) -#define __NDR_convert__float_rep__Reply__mach_exception_raise_state_identity_t__new_state__defined -#define __NDR_convert__float_rep__Reply__mach_exception_raise_state_identity_t__new_state(a, f, c) \ - __NDR_convert__float_rep__mach_exc__thread_state_t((thread_state_t *)(a), f, c) -#elif defined(__NDR_convert__float_rep__thread_state_t__defined) -#define __NDR_convert__float_rep__Reply__mach_exception_raise_state_identity_t__new_state__defined -#define __NDR_convert__float_rep__Reply__mach_exception_raise_state_identity_t__new_state(a, f, c) \ - __NDR_convert__float_rep__thread_state_t((thread_state_t *)(a), f, c) -#elif defined(__NDR_convert__float_rep__mach_exc__natural_t__defined) -#define __NDR_convert__float_rep__Reply__mach_exception_raise_state_identity_t__new_state__defined -#define __NDR_convert__float_rep__Reply__mach_exception_raise_state_identity_t__new_state(a, f, c) \ - __NDR_convert__ARRAY((natural_t *)(a), f, c, __NDR_convert__float_rep__mach_exc__natural_t) -#elif defined(__NDR_convert__float_rep__natural_t__defined) -#define __NDR_convert__float_rep__Reply__mach_exception_raise_state_identity_t__new_state__defined -#define __NDR_convert__float_rep__Reply__mach_exception_raise_state_identity_t__new_state(a, f, c) \ - __NDR_convert__ARRAY((natural_t *)(a), f, c, __NDR_convert__float_rep__natural_t) -#elif defined(__NDR_convert__float_rep__mach_exc__uint32_t__defined) -#define __NDR_convert__float_rep__Reply__mach_exception_raise_state_identity_t__new_state__defined -#define __NDR_convert__float_rep__Reply__mach_exception_raise_state_identity_t__new_state(a, f, c) \ - __NDR_convert__ARRAY((uint32_t *)(a), f, c, __NDR_convert__float_rep__mach_exc__uint32_t) -#elif defined(__NDR_convert__float_rep__uint32_t__defined) -#define __NDR_convert__float_rep__Reply__mach_exception_raise_state_identity_t__new_state__defined -#define __NDR_convert__float_rep__Reply__mach_exception_raise_state_identity_t__new_state(a, f, c) \ - __NDR_convert__ARRAY((uint32_t *)(a), f, c, __NDR_convert__float_rep__uint32_t) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__float_rep__Reply__mach_exception_raise_state_identity_t__new_state__defined */ - - - - -mig_internal kern_return_t __MIG_check__Reply__mach_exception_raise_state_identity_t(__Reply__mach_exception_raise_state_identity_t *Out0P) -{ - - typedef __Reply__mach_exception_raise_state_identity_t __Reply; - #if __MigTypeCheck - unsigned int msgh_size; - #endif /* __MigTypeCheck */ - - if (Out0P->Head.msgh_id != 2507) { - if (Out0P->Head.msgh_id == MACH_NOTIFY_SEND_ONCE) - { return MIG_SERVER_DIED; } - else - { return MIG_REPLY_MISMATCH; } - } - - #if __MigTypeCheck - msgh_size = Out0P->Head.msgh_size; - - if ((Out0P->Head.msgh_bits & MACH_MSGH_BITS_COMPLEX) || - ((msgh_size > (mach_msg_size_t)sizeof(__Reply) || msgh_size < (mach_msg_size_t)(sizeof(__Reply) - 576)) && - (msgh_size != (mach_msg_size_t)sizeof(mig_reply_error_t) || - Out0P->RetCode == KERN_SUCCESS))) - { return MIG_TYPE_ERROR ; } - #endif /* __MigTypeCheck */ - - if (Out0P->RetCode != KERN_SUCCESS) { - #ifdef __NDR_convert__mig_reply_error_t__defined - __NDR_convert__mig_reply_error_t((mig_reply_error_t *)Out0P); - #endif /* __NDR_convert__mig_reply_error_t__defined */ - return ((mig_reply_error_t *)Out0P)->RetCode; - } - - #if defined(__NDR_convert__int_rep__Reply__mach_exception_raise_state_identity_t__new_stateCnt__defined) - if (Out0P->NDR.int_rep != NDR_record.int_rep) - __NDR_convert__int_rep__Reply__mach_exception_raise_state_identity_t__new_stateCnt(&Out0P->new_stateCnt, Out0P->NDR.int_rep); - #endif /* __NDR_convert__int_rep__Reply__mach_exception_raise_state_identity_t__new_stateCnt__defined */ - #if __MigTypeCheck - if ( Out0P->new_stateCnt > 144 ) - return MIG_TYPE_ERROR; - if (((msgh_size - (mach_msg_size_t)(sizeof(__Reply) - 576)) / 4 != Out0P->new_stateCnt) || - (msgh_size != (mach_msg_size_t)(sizeof(__Reply) - 576) + Out0P->new_stateCnt * 4)) - { return MIG_TYPE_ERROR ; } - #endif /* __MigTypeCheck */ - - #if defined(__NDR_convert__int_rep__Reply__mach_exception_raise_state_identity_t__RetCode__defined) || \ - defined(__NDR_convert__int_rep__Reply__mach_exception_raise_state_identity_t__flavor__defined) || \ - defined(__NDR_convert__int_rep__Reply__mach_exception_raise_state_identity_t__new_state__defined) || \ - defined(__NDR_convert__int_rep__Reply__mach_exception_raise_state_identity_t__new_stateCnt__defined) - if (Out0P->NDR.int_rep != NDR_record.int_rep) { - #if defined(__NDR_convert__int_rep__Reply__mach_exception_raise_state_identity_t__RetCode__defined) - __NDR_convert__int_rep__Reply__mach_exception_raise_state_identity_t__RetCode(&Out0P->RetCode, Out0P->NDR.int_rep); - #endif /* __NDR_convert__int_rep__Reply__mach_exception_raise_state_identity_t__RetCode__defined */ - #if defined(__NDR_convert__int_rep__Reply__mach_exception_raise_state_identity_t__flavor__defined) - __NDR_convert__int_rep__Reply__mach_exception_raise_state_identity_t__flavor(&Out0P->flavor, Out0P->NDR.int_rep); - #endif /* __NDR_convert__int_rep__Reply__mach_exception_raise_state_identity_t__flavor__defined */ - #if defined(__NDR_convert__int_rep__Reply__mach_exception_raise_state_identity_t__new_state__defined) - __NDR_convert__int_rep__Reply__mach_exception_raise_state_identity_t__new_state(&Out0P->new_state, Out0P->NDR.int_rep, Out0P->new_stateCnt); - #endif /* __NDR_convert__int_rep__Reply__mach_exception_raise_state_identity_t__new_state__defined */ - } - #endif /* defined(__NDR_convert__int_rep...) */ - - #if 0 || \ - defined(__NDR_convert__char_rep__Reply__mach_exception_raise_state_identity_t__flavor__defined) || \ - defined(__NDR_convert__char_rep__Reply__mach_exception_raise_state_identity_t__new_state__defined) || \ - 0 - if (Out0P->NDR.char_rep != NDR_record.char_rep) { - #if defined(__NDR_convert__char_rep__Reply__mach_exception_raise_state_identity_t__flavor__defined) - __NDR_convert__char_rep__Reply__mach_exception_raise_state_identity_t__flavor(&Out0P->flavor, Out0P->NDR.char_rep); - #endif /* __NDR_convert__char_rep__Reply__mach_exception_raise_state_identity_t__flavor__defined */ - #if defined(__NDR_convert__char_rep__Reply__mach_exception_raise_state_identity_t__new_state__defined) - __NDR_convert__char_rep__Reply__mach_exception_raise_state_identity_t__new_state(&Out0P->new_state, Out0P->NDR.char_rep, Out0P->new_stateCnt); - #endif /* __NDR_convert__char_rep__Reply__mach_exception_raise_state_identity_t__new_state__defined */ - } - #endif /* defined(__NDR_convert__char_rep...) */ - - #if 0 || \ - defined(__NDR_convert__float_rep__Reply__mach_exception_raise_state_identity_t__flavor__defined) || \ - defined(__NDR_convert__float_rep__Reply__mach_exception_raise_state_identity_t__new_state__defined) || \ - 0 - if (Out0P->NDR.float_rep != NDR_record.float_rep) { - #if defined(__NDR_convert__float_rep__Reply__mach_exception_raise_state_identity_t__flavor__defined) - __NDR_convert__float_rep__Reply__mach_exception_raise_state_identity_t__flavor(&Out0P->flavor, Out0P->NDR.float_rep); - #endif /* __NDR_convert__float_rep__Reply__mach_exception_raise_state_identity_t__flavor__defined */ - #if defined(__NDR_convert__float_rep__Reply__mach_exception_raise_state_identity_t__new_state__defined) - __NDR_convert__float_rep__Reply__mach_exception_raise_state_identity_t__new_state(&Out0P->new_state, Out0P->NDR.float_rep, Out0P->new_stateCnt); - #endif /* __NDR_convert__float_rep__Reply__mach_exception_raise_state_identity_t__new_state__defined */ - } - #endif /* defined(__NDR_convert__float_rep...) */ - - return MACH_MSG_SUCCESS; -} -#endif /* !defined(__MIG_check__Reply__mach_exception_raise_state_identity_t__defined) */ -#endif /* __MIG_check__Reply__mach_exc_subsystem__ */ -#endif /* ( __MigTypeCheck || __NDR_convert__ ) */ - - -/* Routine mach_exception_raise_state_identity_OVR */ -mig_external kern_return_t mach_exception_raise_state_identity_OVR -( - mach_port_t exception_port, - mach_port_t thread, - mach_port_t task, - exception_type_t exception, - mach_exception_data_t code, - mach_msg_type_number_t codeCnt, - int *flavor, - thread_state_t old_state, - mach_msg_type_number_t old_stateCnt, - thread_state_t new_state, - mach_msg_type_number_t *new_stateCnt -) -{ - - #ifdef __MigPackStructs - #pragma pack(4) - #endif - typedef struct { - mach_msg_header_t Head; - /* start of the kernel processed data */ - mach_msg_body_t msgh_body; - mach_msg_port_descriptor_t thread; - mach_msg_port_descriptor_t task; - /* end of the kernel processed data */ - NDR_record_t NDR; - exception_type_t exception; - mach_msg_type_number_t codeCnt; - int64_t code[2]; - int flavor; - mach_msg_type_number_t old_stateCnt; - natural_t old_state[144]; - } Request; - #ifdef __MigPackStructs - #pragma pack() - #endif - - #ifdef __MigPackStructs - #pragma pack(4) - #endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - kern_return_t RetCode; - int flavor; - mach_msg_type_number_t new_stateCnt; - natural_t new_state[144]; - mach_msg_trailer_t trailer; - } Reply; - #ifdef __MigPackStructs - #pragma pack() - #endif - - #ifdef __MigPackStructs - #pragma pack(4) - #endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - kern_return_t RetCode; - int flavor; - mach_msg_type_number_t new_stateCnt; - natural_t new_state[144]; - } __Reply; - #ifdef __MigPackStructs - #pragma pack() - #endif - /* - * typedef struct { - * mach_msg_header_t Head; - * NDR_record_t NDR; - * kern_return_t RetCode; - * } mig_reply_error_t; - */ - - union { - Request In; - Reply Out; - } Mess; - - Request *InP = &Mess.In; - Reply *Out0P = &Mess.Out; - - mach_msg_return_t msg_result; - unsigned int msgh_size; - unsigned int msgh_size_delta; - - - #ifdef __MIG_check__Reply__mach_exception_raise_state_identity_t__defined - kern_return_t check_result; - #endif /* __MIG_check__Reply__mach_exception_raise_state_identity_t__defined */ - - __DeclareSendRpc(2407, "mach_exception_raise_state_identity_OVR") - - #if UseStaticTemplates - const static mach_msg_port_descriptor_t threadTemplate = { - /* name = */ MACH_PORT_NULL, - /* pad1 = */ 0, - /* pad2 = */ 0, - /* disp = */ 19, - /* type = */ MACH_MSG_PORT_DESCRIPTOR, - }; - #endif /* UseStaticTemplates */ - - #if UseStaticTemplates - const static mach_msg_port_descriptor_t taskTemplate = { - /* name = */ MACH_PORT_NULL, - /* pad1 = */ 0, - /* pad2 = */ 0, - /* disp = */ 19, - /* type = */ MACH_MSG_PORT_DESCRIPTOR, - }; - #endif /* UseStaticTemplates */ - - InP->msgh_body.msgh_descriptor_count = 2; - #if UseStaticTemplates - InP->thread = threadTemplate; - InP->thread.name = thread; - #else /* UseStaticTemplates */ - InP->thread.name = thread; - InP->thread.disposition = 19; - InP->thread.type = MACH_MSG_PORT_DESCRIPTOR; - #endif /* UseStaticTemplates */ - - #if UseStaticTemplates - InP->task = taskTemplate; - InP->task.name = task; - #else /* UseStaticTemplates */ - InP->task.name = task; - InP->task.disposition = 19; - InP->task.type = MACH_MSG_PORT_DESCRIPTOR; - #endif /* UseStaticTemplates */ - - InP->NDR = NDR_record; - - InP->exception = exception; - - if (codeCnt > 2) { - { return MIG_ARRAY_TOO_LARGE; } - } - (void)memcpy((char *) InP->code, (const char *) code, 8 * codeCnt); - - InP->codeCnt = codeCnt; - - msgh_size_delta = (8 * codeCnt); - msgh_size = (mach_msg_size_t)(sizeof(Request) - 592) + msgh_size_delta; - InP = (Request *) ((pointer_t) InP + msgh_size_delta - 16); - - InP->flavor = *flavor; - - if (old_stateCnt > 144) { - { return MIG_ARRAY_TOO_LARGE; } - } - (void)memcpy((char *) InP->old_state, (const char *) old_state, 4 * old_stateCnt); - - InP->old_stateCnt = old_stateCnt; - - msgh_size += (4 * old_stateCnt); - InP = &Mess.In; - InP->Head.msgh_bits = MACH_MSGH_BITS_COMPLEX| - MACH_MSGH_BITS(19, MACH_MSG_TYPE_MAKE_SEND_ONCE); - /* msgh_size passed as argument */ - InP->Head.msgh_request_port = exception_port; - InP->Head.msgh_reply_port = mig_get_reply_port(); - InP->Head.msgh_id = 2407; - - __BeforeSendRpc(2407, "mach_exception_raise_state_identity_OVR") - msg_result = mach_msg(&InP->Head, MACH_SEND_MSG|MACH_RCV_MSG|MACH_MSG_OPTION_NONE, msgh_size, (mach_msg_size_t)sizeof(Reply), InP->Head.msgh_reply_port, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL); - __AfterSendRpc(2407, "mach_exception_raise_state_identity_OVR") - if (msg_result != MACH_MSG_SUCCESS) { - __MachMsgErrorWithoutTimeout(msg_result); - { return msg_result; } - } - - - #if defined(__MIG_check__Reply__mach_exception_raise_state_identity_t__defined) - check_result = __MIG_check__Reply__mach_exception_raise_state_identity_t((__Reply__mach_exception_raise_state_identity_t *)Out0P); - if (check_result != MACH_MSG_SUCCESS) - { return check_result; } - #endif /* defined(__MIG_check__Reply__mach_exception_raise_state_identity_t__defined) */ - - *flavor = Out0P->flavor; - - if (Out0P->new_stateCnt > 144) { - (void)memcpy((char *) new_state, (const char *) Out0P->new_state, 4 * 144); - *new_stateCnt = Out0P->new_stateCnt; - { return MIG_ARRAY_TOO_LARGE; } - } - (void)memcpy((char *) new_state, (const char *) Out0P->new_state, 4 * Out0P->new_stateCnt); - - *new_stateCnt = Out0P->new_stateCnt; - - return KERN_SUCCESS; -} - -#if defined(__cplusplus) - } /* extern "C" */ -#endif - -/* End mach_excUser.c */ - - - - -/* Begin mach_excServer.c */ - -/* Module mach_exc */ - -#define __MIG_check__Request__mach_exc_subsystem__ 1 -#define __NDR_convert__Request__mach_exc_subsystem__ 1 - -#include <string.h> -#include <mach/ndr.h> -#include <mach/boolean.h> -#include <mach/kern_return.h> -#include <mach/notify.h> -#include <mach/mach_types.h> -#include <mach/message.h> -#include <mach/mig_errors.h> -#include <mach/port.h> - -#include <mach/std_types.h> -#include <mach/mig.h> -#include <mach/mig.h> -#include <mach/mach_types.h> - -#if defined(__cplusplus) - extern "C" { -#endif - -#ifndef mig_internal -#define mig_internal static __inline__ -#endif /* mig_internal */ - -#ifndef mig_external -#define mig_external -#endif /* mig_external */ - -#if !defined(__MigTypeCheck) && defined(TypeCheck) -#define __MigTypeCheck TypeCheck /* Legacy setting */ -#endif /* !defined(__MigTypeCheck) */ - -#if !defined(__MigKernelSpecificCode) && defined(_MIG_KERNEL_SPECIFIC_CODE_) -#define __MigKernelSpecificCode _MIG_KERNEL_SPECIFIC_CODE_ /* Legacy setting */ -#endif /* !defined(__MigKernelSpecificCode) */ - -#ifndef LimitCheck -#define LimitCheck 0 -#endif /* LimitCheck */ - -#ifndef min -#define min(a,b) ( ((a) < (b))? (a): (b) ) -#endif /* min */ - -#if !defined(_WALIGN_) -#define _WALIGN_(x) (((x) + 3) & ~3) -#endif /* !defined(_WALIGN_) */ - -#if !defined(_WALIGNSZ_) -#define _WALIGNSZ_(x) _WALIGN_(sizeof(x)) -#endif /* !defined(_WALIGNSZ_) */ - -#ifndef UseStaticTemplates -#define UseStaticTemplates 0 -#endif /* UseStaticTemplates */ - -#ifndef __DeclareRcvRpc -#define __DeclareRcvRpc(_NUM_, _NAME_) -#endif /* __DeclareRcvRpc */ - -#ifndef __BeforeRcvRpc -#define __BeforeRcvRpc(_NUM_, _NAME_) -#endif /* __BeforeRcvRpc */ - -#ifndef __AfterRcvRpc -#define __AfterRcvRpc(_NUM_, _NAME_) -#endif /* __AfterRcvRpc */ - -#ifndef __DeclareRcvSimple -#define __DeclareRcvSimple(_NUM_, _NAME_) -#endif /* __DeclareRcvSimple */ - -#ifndef __BeforeRcvSimple -#define __BeforeRcvSimple(_NUM_, _NAME_) -#endif /* __BeforeRcvSimple */ - -#ifndef __AfterRcvSimple -#define __AfterRcvSimple(_NUM_, _NAME_) -#endif /* __AfterRcvSimple */ - -#define novalue void - -#ifndef msgh_request_port - #define msgh_request_port msgh_local_port -#endif -#define MACH_MSGH_BITS_REQUEST(bits) MACH_MSGH_BITS_LOCAL(bits) -#ifndef msgh_reply_port - #define msgh_reply_port msgh_remote_port -#endif -#define MACH_MSGH_BITS_REPLY(bits) MACH_MSGH_BITS_REMOTE(bits) - -#define MIG_RETURN_ERROR(X, code) {\ - ((mig_reply_error_t *)X)->RetCode = code;\ - ((mig_reply_error_t *)X)->NDR = NDR_record;\ - return;\ - } - -/* typedefs for all requests */ - -#ifndef __Request__mach_exc_subsystem__defined -#define __Request__mach_exc_subsystem__defined - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - /* start of the kernel processed data */ - mach_msg_body_t msgh_body; - mach_msg_port_descriptor_t thread; - mach_msg_port_descriptor_t task; - /* end of the kernel processed data */ - NDR_record_t NDR; - exception_type_t exception; - mach_msg_type_number_t codeCnt; - int64_t code[2]; - } __Request__mach_exception_raise_t; -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - exception_type_t exception; - mach_msg_type_number_t codeCnt; - int64_t code[2]; - int flavor; - mach_msg_type_number_t old_stateCnt; - natural_t old_state[144]; - } __Request__mach_exception_raise_state_t; -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - /* start of the kernel processed data */ - mach_msg_body_t msgh_body; - mach_msg_port_descriptor_t thread; - mach_msg_port_descriptor_t task; - /* end of the kernel processed data */ - NDR_record_t NDR; - exception_type_t exception; - mach_msg_type_number_t codeCnt; - int64_t code[2]; - int flavor; - mach_msg_type_number_t old_stateCnt; - natural_t old_state[144]; - } __Request__mach_exception_raise_state_identity_t; -#ifdef __MigPackStructs -#pragma pack() -#endif -#endif /* !__Request__mach_exc_subsystem__defined */ - -/* typedefs for all replies */ - -#ifndef __Reply__mach_exc_subsystem__defined -#define __Reply__mach_exc_subsystem__defined - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - kern_return_t RetCode; - } __Reply__mach_exception_raise_t; -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - kern_return_t RetCode; - int flavor; - mach_msg_type_number_t new_stateCnt; - natural_t new_state[144]; - } __Reply__mach_exception_raise_state_t; -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - kern_return_t RetCode; - int flavor; - mach_msg_type_number_t new_stateCnt; - natural_t new_state[144]; - } __Reply__mach_exception_raise_state_identity_t; -#ifdef __MigPackStructs -#pragma pack() -#endif -#endif /* !__Reply__mach_exc_subsystem__defined */ - - -/* union of all replies */ - -#ifndef __ReplyUnion__catch_mach_exc_subsystem__defined -#define __ReplyUnion__catch_mach_exc_subsystem__defined -union __ReplyUnion__catch_mach_exc_subsystem { - __Reply__mach_exception_raise_t Reply_mach_exception_raise; - __Reply__mach_exception_raise_state_t Reply_mach_exception_raise_state; - __Reply__mach_exception_raise_state_identity_t Reply_mach_exception_raise_state_identity; -}; -#endif /* __RequestUnion__catch_mach_exc_subsystem__defined */ -/* Forward Declarations */ - - -mig_internal novalue _Xmach_exception_raise_OVR - (mach_msg_header_t *InHeadP, mach_msg_header_t *OutHeadP); - -mig_internal novalue _Xmach_exception_raise_state_OVR - (mach_msg_header_t *InHeadP, mach_msg_header_t *OutHeadP); - -mig_internal novalue _Xmach_exception_raise_state_identity_OVR - (mach_msg_header_t *InHeadP, mach_msg_header_t *OutHeadP); - - -#if ( __MigTypeCheck || __NDR_convert__ ) -#if __MIG_check__Request__mach_exc_subsystem__ -#if !defined(__MIG_check__Request__mach_exception_raise_t__defined) -#define __MIG_check__Request__mach_exception_raise_t__defined -#ifndef __NDR_convert__int_rep__Request__mach_exception_raise_t__exception__defined -#if defined(__NDR_convert__int_rep__mach_exc__exception_type_t__defined) -#define __NDR_convert__int_rep__Request__mach_exception_raise_t__exception__defined -#define __NDR_convert__int_rep__Request__mach_exception_raise_t__exception(a, f) \ - __NDR_convert__int_rep__mach_exc__exception_type_t((exception_type_t *)(a), f) -#elif defined(__NDR_convert__int_rep__exception_type_t__defined) -#define __NDR_convert__int_rep__Request__mach_exception_raise_t__exception__defined -#define __NDR_convert__int_rep__Request__mach_exception_raise_t__exception(a, f) \ - __NDR_convert__int_rep__exception_type_t((exception_type_t *)(a), f) -#elif defined(__NDR_convert__int_rep__mach_exc__int__defined) -#define __NDR_convert__int_rep__Request__mach_exception_raise_t__exception__defined -#define __NDR_convert__int_rep__Request__mach_exception_raise_t__exception(a, f) \ - __NDR_convert__int_rep__mach_exc__int((int *)(a), f) -#elif defined(__NDR_convert__int_rep__int__defined) -#define __NDR_convert__int_rep__Request__mach_exception_raise_t__exception__defined -#define __NDR_convert__int_rep__Request__mach_exception_raise_t__exception(a, f) \ - __NDR_convert__int_rep__int((int *)(a), f) -#elif defined(__NDR_convert__int_rep__mach_exc__int32_t__defined) -#define __NDR_convert__int_rep__Request__mach_exception_raise_t__exception__defined -#define __NDR_convert__int_rep__Request__mach_exception_raise_t__exception(a, f) \ - __NDR_convert__int_rep__mach_exc__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__int_rep__int32_t__defined) -#define __NDR_convert__int_rep__Request__mach_exception_raise_t__exception__defined -#define __NDR_convert__int_rep__Request__mach_exception_raise_t__exception(a, f) \ - __NDR_convert__int_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__int_rep__Request__mach_exception_raise_t__exception__defined */ - -#ifndef __NDR_convert__int_rep__Request__mach_exception_raise_t__code__defined -#if defined(__NDR_convert__int_rep__mach_exc__mach_exception_data_t__defined) -#define __NDR_convert__int_rep__Request__mach_exception_raise_t__code__defined -#define __NDR_convert__int_rep__Request__mach_exception_raise_t__code(a, f, c) \ - __NDR_convert__int_rep__mach_exc__mach_exception_data_t((mach_exception_data_t *)(a), f, c) -#elif defined(__NDR_convert__int_rep__mach_exception_data_t__defined) -#define __NDR_convert__int_rep__Request__mach_exception_raise_t__code__defined -#define __NDR_convert__int_rep__Request__mach_exception_raise_t__code(a, f, c) \ - __NDR_convert__int_rep__mach_exception_data_t((mach_exception_data_t *)(a), f, c) -#elif defined(__NDR_convert__int_rep__mach_exc__int64_t__defined) -#define __NDR_convert__int_rep__Request__mach_exception_raise_t__code__defined -#define __NDR_convert__int_rep__Request__mach_exception_raise_t__code(a, f, c) \ - __NDR_convert__ARRAY((int64_t *)(a), f, c, __NDR_convert__int_rep__mach_exc__int64_t) -#elif defined(__NDR_convert__int_rep__int64_t__defined) -#define __NDR_convert__int_rep__Request__mach_exception_raise_t__code__defined -#define __NDR_convert__int_rep__Request__mach_exception_raise_t__code(a, f, c) \ - __NDR_convert__ARRAY((int64_t *)(a), f, c, __NDR_convert__int_rep__int64_t) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__int_rep__Request__mach_exception_raise_t__code__defined */ - -#ifndef __NDR_convert__int_rep__Request__mach_exception_raise_t__codeCnt__defined -#if defined(__NDR_convert__int_rep__mach_exc__mach_msg_type_number_t__defined) -#define __NDR_convert__int_rep__Request__mach_exception_raise_t__codeCnt__defined -#define __NDR_convert__int_rep__Request__mach_exception_raise_t__codeCnt(a, f) \ - __NDR_convert__int_rep__mach_exc__mach_msg_type_number_t((mach_msg_type_number_t *)(a), f) -#elif defined(__NDR_convert__int_rep__mach_msg_type_number_t__defined) -#define __NDR_convert__int_rep__Request__mach_exception_raise_t__codeCnt__defined -#define __NDR_convert__int_rep__Request__mach_exception_raise_t__codeCnt(a, f) \ - __NDR_convert__int_rep__mach_msg_type_number_t((mach_msg_type_number_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__int_rep__Request__mach_exception_raise_t__codeCnt__defined */ - -#ifndef __NDR_convert__char_rep__Request__mach_exception_raise_t__exception__defined -#if defined(__NDR_convert__char_rep__mach_exc__exception_type_t__defined) -#define __NDR_convert__char_rep__Request__mach_exception_raise_t__exception__defined -#define __NDR_convert__char_rep__Request__mach_exception_raise_t__exception(a, f) \ - __NDR_convert__char_rep__mach_exc__exception_type_t((exception_type_t *)(a), f) -#elif defined(__NDR_convert__char_rep__exception_type_t__defined) -#define __NDR_convert__char_rep__Request__mach_exception_raise_t__exception__defined -#define __NDR_convert__char_rep__Request__mach_exception_raise_t__exception(a, f) \ - __NDR_convert__char_rep__exception_type_t((exception_type_t *)(a), f) -#elif defined(__NDR_convert__char_rep__mach_exc__int__defined) -#define __NDR_convert__char_rep__Request__mach_exception_raise_t__exception__defined -#define __NDR_convert__char_rep__Request__mach_exception_raise_t__exception(a, f) \ - __NDR_convert__char_rep__mach_exc__int((int *)(a), f) -#elif defined(__NDR_convert__char_rep__int__defined) -#define __NDR_convert__char_rep__Request__mach_exception_raise_t__exception__defined -#define __NDR_convert__char_rep__Request__mach_exception_raise_t__exception(a, f) \ - __NDR_convert__char_rep__int((int *)(a), f) -#elif defined(__NDR_convert__char_rep__mach_exc__int32_t__defined) -#define __NDR_convert__char_rep__Request__mach_exception_raise_t__exception__defined -#define __NDR_convert__char_rep__Request__mach_exception_raise_t__exception(a, f) \ - __NDR_convert__char_rep__mach_exc__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__char_rep__int32_t__defined) -#define __NDR_convert__char_rep__Request__mach_exception_raise_t__exception__defined -#define __NDR_convert__char_rep__Request__mach_exception_raise_t__exception(a, f) \ - __NDR_convert__char_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__char_rep__Request__mach_exception_raise_t__exception__defined */ - -#ifndef __NDR_convert__char_rep__Request__mach_exception_raise_t__code__defined -#if defined(__NDR_convert__char_rep__mach_exc__mach_exception_data_t__defined) -#define __NDR_convert__char_rep__Request__mach_exception_raise_t__code__defined -#define __NDR_convert__char_rep__Request__mach_exception_raise_t__code(a, f, c) \ - __NDR_convert__char_rep__mach_exc__mach_exception_data_t((mach_exception_data_t *)(a), f, c) -#elif defined(__NDR_convert__char_rep__mach_exception_data_t__defined) -#define __NDR_convert__char_rep__Request__mach_exception_raise_t__code__defined -#define __NDR_convert__char_rep__Request__mach_exception_raise_t__code(a, f, c) \ - __NDR_convert__char_rep__mach_exception_data_t((mach_exception_data_t *)(a), f, c) -#elif defined(__NDR_convert__char_rep__mach_exc__int64_t__defined) -#define __NDR_convert__char_rep__Request__mach_exception_raise_t__code__defined -#define __NDR_convert__char_rep__Request__mach_exception_raise_t__code(a, f, c) \ - __NDR_convert__ARRAY((int64_t *)(a), f, c, __NDR_convert__char_rep__mach_exc__int64_t) -#elif defined(__NDR_convert__char_rep__int64_t__defined) -#define __NDR_convert__char_rep__Request__mach_exception_raise_t__code__defined -#define __NDR_convert__char_rep__Request__mach_exception_raise_t__code(a, f, c) \ - __NDR_convert__ARRAY((int64_t *)(a), f, c, __NDR_convert__char_rep__int64_t) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__char_rep__Request__mach_exception_raise_t__code__defined */ - -#ifndef __NDR_convert__float_rep__Request__mach_exception_raise_t__exception__defined -#if defined(__NDR_convert__float_rep__mach_exc__exception_type_t__defined) -#define __NDR_convert__float_rep__Request__mach_exception_raise_t__exception__defined -#define __NDR_convert__float_rep__Request__mach_exception_raise_t__exception(a, f) \ - __NDR_convert__float_rep__mach_exc__exception_type_t((exception_type_t *)(a), f) -#elif defined(__NDR_convert__float_rep__exception_type_t__defined) -#define __NDR_convert__float_rep__Request__mach_exception_raise_t__exception__defined -#define __NDR_convert__float_rep__Request__mach_exception_raise_t__exception(a, f) \ - __NDR_convert__float_rep__exception_type_t((exception_type_t *)(a), f) -#elif defined(__NDR_convert__float_rep__mach_exc__int__defined) -#define __NDR_convert__float_rep__Request__mach_exception_raise_t__exception__defined -#define __NDR_convert__float_rep__Request__mach_exception_raise_t__exception(a, f) \ - __NDR_convert__float_rep__mach_exc__int((int *)(a), f) -#elif defined(__NDR_convert__float_rep__int__defined) -#define __NDR_convert__float_rep__Request__mach_exception_raise_t__exception__defined -#define __NDR_convert__float_rep__Request__mach_exception_raise_t__exception(a, f) \ - __NDR_convert__float_rep__int((int *)(a), f) -#elif defined(__NDR_convert__float_rep__mach_exc__int32_t__defined) -#define __NDR_convert__float_rep__Request__mach_exception_raise_t__exception__defined -#define __NDR_convert__float_rep__Request__mach_exception_raise_t__exception(a, f) \ - __NDR_convert__float_rep__mach_exc__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__float_rep__int32_t__defined) -#define __NDR_convert__float_rep__Request__mach_exception_raise_t__exception__defined -#define __NDR_convert__float_rep__Request__mach_exception_raise_t__exception(a, f) \ - __NDR_convert__float_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__float_rep__Request__mach_exception_raise_t__exception__defined */ - -#ifndef __NDR_convert__float_rep__Request__mach_exception_raise_t__code__defined -#if defined(__NDR_convert__float_rep__mach_exc__mach_exception_data_t__defined) -#define __NDR_convert__float_rep__Request__mach_exception_raise_t__code__defined -#define __NDR_convert__float_rep__Request__mach_exception_raise_t__code(a, f, c) \ - __NDR_convert__float_rep__mach_exc__mach_exception_data_t((mach_exception_data_t *)(a), f, c) -#elif defined(__NDR_convert__float_rep__mach_exception_data_t__defined) -#define __NDR_convert__float_rep__Request__mach_exception_raise_t__code__defined -#define __NDR_convert__float_rep__Request__mach_exception_raise_t__code(a, f, c) \ - __NDR_convert__float_rep__mach_exception_data_t((mach_exception_data_t *)(a), f, c) -#elif defined(__NDR_convert__float_rep__mach_exc__int64_t__defined) -#define __NDR_convert__float_rep__Request__mach_exception_raise_t__code__defined -#define __NDR_convert__float_rep__Request__mach_exception_raise_t__code(a, f, c) \ - __NDR_convert__ARRAY((int64_t *)(a), f, c, __NDR_convert__float_rep__mach_exc__int64_t) -#elif defined(__NDR_convert__float_rep__int64_t__defined) -#define __NDR_convert__float_rep__Request__mach_exception_raise_t__code__defined -#define __NDR_convert__float_rep__Request__mach_exception_raise_t__code(a, f, c) \ - __NDR_convert__ARRAY((int64_t *)(a), f, c, __NDR_convert__float_rep__int64_t) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__float_rep__Request__mach_exception_raise_t__code__defined */ - - -mig_internal kern_return_t __MIG_check__Request__mach_exception_raise_t_OVR(__attribute__((__unused__)) __Request__mach_exception_raise_t *In0P) -{ - const size_t sizeofRequest = sizeof(__Request__mach_exception_raise_t); - - typedef __Request__mach_exception_raise_t __Request; - #if __MigTypeCheck - unsigned int msgh_size; - #endif /* __MigTypeCheck */ - - #if __MigTypeCheck - msgh_size = In0P->Head.msgh_size; - if (!(In0P->Head.msgh_bits & MACH_MSGH_BITS_COMPLEX) || - (In0P->msgh_body.msgh_descriptor_count != 2) || - (msgh_size < (mach_msg_size_t)(sizeofRequest - 16)) || (msgh_size > (mach_msg_size_t)sizeofRequest)) - return MIG_BAD_ARGUMENTS; - #endif /* __MigTypeCheck */ - - #if __MigTypeCheck - if (In0P->thread.type != MACH_MSG_PORT_DESCRIPTOR || - In0P->thread.disposition != 17) - return MIG_TYPE_ERROR; - #endif /* __MigTypeCheck */ - - #if __MigTypeCheck - if (In0P->task.type != MACH_MSG_PORT_DESCRIPTOR || - In0P->task.disposition != 17) - return MIG_TYPE_ERROR; - #endif /* __MigTypeCheck */ - - #if defined(__NDR_convert__int_rep__Request__mach_exception_raise_t__codeCnt__defined) - if (In0P->NDR.int_rep != NDR_record.int_rep) - __NDR_convert__int_rep__Request__mach_exception_raise_t__codeCnt(&In0P->codeCnt, In0P->NDR.int_rep); - #endif /* __NDR_convert__int_rep__Request__mach_exception_raise_t__codeCnt__defined */ - #if __MigTypeCheck - if ( In0P->codeCnt > 2 ) - return MIG_BAD_ARGUMENTS; - if (((msgh_size - (mach_msg_size_t)(sizeofRequest - 16)) / 8 != In0P->codeCnt) || - (msgh_size != (mach_msg_size_t)(sizeofRequest - 16) + (8 * In0P->codeCnt))) - return MIG_BAD_ARGUMENTS; - #endif /* __MigTypeCheck */ - - #if defined(__NDR_convert__int_rep__Request__mach_exception_raise_t__exception__defined) || \ - defined(__NDR_convert__int_rep__Request__mach_exception_raise_t__code__defined) || \ - defined(__NDR_convert__int_rep__Request__mach_exception_raise_t__codeCnt__defined) - if (In0P->NDR.int_rep != NDR_record.int_rep) { - #if defined(__NDR_convert__int_rep__Request__mach_exception_raise_t__exception__defined) - __NDR_convert__int_rep__Request__mach_exception_raise_t__exception(&In0P->exception, In0P->NDR.int_rep); - #endif /* __NDR_convert__int_rep__Request__mach_exception_raise_t__exception__defined */ - #if defined(__NDR_convert__int_rep__Request__mach_exception_raise_t__code__defined) - __NDR_convert__int_rep__Request__mach_exception_raise_t__code(&In0P->code, In0P->NDR.int_rep, In0P->codeCnt); - #endif /* __NDR_convert__int_rep__Request__mach_exception_raise_t__code__defined */ - } - #endif /* defined(__NDR_convert__int_rep...) */ - - #if defined(__NDR_convert__char_rep__Request__mach_exception_raise_t__exception__defined) || \ - defined(__NDR_convert__char_rep__Request__mach_exception_raise_t__code__defined) || \ - 0 - if (In0P->NDR.char_rep != NDR_record.char_rep) { - #if defined(__NDR_convert__char_rep__Request__mach_exception_raise_t__exception__defined) - __NDR_convert__char_rep__Request__mach_exception_raise_t__exception(&In0P->exception, In0P->NDR.char_rep); - #endif /* __NDR_convert__char_rep__Request__mach_exception_raise_t__exception__defined */ - #if defined(__NDR_convert__char_rep__Request__mach_exception_raise_t__code__defined) - __NDR_convert__char_rep__Request__mach_exception_raise_t__code(&In0P->code, In0P->NDR.char_rep, In0P->codeCnt); - #endif /* __NDR_convert__char_rep__Request__mach_exception_raise_t__code__defined */ - } - #endif /* defined(__NDR_convert__char_rep...) */ - - #if defined(__NDR_convert__float_rep__Request__mach_exception_raise_t__exception__defined) || \ - defined(__NDR_convert__float_rep__Request__mach_exception_raise_t__code__defined) || \ - 0 - if (In0P->NDR.float_rep != NDR_record.float_rep) { - #if defined(__NDR_convert__float_rep__Request__mach_exception_raise_t__exception__defined) - __NDR_convert__float_rep__Request__mach_exception_raise_t__exception(&In0P->exception, In0P->NDR.float_rep); - #endif /* __NDR_convert__float_rep__Request__mach_exception_raise_t__exception__defined */ - #if defined(__NDR_convert__float_rep__Request__mach_exception_raise_t__code__defined) - __NDR_convert__float_rep__Request__mach_exception_raise_t__code(&In0P->code, In0P->NDR.float_rep, In0P->codeCnt); - #endif /* __NDR_convert__float_rep__Request__mach_exception_raise_t__code__defined */ - } - #endif /* defined(__NDR_convert__float_rep...) */ - - return MACH_MSG_SUCCESS; -} -#endif /* !defined(__MIG_check__Request__mach_exception_raise_t__defined) */ -#endif /* __MIG_check__Request__mach_exc_subsystem__ */ -#endif /* ( __MigTypeCheck || __NDR_convert__ ) */ - - -/* Routine catch_mach_exception_raise_OVR */ -#ifdef mig_external -mig_external -#else -extern -#endif /* mig_external */ -kern_return_t catch_mach_exception_raise_OVR -( - mach_port_t exception_port, - mach_port_t thread, - mach_port_t task, - exception_type_t exception, - mach_exception_data_t code, - mach_msg_type_number_t codeCnt -); - -/* Routine _Xmach_exception_raise_OVR */ -mig_internal novalue _Xmach_exception_raise_OVR - (mach_msg_header_t *InHeadP, mach_msg_header_t *OutHeadP) -{ - - #ifdef __MigPackStructs - #pragma pack(4) - #endif - typedef struct { - mach_msg_header_t Head; - /* start of the kernel processed data */ - mach_msg_body_t msgh_body; - mach_msg_port_descriptor_t thread; - mach_msg_port_descriptor_t task; - /* end of the kernel processed data */ - NDR_record_t NDR; - exception_type_t exception; - mach_msg_type_number_t codeCnt; - int64_t code[2]; - mach_msg_trailer_t trailer; - } Request; - #ifdef __MigPackStructs - #pragma pack() - #endif - typedef __Request__mach_exception_raise_t __Request; - typedef __Reply__mach_exception_raise_t Reply; - - /* - * typedef struct { - * mach_msg_header_t Head; - * NDR_record_t NDR; - * kern_return_t RetCode; - * } mig_reply_error_t; - */ - - Request *In0P = (Request *) InHeadP; - Reply *OutP = (Reply *) OutHeadP; - #ifdef __MIG_check__Request__mach_exception_raise_t__defined - kern_return_t check_result; - #endif /* __MIG_check__Request__mach_exception_raise_t__defined */ - - __DeclareRcvRpc(2405, "mach_exception_raise_OVR") - __BeforeRcvRpc(2405, "mach_exception_raise_OVR") - - #if defined(__MIG_check__Request__mach_exception_raise_t__defined) - check_result = __MIG_check__Request__mach_exception_raise_t_OVR((__Request *)In0P); - if (check_result != MACH_MSG_SUCCESS) - { MIG_RETURN_ERROR(OutP, check_result); } - #endif /* defined(__MIG_check__Request__mach_exception_raise_t__defined) */ - - OutP->RetCode = catch_mach_exception_raise_OVR(In0P->Head.msgh_request_port, In0P->thread.name, In0P->task.name, In0P->exception, In0P->code, In0P->codeCnt); - - OutP->NDR = NDR_record; - - - __AfterRcvRpc(2405, "mach_exception_raise_OVR") -} - -#if ( __MigTypeCheck || __NDR_convert__ ) -#if __MIG_check__Request__mach_exc_subsystem__ -#if !defined(__MIG_check__Request__mach_exception_raise_state_t__defined) -#define __MIG_check__Request__mach_exception_raise_state_t__defined -#ifndef __NDR_convert__int_rep__Request__mach_exception_raise_state_t__exception__defined -#if defined(__NDR_convert__int_rep__mach_exc__exception_type_t__defined) -#define __NDR_convert__int_rep__Request__mach_exception_raise_state_t__exception__defined -#define __NDR_convert__int_rep__Request__mach_exception_raise_state_t__exception(a, f) \ - __NDR_convert__int_rep__mach_exc__exception_type_t((exception_type_t *)(a), f) -#elif defined(__NDR_convert__int_rep__exception_type_t__defined) -#define __NDR_convert__int_rep__Request__mach_exception_raise_state_t__exception__defined -#define __NDR_convert__int_rep__Request__mach_exception_raise_state_t__exception(a, f) \ - __NDR_convert__int_rep__exception_type_t((exception_type_t *)(a), f) -#elif defined(__NDR_convert__int_rep__mach_exc__int__defined) -#define __NDR_convert__int_rep__Request__mach_exception_raise_state_t__exception__defined -#define __NDR_convert__int_rep__Request__mach_exception_raise_state_t__exception(a, f) \ - __NDR_convert__int_rep__mach_exc__int((int *)(a), f) -#elif defined(__NDR_convert__int_rep__int__defined) -#define __NDR_convert__int_rep__Request__mach_exception_raise_state_t__exception__defined -#define __NDR_convert__int_rep__Request__mach_exception_raise_state_t__exception(a, f) \ - __NDR_convert__int_rep__int((int *)(a), f) -#elif defined(__NDR_convert__int_rep__mach_exc__int32_t__defined) -#define __NDR_convert__int_rep__Request__mach_exception_raise_state_t__exception__defined -#define __NDR_convert__int_rep__Request__mach_exception_raise_state_t__exception(a, f) \ - __NDR_convert__int_rep__mach_exc__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__int_rep__int32_t__defined) -#define __NDR_convert__int_rep__Request__mach_exception_raise_state_t__exception__defined -#define __NDR_convert__int_rep__Request__mach_exception_raise_state_t__exception(a, f) \ - __NDR_convert__int_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__int_rep__Request__mach_exception_raise_state_t__exception__defined */ - -#ifndef __NDR_convert__int_rep__Request__mach_exception_raise_state_t__code__defined -#if defined(__NDR_convert__int_rep__mach_exc__mach_exception_data_t__defined) -#define __NDR_convert__int_rep__Request__mach_exception_raise_state_t__code__defined -#define __NDR_convert__int_rep__Request__mach_exception_raise_state_t__code(a, f, c) \ - __NDR_convert__int_rep__mach_exc__mach_exception_data_t((mach_exception_data_t *)(a), f, c) -#elif defined(__NDR_convert__int_rep__mach_exception_data_t__defined) -#define __NDR_convert__int_rep__Request__mach_exception_raise_state_t__code__defined -#define __NDR_convert__int_rep__Request__mach_exception_raise_state_t__code(a, f, c) \ - __NDR_convert__int_rep__mach_exception_data_t((mach_exception_data_t *)(a), f, c) -#elif defined(__NDR_convert__int_rep__mach_exc__int64_t__defined) -#define __NDR_convert__int_rep__Request__mach_exception_raise_state_t__code__defined -#define __NDR_convert__int_rep__Request__mach_exception_raise_state_t__code(a, f, c) \ - __NDR_convert__ARRAY((int64_t *)(a), f, c, __NDR_convert__int_rep__mach_exc__int64_t) -#elif defined(__NDR_convert__int_rep__int64_t__defined) -#define __NDR_convert__int_rep__Request__mach_exception_raise_state_t__code__defined -#define __NDR_convert__int_rep__Request__mach_exception_raise_state_t__code(a, f, c) \ - __NDR_convert__ARRAY((int64_t *)(a), f, c, __NDR_convert__int_rep__int64_t) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__int_rep__Request__mach_exception_raise_state_t__code__defined */ - -#ifndef __NDR_convert__int_rep__Request__mach_exception_raise_state_t__codeCnt__defined -#if defined(__NDR_convert__int_rep__mach_exc__mach_msg_type_number_t__defined) -#define __NDR_convert__int_rep__Request__mach_exception_raise_state_t__codeCnt__defined -#define __NDR_convert__int_rep__Request__mach_exception_raise_state_t__codeCnt(a, f) \ - __NDR_convert__int_rep__mach_exc__mach_msg_type_number_t((mach_msg_type_number_t *)(a), f) -#elif defined(__NDR_convert__int_rep__mach_msg_type_number_t__defined) -#define __NDR_convert__int_rep__Request__mach_exception_raise_state_t__codeCnt__defined -#define __NDR_convert__int_rep__Request__mach_exception_raise_state_t__codeCnt(a, f) \ - __NDR_convert__int_rep__mach_msg_type_number_t((mach_msg_type_number_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__int_rep__Request__mach_exception_raise_state_t__codeCnt__defined */ - -#ifndef __NDR_convert__int_rep__Request__mach_exception_raise_state_t__flavor__defined -#if defined(__NDR_convert__int_rep__mach_exc__int__defined) -#define __NDR_convert__int_rep__Request__mach_exception_raise_state_t__flavor__defined -#define __NDR_convert__int_rep__Request__mach_exception_raise_state_t__flavor(a, f) \ - __NDR_convert__int_rep__mach_exc__int((int *)(a), f) -#elif defined(__NDR_convert__int_rep__int__defined) -#define __NDR_convert__int_rep__Request__mach_exception_raise_state_t__flavor__defined -#define __NDR_convert__int_rep__Request__mach_exception_raise_state_t__flavor(a, f) \ - __NDR_convert__int_rep__int((int *)(a), f) -#elif defined(__NDR_convert__int_rep__mach_exc__int32_t__defined) -#define __NDR_convert__int_rep__Request__mach_exception_raise_state_t__flavor__defined -#define __NDR_convert__int_rep__Request__mach_exception_raise_state_t__flavor(a, f) \ - __NDR_convert__int_rep__mach_exc__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__int_rep__int32_t__defined) -#define __NDR_convert__int_rep__Request__mach_exception_raise_state_t__flavor__defined -#define __NDR_convert__int_rep__Request__mach_exception_raise_state_t__flavor(a, f) \ - __NDR_convert__int_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__int_rep__Request__mach_exception_raise_state_t__flavor__defined */ - -#ifndef __NDR_convert__int_rep__Request__mach_exception_raise_state_t__old_state__defined -#if defined(__NDR_convert__int_rep__mach_exc__thread_state_t__defined) -#define __NDR_convert__int_rep__Request__mach_exception_raise_state_t__old_state__defined -#define __NDR_convert__int_rep__Request__mach_exception_raise_state_t__old_state(a, f, c) \ - __NDR_convert__int_rep__mach_exc__thread_state_t((thread_state_t *)(a), f, c) -#elif defined(__NDR_convert__int_rep__thread_state_t__defined) -#define __NDR_convert__int_rep__Request__mach_exception_raise_state_t__old_state__defined -#define __NDR_convert__int_rep__Request__mach_exception_raise_state_t__old_state(a, f, c) \ - __NDR_convert__int_rep__thread_state_t((thread_state_t *)(a), f, c) -#elif defined(__NDR_convert__int_rep__mach_exc__natural_t__defined) -#define __NDR_convert__int_rep__Request__mach_exception_raise_state_t__old_state__defined -#define __NDR_convert__int_rep__Request__mach_exception_raise_state_t__old_state(a, f, c) \ - __NDR_convert__ARRAY((natural_t *)(a), f, c, __NDR_convert__int_rep__mach_exc__natural_t) -#elif defined(__NDR_convert__int_rep__natural_t__defined) -#define __NDR_convert__int_rep__Request__mach_exception_raise_state_t__old_state__defined -#define __NDR_convert__int_rep__Request__mach_exception_raise_state_t__old_state(a, f, c) \ - __NDR_convert__ARRAY((natural_t *)(a), f, c, __NDR_convert__int_rep__natural_t) -#elif defined(__NDR_convert__int_rep__mach_exc__uint32_t__defined) -#define __NDR_convert__int_rep__Request__mach_exception_raise_state_t__old_state__defined -#define __NDR_convert__int_rep__Request__mach_exception_raise_state_t__old_state(a, f, c) \ - __NDR_convert__ARRAY((uint32_t *)(a), f, c, __NDR_convert__int_rep__mach_exc__uint32_t) -#elif defined(__NDR_convert__int_rep__uint32_t__defined) -#define __NDR_convert__int_rep__Request__mach_exception_raise_state_t__old_state__defined -#define __NDR_convert__int_rep__Request__mach_exception_raise_state_t__old_state(a, f, c) \ - __NDR_convert__ARRAY((uint32_t *)(a), f, c, __NDR_convert__int_rep__uint32_t) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__int_rep__Request__mach_exception_raise_state_t__old_state__defined */ - -#ifndef __NDR_convert__int_rep__Request__mach_exception_raise_state_t__old_stateCnt__defined -#if defined(__NDR_convert__int_rep__mach_exc__mach_msg_type_number_t__defined) -#define __NDR_convert__int_rep__Request__mach_exception_raise_state_t__old_stateCnt__defined -#define __NDR_convert__int_rep__Request__mach_exception_raise_state_t__old_stateCnt(a, f) \ - __NDR_convert__int_rep__mach_exc__mach_msg_type_number_t((mach_msg_type_number_t *)(a), f) -#elif defined(__NDR_convert__int_rep__mach_msg_type_number_t__defined) -#define __NDR_convert__int_rep__Request__mach_exception_raise_state_t__old_stateCnt__defined -#define __NDR_convert__int_rep__Request__mach_exception_raise_state_t__old_stateCnt(a, f) \ - __NDR_convert__int_rep__mach_msg_type_number_t((mach_msg_type_number_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__int_rep__Request__mach_exception_raise_state_t__old_stateCnt__defined */ - -#ifndef __NDR_convert__char_rep__Request__mach_exception_raise_state_t__exception__defined -#if defined(__NDR_convert__char_rep__mach_exc__exception_type_t__defined) -#define __NDR_convert__char_rep__Request__mach_exception_raise_state_t__exception__defined -#define __NDR_convert__char_rep__Request__mach_exception_raise_state_t__exception(a, f) \ - __NDR_convert__char_rep__mach_exc__exception_type_t((exception_type_t *)(a), f) -#elif defined(__NDR_convert__char_rep__exception_type_t__defined) -#define __NDR_convert__char_rep__Request__mach_exception_raise_state_t__exception__defined -#define __NDR_convert__char_rep__Request__mach_exception_raise_state_t__exception(a, f) \ - __NDR_convert__char_rep__exception_type_t((exception_type_t *)(a), f) -#elif defined(__NDR_convert__char_rep__mach_exc__int__defined) -#define __NDR_convert__char_rep__Request__mach_exception_raise_state_t__exception__defined -#define __NDR_convert__char_rep__Request__mach_exception_raise_state_t__exception(a, f) \ - __NDR_convert__char_rep__mach_exc__int((int *)(a), f) -#elif defined(__NDR_convert__char_rep__int__defined) -#define __NDR_convert__char_rep__Request__mach_exception_raise_state_t__exception__defined -#define __NDR_convert__char_rep__Request__mach_exception_raise_state_t__exception(a, f) \ - __NDR_convert__char_rep__int((int *)(a), f) -#elif defined(__NDR_convert__char_rep__mach_exc__int32_t__defined) -#define __NDR_convert__char_rep__Request__mach_exception_raise_state_t__exception__defined -#define __NDR_convert__char_rep__Request__mach_exception_raise_state_t__exception(a, f) \ - __NDR_convert__char_rep__mach_exc__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__char_rep__int32_t__defined) -#define __NDR_convert__char_rep__Request__mach_exception_raise_state_t__exception__defined -#define __NDR_convert__char_rep__Request__mach_exception_raise_state_t__exception(a, f) \ - __NDR_convert__char_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__char_rep__Request__mach_exception_raise_state_t__exception__defined */ - -#ifndef __NDR_convert__char_rep__Request__mach_exception_raise_state_t__code__defined -#if defined(__NDR_convert__char_rep__mach_exc__mach_exception_data_t__defined) -#define __NDR_convert__char_rep__Request__mach_exception_raise_state_t__code__defined -#define __NDR_convert__char_rep__Request__mach_exception_raise_state_t__code(a, f, c) \ - __NDR_convert__char_rep__mach_exc__mach_exception_data_t((mach_exception_data_t *)(a), f, c) -#elif defined(__NDR_convert__char_rep__mach_exception_data_t__defined) -#define __NDR_convert__char_rep__Request__mach_exception_raise_state_t__code__defined -#define __NDR_convert__char_rep__Request__mach_exception_raise_state_t__code(a, f, c) \ - __NDR_convert__char_rep__mach_exception_data_t((mach_exception_data_t *)(a), f, c) -#elif defined(__NDR_convert__char_rep__mach_exc__int64_t__defined) -#define __NDR_convert__char_rep__Request__mach_exception_raise_state_t__code__defined -#define __NDR_convert__char_rep__Request__mach_exception_raise_state_t__code(a, f, c) \ - __NDR_convert__ARRAY((int64_t *)(a), f, c, __NDR_convert__char_rep__mach_exc__int64_t) -#elif defined(__NDR_convert__char_rep__int64_t__defined) -#define __NDR_convert__char_rep__Request__mach_exception_raise_state_t__code__defined -#define __NDR_convert__char_rep__Request__mach_exception_raise_state_t__code(a, f, c) \ - __NDR_convert__ARRAY((int64_t *)(a), f, c, __NDR_convert__char_rep__int64_t) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__char_rep__Request__mach_exception_raise_state_t__code__defined */ - -#ifndef __NDR_convert__char_rep__Request__mach_exception_raise_state_t__flavor__defined -#if defined(__NDR_convert__char_rep__mach_exc__int__defined) -#define __NDR_convert__char_rep__Request__mach_exception_raise_state_t__flavor__defined -#define __NDR_convert__char_rep__Request__mach_exception_raise_state_t__flavor(a, f) \ - __NDR_convert__char_rep__mach_exc__int((int *)(a), f) -#elif defined(__NDR_convert__char_rep__int__defined) -#define __NDR_convert__char_rep__Request__mach_exception_raise_state_t__flavor__defined -#define __NDR_convert__char_rep__Request__mach_exception_raise_state_t__flavor(a, f) \ - __NDR_convert__char_rep__int((int *)(a), f) -#elif defined(__NDR_convert__char_rep__mach_exc__int32_t__defined) -#define __NDR_convert__char_rep__Request__mach_exception_raise_state_t__flavor__defined -#define __NDR_convert__char_rep__Request__mach_exception_raise_state_t__flavor(a, f) \ - __NDR_convert__char_rep__mach_exc__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__char_rep__int32_t__defined) -#define __NDR_convert__char_rep__Request__mach_exception_raise_state_t__flavor__defined -#define __NDR_convert__char_rep__Request__mach_exception_raise_state_t__flavor(a, f) \ - __NDR_convert__char_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__char_rep__Request__mach_exception_raise_state_t__flavor__defined */ - -#ifndef __NDR_convert__char_rep__Request__mach_exception_raise_state_t__old_state__defined -#if defined(__NDR_convert__char_rep__mach_exc__thread_state_t__defined) -#define __NDR_convert__char_rep__Request__mach_exception_raise_state_t__old_state__defined -#define __NDR_convert__char_rep__Request__mach_exception_raise_state_t__old_state(a, f, c) \ - __NDR_convert__char_rep__mach_exc__thread_state_t((thread_state_t *)(a), f, c) -#elif defined(__NDR_convert__char_rep__thread_state_t__defined) -#define __NDR_convert__char_rep__Request__mach_exception_raise_state_t__old_state__defined -#define __NDR_convert__char_rep__Request__mach_exception_raise_state_t__old_state(a, f, c) \ - __NDR_convert__char_rep__thread_state_t((thread_state_t *)(a), f, c) -#elif defined(__NDR_convert__char_rep__mach_exc__natural_t__defined) -#define __NDR_convert__char_rep__Request__mach_exception_raise_state_t__old_state__defined -#define __NDR_convert__char_rep__Request__mach_exception_raise_state_t__old_state(a, f, c) \ - __NDR_convert__ARRAY((natural_t *)(a), f, c, __NDR_convert__char_rep__mach_exc__natural_t) -#elif defined(__NDR_convert__char_rep__natural_t__defined) -#define __NDR_convert__char_rep__Request__mach_exception_raise_state_t__old_state__defined -#define __NDR_convert__char_rep__Request__mach_exception_raise_state_t__old_state(a, f, c) \ - __NDR_convert__ARRAY((natural_t *)(a), f, c, __NDR_convert__char_rep__natural_t) -#elif defined(__NDR_convert__char_rep__mach_exc__uint32_t__defined) -#define __NDR_convert__char_rep__Request__mach_exception_raise_state_t__old_state__defined -#define __NDR_convert__char_rep__Request__mach_exception_raise_state_t__old_state(a, f, c) \ - __NDR_convert__ARRAY((uint32_t *)(a), f, c, __NDR_convert__char_rep__mach_exc__uint32_t) -#elif defined(__NDR_convert__char_rep__uint32_t__defined) -#define __NDR_convert__char_rep__Request__mach_exception_raise_state_t__old_state__defined -#define __NDR_convert__char_rep__Request__mach_exception_raise_state_t__old_state(a, f, c) \ - __NDR_convert__ARRAY((uint32_t *)(a), f, c, __NDR_convert__char_rep__uint32_t) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__char_rep__Request__mach_exception_raise_state_t__old_state__defined */ - -#ifndef __NDR_convert__float_rep__Request__mach_exception_raise_state_t__exception__defined -#if defined(__NDR_convert__float_rep__mach_exc__exception_type_t__defined) -#define __NDR_convert__float_rep__Request__mach_exception_raise_state_t__exception__defined -#define __NDR_convert__float_rep__Request__mach_exception_raise_state_t__exception(a, f) \ - __NDR_convert__float_rep__mach_exc__exception_type_t((exception_type_t *)(a), f) -#elif defined(__NDR_convert__float_rep__exception_type_t__defined) -#define __NDR_convert__float_rep__Request__mach_exception_raise_state_t__exception__defined -#define __NDR_convert__float_rep__Request__mach_exception_raise_state_t__exception(a, f) \ - __NDR_convert__float_rep__exception_type_t((exception_type_t *)(a), f) -#elif defined(__NDR_convert__float_rep__mach_exc__int__defined) -#define __NDR_convert__float_rep__Request__mach_exception_raise_state_t__exception__defined -#define __NDR_convert__float_rep__Request__mach_exception_raise_state_t__exception(a, f) \ - __NDR_convert__float_rep__mach_exc__int((int *)(a), f) -#elif defined(__NDR_convert__float_rep__int__defined) -#define __NDR_convert__float_rep__Request__mach_exception_raise_state_t__exception__defined -#define __NDR_convert__float_rep__Request__mach_exception_raise_state_t__exception(a, f) \ - __NDR_convert__float_rep__int((int *)(a), f) -#elif defined(__NDR_convert__float_rep__mach_exc__int32_t__defined) -#define __NDR_convert__float_rep__Request__mach_exception_raise_state_t__exception__defined -#define __NDR_convert__float_rep__Request__mach_exception_raise_state_t__exception(a, f) \ - __NDR_convert__float_rep__mach_exc__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__float_rep__int32_t__defined) -#define __NDR_convert__float_rep__Request__mach_exception_raise_state_t__exception__defined -#define __NDR_convert__float_rep__Request__mach_exception_raise_state_t__exception(a, f) \ - __NDR_convert__float_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__float_rep__Request__mach_exception_raise_state_t__exception__defined */ - -#ifndef __NDR_convert__float_rep__Request__mach_exception_raise_state_t__code__defined -#if defined(__NDR_convert__float_rep__mach_exc__mach_exception_data_t__defined) -#define __NDR_convert__float_rep__Request__mach_exception_raise_state_t__code__defined -#define __NDR_convert__float_rep__Request__mach_exception_raise_state_t__code(a, f, c) \ - __NDR_convert__float_rep__mach_exc__mach_exception_data_t((mach_exception_data_t *)(a), f, c) -#elif defined(__NDR_convert__float_rep__mach_exception_data_t__defined) -#define __NDR_convert__float_rep__Request__mach_exception_raise_state_t__code__defined -#define __NDR_convert__float_rep__Request__mach_exception_raise_state_t__code(a, f, c) \ - __NDR_convert__float_rep__mach_exception_data_t((mach_exception_data_t *)(a), f, c) -#elif defined(__NDR_convert__float_rep__mach_exc__int64_t__defined) -#define __NDR_convert__float_rep__Request__mach_exception_raise_state_t__code__defined -#define __NDR_convert__float_rep__Request__mach_exception_raise_state_t__code(a, f, c) \ - __NDR_convert__ARRAY((int64_t *)(a), f, c, __NDR_convert__float_rep__mach_exc__int64_t) -#elif defined(__NDR_convert__float_rep__int64_t__defined) -#define __NDR_convert__float_rep__Request__mach_exception_raise_state_t__code__defined -#define __NDR_convert__float_rep__Request__mach_exception_raise_state_t__code(a, f, c) \ - __NDR_convert__ARRAY((int64_t *)(a), f, c, __NDR_convert__float_rep__int64_t) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__float_rep__Request__mach_exception_raise_state_t__code__defined */ - -#ifndef __NDR_convert__float_rep__Request__mach_exception_raise_state_t__flavor__defined -#if defined(__NDR_convert__float_rep__mach_exc__int__defined) -#define __NDR_convert__float_rep__Request__mach_exception_raise_state_t__flavor__defined -#define __NDR_convert__float_rep__Request__mach_exception_raise_state_t__flavor(a, f) \ - __NDR_convert__float_rep__mach_exc__int((int *)(a), f) -#elif defined(__NDR_convert__float_rep__int__defined) -#define __NDR_convert__float_rep__Request__mach_exception_raise_state_t__flavor__defined -#define __NDR_convert__float_rep__Request__mach_exception_raise_state_t__flavor(a, f) \ - __NDR_convert__float_rep__int((int *)(a), f) -#elif defined(__NDR_convert__float_rep__mach_exc__int32_t__defined) -#define __NDR_convert__float_rep__Request__mach_exception_raise_state_t__flavor__defined -#define __NDR_convert__float_rep__Request__mach_exception_raise_state_t__flavor(a, f) \ - __NDR_convert__float_rep__mach_exc__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__float_rep__int32_t__defined) -#define __NDR_convert__float_rep__Request__mach_exception_raise_state_t__flavor__defined -#define __NDR_convert__float_rep__Request__mach_exception_raise_state_t__flavor(a, f) \ - __NDR_convert__float_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__float_rep__Request__mach_exception_raise_state_t__flavor__defined */ - -#ifndef __NDR_convert__float_rep__Request__mach_exception_raise_state_t__old_state__defined -#if defined(__NDR_convert__float_rep__mach_exc__thread_state_t__defined) -#define __NDR_convert__float_rep__Request__mach_exception_raise_state_t__old_state__defined -#define __NDR_convert__float_rep__Request__mach_exception_raise_state_t__old_state(a, f, c) \ - __NDR_convert__float_rep__mach_exc__thread_state_t((thread_state_t *)(a), f, c) -#elif defined(__NDR_convert__float_rep__thread_state_t__defined) -#define __NDR_convert__float_rep__Request__mach_exception_raise_state_t__old_state__defined -#define __NDR_convert__float_rep__Request__mach_exception_raise_state_t__old_state(a, f, c) \ - __NDR_convert__float_rep__thread_state_t((thread_state_t *)(a), f, c) -#elif defined(__NDR_convert__float_rep__mach_exc__natural_t__defined) -#define __NDR_convert__float_rep__Request__mach_exception_raise_state_t__old_state__defined -#define __NDR_convert__float_rep__Request__mach_exception_raise_state_t__old_state(a, f, c) \ - __NDR_convert__ARRAY((natural_t *)(a), f, c, __NDR_convert__float_rep__mach_exc__natural_t) -#elif defined(__NDR_convert__float_rep__natural_t__defined) -#define __NDR_convert__float_rep__Request__mach_exception_raise_state_t__old_state__defined -#define __NDR_convert__float_rep__Request__mach_exception_raise_state_t__old_state(a, f, c) \ - __NDR_convert__ARRAY((natural_t *)(a), f, c, __NDR_convert__float_rep__natural_t) -#elif defined(__NDR_convert__float_rep__mach_exc__uint32_t__defined) -#define __NDR_convert__float_rep__Request__mach_exception_raise_state_t__old_state__defined -#define __NDR_convert__float_rep__Request__mach_exception_raise_state_t__old_state(a, f, c) \ - __NDR_convert__ARRAY((uint32_t *)(a), f, c, __NDR_convert__float_rep__mach_exc__uint32_t) -#elif defined(__NDR_convert__float_rep__uint32_t__defined) -#define __NDR_convert__float_rep__Request__mach_exception_raise_state_t__old_state__defined -#define __NDR_convert__float_rep__Request__mach_exception_raise_state_t__old_state(a, f, c) \ - __NDR_convert__ARRAY((uint32_t *)(a), f, c, __NDR_convert__float_rep__uint32_t) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__float_rep__Request__mach_exception_raise_state_t__old_state__defined */ - - -mig_internal kern_return_t __MIG_check__Request__mach_exception_raise_state_t_OVR(__attribute__((__unused__)) __Request__mach_exception_raise_state_t *In0P, __attribute__((__unused__)) __Request__mach_exception_raise_state_t **In1PP) -{ - - typedef __Request__mach_exception_raise_state_t __Request; - __Request *In1P; - #if __MigTypeCheck - unsigned int msgh_size; - #endif /* __MigTypeCheck */ - unsigned int msgh_size_delta; - - #if __MigTypeCheck - msgh_size = In0P->Head.msgh_size; - if ((In0P->Head.msgh_bits & MACH_MSGH_BITS_COMPLEX) || - (msgh_size < (mach_msg_size_t)(sizeof(__Request) - 592)) || (msgh_size > (mach_msg_size_t)sizeof(__Request))) - return MIG_BAD_ARGUMENTS; - #endif /* __MigTypeCheck */ - - #if defined(__NDR_convert__int_rep__Request__mach_exception_raise_state_t__codeCnt__defined) - if (In0P->NDR.int_rep != NDR_record.int_rep) - __NDR_convert__int_rep__Request__mach_exception_raise_state_t__codeCnt(&In0P->codeCnt, In0P->NDR.int_rep); - #endif /* __NDR_convert__int_rep__Request__mach_exception_raise_state_t__codeCnt__defined */ - msgh_size_delta = (8 * In0P->codeCnt); - #if __MigTypeCheck - if ( In0P->codeCnt > 2 ) - return MIG_BAD_ARGUMENTS; - if (((msgh_size - (mach_msg_size_t)(sizeof(__Request) - 592)) / 8 < In0P->codeCnt) || - (msgh_size < (mach_msg_size_t)(sizeof(__Request) - 592) + (8 * In0P->codeCnt))) - return MIG_BAD_ARGUMENTS; - msgh_size -= msgh_size_delta; - #endif /* __MigTypeCheck */ - - *In1PP = In1P = (__Request *) ((pointer_t) In0P + msgh_size_delta - 16); - - #if defined(__NDR_convert__int_rep__Request__mach_exception_raise_state_t__old_stateCnt__defined) - if (In0P->NDR.int_rep != NDR_record.int_rep) - __NDR_convert__int_rep__Request__mach_exception_raise_state_t__old_stateCnt(&In1P->old_stateCnt, In1P->NDR.int_rep); - #endif /* __NDR_convert__int_rep__Request__mach_exception_raise_state_t__old_stateCnt__defined */ - #if __MigTypeCheck - if ( In1P->old_stateCnt > 144 ) - return MIG_BAD_ARGUMENTS; - if (((msgh_size - (mach_msg_size_t)(sizeof(__Request) - 592)) / 4 != In1P->old_stateCnt) || - (msgh_size != (mach_msg_size_t)(sizeof(__Request) - 592) + (4 * In1P->old_stateCnt))) - return MIG_BAD_ARGUMENTS; - #endif /* __MigTypeCheck */ - - #if defined(__NDR_convert__int_rep__Request__mach_exception_raise_state_t__exception__defined) || \ - defined(__NDR_convert__int_rep__Request__mach_exception_raise_state_t__code__defined) || \ - defined(__NDR_convert__int_rep__Request__mach_exception_raise_state_t__codeCnt__defined) || \ - defined(__NDR_convert__int_rep__Request__mach_exception_raise_state_t__flavor__defined) || \ - defined(__NDR_convert__int_rep__Request__mach_exception_raise_state_t__old_state__defined) || \ - defined(__NDR_convert__int_rep__Request__mach_exception_raise_state_t__old_stateCnt__defined) - if (In0P->NDR.int_rep != NDR_record.int_rep) { - #if defined(__NDR_convert__int_rep__Request__mach_exception_raise_state_t__exception__defined) - __NDR_convert__int_rep__Request__mach_exception_raise_state_t__exception(&In0P->exception, In0P->NDR.int_rep); - #endif /* __NDR_convert__int_rep__Request__mach_exception_raise_state_t__exception__defined */ - #if defined(__NDR_convert__int_rep__Request__mach_exception_raise_state_t__code__defined) - __NDR_convert__int_rep__Request__mach_exception_raise_state_t__code(&In0P->code, In0P->NDR.int_rep, In0P->codeCnt); - #endif /* __NDR_convert__int_rep__Request__mach_exception_raise_state_t__code__defined */ - #if defined(__NDR_convert__int_rep__Request__mach_exception_raise_state_t__flavor__defined) - __NDR_convert__int_rep__Request__mach_exception_raise_state_t__flavor(&In1P->flavor, In0P->NDR.int_rep); - #endif /* __NDR_convert__int_rep__Request__mach_exception_raise_state_t__flavor__defined */ - #if defined(__NDR_convert__int_rep__Request__mach_exception_raise_state_t__old_state__defined) - __NDR_convert__int_rep__Request__mach_exception_raise_state_t__old_state(&In1P->old_state, In0P->NDR.int_rep, In1P->old_stateCnt); - #endif /* __NDR_convert__int_rep__Request__mach_exception_raise_state_t__old_state__defined */ - } - #endif /* defined(__NDR_convert__int_rep...) */ - - #if defined(__NDR_convert__char_rep__Request__mach_exception_raise_state_t__exception__defined) || \ - defined(__NDR_convert__char_rep__Request__mach_exception_raise_state_t__code__defined) || \ - 0 || \ - defined(__NDR_convert__char_rep__Request__mach_exception_raise_state_t__flavor__defined) || \ - defined(__NDR_convert__char_rep__Request__mach_exception_raise_state_t__old_state__defined) || \ - 0 - if (In0P->NDR.char_rep != NDR_record.char_rep) { - #if defined(__NDR_convert__char_rep__Request__mach_exception_raise_state_t__exception__defined) - __NDR_convert__char_rep__Request__mach_exception_raise_state_t__exception(&In0P->exception, In0P->NDR.char_rep); - #endif /* __NDR_convert__char_rep__Request__mach_exception_raise_state_t__exception__defined */ - #if defined(__NDR_convert__char_rep__Request__mach_exception_raise_state_t__code__defined) - __NDR_convert__char_rep__Request__mach_exception_raise_state_t__code(&In0P->code, In0P->NDR.char_rep, In0P->codeCnt); - #endif /* __NDR_convert__char_rep__Request__mach_exception_raise_state_t__code__defined */ - #if defined(__NDR_convert__char_rep__Request__mach_exception_raise_state_t__flavor__defined) - __NDR_convert__char_rep__Request__mach_exception_raise_state_t__flavor(&In1P->flavor, In0P->NDR.char_rep); - #endif /* __NDR_convert__char_rep__Request__mach_exception_raise_state_t__flavor__defined */ - #if defined(__NDR_convert__char_rep__Request__mach_exception_raise_state_t__old_state__defined) - __NDR_convert__char_rep__Request__mach_exception_raise_state_t__old_state(&In1P->old_state, In0P->NDR.char_rep, In1P->old_stateCnt); - #endif /* __NDR_convert__char_rep__Request__mach_exception_raise_state_t__old_state__defined */ - } - #endif /* defined(__NDR_convert__char_rep...) */ - - #if defined(__NDR_convert__float_rep__Request__mach_exception_raise_state_t__exception__defined) || \ - defined(__NDR_convert__float_rep__Request__mach_exception_raise_state_t__code__defined) || \ - 0 || \ - defined(__NDR_convert__float_rep__Request__mach_exception_raise_state_t__flavor__defined) || \ - defined(__NDR_convert__float_rep__Request__mach_exception_raise_state_t__old_state__defined) || \ - 0 - if (In0P->NDR.float_rep != NDR_record.float_rep) { - #if defined(__NDR_convert__float_rep__Request__mach_exception_raise_state_t__exception__defined) - __NDR_convert__float_rep__Request__mach_exception_raise_state_t__exception(&In0P->exception, In0P->NDR.float_rep); - #endif /* __NDR_convert__float_rep__Request__mach_exception_raise_state_t__exception__defined */ - #if defined(__NDR_convert__float_rep__Request__mach_exception_raise_state_t__code__defined) - __NDR_convert__float_rep__Request__mach_exception_raise_state_t__code(&In0P->code, In0P->NDR.float_rep, In0P->codeCnt); - #endif /* __NDR_convert__float_rep__Request__mach_exception_raise_state_t__code__defined */ - #if defined(__NDR_convert__float_rep__Request__mach_exception_raise_state_t__flavor__defined) - __NDR_convert__float_rep__Request__mach_exception_raise_state_t__flavor(&In1P->flavor, In0P->NDR.float_rep); - #endif /* __NDR_convert__float_rep__Request__mach_exception_raise_state_t__flavor__defined */ - #if defined(__NDR_convert__float_rep__Request__mach_exception_raise_state_t__old_state__defined) - __NDR_convert__float_rep__Request__mach_exception_raise_state_t__old_state(&In1P->old_state, In0P->NDR.float_rep, In1P->old_stateCnt); - #endif /* __NDR_convert__float_rep__Request__mach_exception_raise_state_t__old_state__defined */ - } - #endif /* defined(__NDR_convert__float_rep...) */ - - return MACH_MSG_SUCCESS; -} -#endif /* !defined(__MIG_check__Request__mach_exception_raise_state_t__defined) */ -#endif /* __MIG_check__Request__mach_exc_subsystem__ */ -#endif /* ( __MigTypeCheck || __NDR_convert__ ) */ - - -/* Routine mach_exception_raise_state_OVR */ -#ifdef mig_external -mig_external -#else -extern -#endif /* mig_external */ -kern_return_t catch_mach_exception_raise_state_OVR -( - mach_port_t exception_port, - exception_type_t exception, - const mach_exception_data_t code, - mach_msg_type_number_t codeCnt, - int *flavor, - const thread_state_t old_state, - mach_msg_type_number_t old_stateCnt, - thread_state_t new_state, - mach_msg_type_number_t *new_stateCnt -); - -/* Routine _Xmach_exception_raise_state_OVR */ -mig_internal novalue _Xmach_exception_raise_state_OVR - (mach_msg_header_t *InHeadP, mach_msg_header_t *OutHeadP) -{ - - #ifdef __MigPackStructs - #pragma pack(4) - #endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - exception_type_t exception; - mach_msg_type_number_t codeCnt; - int64_t code[2]; - int flavor; - mach_msg_type_number_t old_stateCnt; - natural_t old_state[144]; - mach_msg_trailer_t trailer; - } Request; - #ifdef __MigPackStructs - #pragma pack() - #endif - typedef __Request__mach_exception_raise_state_t __Request; - typedef __Reply__mach_exception_raise_state_t Reply; - - /* - * typedef struct { - * mach_msg_header_t Head; - * NDR_record_t NDR; - * kern_return_t RetCode; - * } mig_reply_error_t; - */ - - Request *In0P = (Request *) InHeadP; - Request *In1P; - Reply *OutP = (Reply *) OutHeadP; - #ifdef __MIG_check__Request__mach_exception_raise_state_t__defined - kern_return_t check_result; - #endif /* __MIG_check__Request__mach_exception_raise_state_t__defined */ - - __DeclareRcvRpc(2406, "mach_exception_raise_state_OVR") - __BeforeRcvRpc(2406, "mach_exception_raise_state_OVR") - - #if defined(__MIG_check__Request__mach_exception_raise_state_t__defined) - check_result = __MIG_check__Request__mach_exception_raise_state_t_OVR((__Request *)In0P, (__Request **)&In1P); - if (check_result != MACH_MSG_SUCCESS) - { MIG_RETURN_ERROR(OutP, check_result); } - #endif /* defined(__MIG_check__Request__mach_exception_raise_state_t__defined) */ - - OutP->new_stateCnt = 144; - - OutP->RetCode = catch_mach_exception_raise_state_OVR(In0P->Head.msgh_request_port, In0P->exception, In0P->code, In0P->codeCnt, &In1P->flavor, In1P->old_state, In1P->old_stateCnt, OutP->new_state, &OutP->new_stateCnt); - if (OutP->RetCode != KERN_SUCCESS) { - MIG_RETURN_ERROR(OutP, OutP->RetCode); - } - - OutP->NDR = NDR_record; - - - OutP->flavor = In1P->flavor; - OutP->Head.msgh_size = (mach_msg_size_t)(sizeof(Reply) - 576) + (((4 * OutP->new_stateCnt))); - - __AfterRcvRpc(2406, "mach_exception_raise_state_OVR") -} - -#if ( __MigTypeCheck || __NDR_convert__ ) -#if __MIG_check__Request__mach_exc_subsystem__ -#if !defined(__MIG_check__Request__mach_exception_raise_state_identity_t__defined) -#define __MIG_check__Request__mach_exception_raise_state_identity_t__defined -#ifndef __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__exception__defined -#if defined(__NDR_convert__int_rep__mach_exc__exception_type_t__defined) -#define __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__exception__defined -#define __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__exception(a, f) \ - __NDR_convert__int_rep__mach_exc__exception_type_t((exception_type_t *)(a), f) -#elif defined(__NDR_convert__int_rep__exception_type_t__defined) -#define __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__exception__defined -#define __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__exception(a, f) \ - __NDR_convert__int_rep__exception_type_t((exception_type_t *)(a), f) -#elif defined(__NDR_convert__int_rep__mach_exc__int__defined) -#define __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__exception__defined -#define __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__exception(a, f) \ - __NDR_convert__int_rep__mach_exc__int((int *)(a), f) -#elif defined(__NDR_convert__int_rep__int__defined) -#define __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__exception__defined -#define __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__exception(a, f) \ - __NDR_convert__int_rep__int((int *)(a), f) -#elif defined(__NDR_convert__int_rep__mach_exc__int32_t__defined) -#define __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__exception__defined -#define __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__exception(a, f) \ - __NDR_convert__int_rep__mach_exc__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__int_rep__int32_t__defined) -#define __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__exception__defined -#define __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__exception(a, f) \ - __NDR_convert__int_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__exception__defined */ - -#ifndef __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__code__defined -#if defined(__NDR_convert__int_rep__mach_exc__mach_exception_data_t__defined) -#define __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__code__defined -#define __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__code(a, f, c) \ - __NDR_convert__int_rep__mach_exc__mach_exception_data_t((mach_exception_data_t *)(a), f, c) -#elif defined(__NDR_convert__int_rep__mach_exception_data_t__defined) -#define __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__code__defined -#define __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__code(a, f, c) \ - __NDR_convert__int_rep__mach_exception_data_t((mach_exception_data_t *)(a), f, c) -#elif defined(__NDR_convert__int_rep__mach_exc__int64_t__defined) -#define __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__code__defined -#define __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__code(a, f, c) \ - __NDR_convert__ARRAY((int64_t *)(a), f, c, __NDR_convert__int_rep__mach_exc__int64_t) -#elif defined(__NDR_convert__int_rep__int64_t__defined) -#define __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__code__defined -#define __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__code(a, f, c) \ - __NDR_convert__ARRAY((int64_t *)(a), f, c, __NDR_convert__int_rep__int64_t) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__code__defined */ - -#ifndef __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__codeCnt__defined -#if defined(__NDR_convert__int_rep__mach_exc__mach_msg_type_number_t__defined) -#define __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__codeCnt__defined -#define __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__codeCnt(a, f) \ - __NDR_convert__int_rep__mach_exc__mach_msg_type_number_t((mach_msg_type_number_t *)(a), f) -#elif defined(__NDR_convert__int_rep__mach_msg_type_number_t__defined) -#define __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__codeCnt__defined -#define __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__codeCnt(a, f) \ - __NDR_convert__int_rep__mach_msg_type_number_t((mach_msg_type_number_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__codeCnt__defined */ - -#ifndef __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__flavor__defined -#if defined(__NDR_convert__int_rep__mach_exc__int__defined) -#define __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__flavor__defined -#define __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__flavor(a, f) \ - __NDR_convert__int_rep__mach_exc__int((int *)(a), f) -#elif defined(__NDR_convert__int_rep__int__defined) -#define __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__flavor__defined -#define __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__flavor(a, f) \ - __NDR_convert__int_rep__int((int *)(a), f) -#elif defined(__NDR_convert__int_rep__mach_exc__int32_t__defined) -#define __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__flavor__defined -#define __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__flavor(a, f) \ - __NDR_convert__int_rep__mach_exc__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__int_rep__int32_t__defined) -#define __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__flavor__defined -#define __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__flavor(a, f) \ - __NDR_convert__int_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__flavor__defined */ - -#ifndef __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__old_state__defined -#if defined(__NDR_convert__int_rep__mach_exc__thread_state_t__defined) -#define __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__old_state__defined -#define __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__old_state(a, f, c) \ - __NDR_convert__int_rep__mach_exc__thread_state_t((thread_state_t *)(a), f, c) -#elif defined(__NDR_convert__int_rep__thread_state_t__defined) -#define __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__old_state__defined -#define __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__old_state(a, f, c) \ - __NDR_convert__int_rep__thread_state_t((thread_state_t *)(a), f, c) -#elif defined(__NDR_convert__int_rep__mach_exc__natural_t__defined) -#define __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__old_state__defined -#define __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__old_state(a, f, c) \ - __NDR_convert__ARRAY((natural_t *)(a), f, c, __NDR_convert__int_rep__mach_exc__natural_t) -#elif defined(__NDR_convert__int_rep__natural_t__defined) -#define __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__old_state__defined -#define __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__old_state(a, f, c) \ - __NDR_convert__ARRAY((natural_t *)(a), f, c, __NDR_convert__int_rep__natural_t) -#elif defined(__NDR_convert__int_rep__mach_exc__uint32_t__defined) -#define __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__old_state__defined -#define __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__old_state(a, f, c) \ - __NDR_convert__ARRAY((uint32_t *)(a), f, c, __NDR_convert__int_rep__mach_exc__uint32_t) -#elif defined(__NDR_convert__int_rep__uint32_t__defined) -#define __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__old_state__defined -#define __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__old_state(a, f, c) \ - __NDR_convert__ARRAY((uint32_t *)(a), f, c, __NDR_convert__int_rep__uint32_t) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__old_state__defined */ - -#ifndef __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__old_stateCnt__defined -#if defined(__NDR_convert__int_rep__mach_exc__mach_msg_type_number_t__defined) -#define __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__old_stateCnt__defined -#define __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__old_stateCnt(a, f) \ - __NDR_convert__int_rep__mach_exc__mach_msg_type_number_t((mach_msg_type_number_t *)(a), f) -#elif defined(__NDR_convert__int_rep__mach_msg_type_number_t__defined) -#define __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__old_stateCnt__defined -#define __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__old_stateCnt(a, f) \ - __NDR_convert__int_rep__mach_msg_type_number_t((mach_msg_type_number_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__old_stateCnt__defined */ - -#ifndef __NDR_convert__char_rep__Request__mach_exception_raise_state_identity_t__exception__defined -#if defined(__NDR_convert__char_rep__mach_exc__exception_type_t__defined) -#define __NDR_convert__char_rep__Request__mach_exception_raise_state_identity_t__exception__defined -#define __NDR_convert__char_rep__Request__mach_exception_raise_state_identity_t__exception(a, f) \ - __NDR_convert__char_rep__mach_exc__exception_type_t((exception_type_t *)(a), f) -#elif defined(__NDR_convert__char_rep__exception_type_t__defined) -#define __NDR_convert__char_rep__Request__mach_exception_raise_state_identity_t__exception__defined -#define __NDR_convert__char_rep__Request__mach_exception_raise_state_identity_t__exception(a, f) \ - __NDR_convert__char_rep__exception_type_t((exception_type_t *)(a), f) -#elif defined(__NDR_convert__char_rep__mach_exc__int__defined) -#define __NDR_convert__char_rep__Request__mach_exception_raise_state_identity_t__exception__defined -#define __NDR_convert__char_rep__Request__mach_exception_raise_state_identity_t__exception(a, f) \ - __NDR_convert__char_rep__mach_exc__int((int *)(a), f) -#elif defined(__NDR_convert__char_rep__int__defined) -#define __NDR_convert__char_rep__Request__mach_exception_raise_state_identity_t__exception__defined -#define __NDR_convert__char_rep__Request__mach_exception_raise_state_identity_t__exception(a, f) \ - __NDR_convert__char_rep__int((int *)(a), f) -#elif defined(__NDR_convert__char_rep__mach_exc__int32_t__defined) -#define __NDR_convert__char_rep__Request__mach_exception_raise_state_identity_t__exception__defined -#define __NDR_convert__char_rep__Request__mach_exception_raise_state_identity_t__exception(a, f) \ - __NDR_convert__char_rep__mach_exc__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__char_rep__int32_t__defined) -#define __NDR_convert__char_rep__Request__mach_exception_raise_state_identity_t__exception__defined -#define __NDR_convert__char_rep__Request__mach_exception_raise_state_identity_t__exception(a, f) \ - __NDR_convert__char_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__char_rep__Request__mach_exception_raise_state_identity_t__exception__defined */ - -#ifndef __NDR_convert__char_rep__Request__mach_exception_raise_state_identity_t__code__defined -#if defined(__NDR_convert__char_rep__mach_exc__mach_exception_data_t__defined) -#define __NDR_convert__char_rep__Request__mach_exception_raise_state_identity_t__code__defined -#define __NDR_convert__char_rep__Request__mach_exception_raise_state_identity_t__code(a, f, c) \ - __NDR_convert__char_rep__mach_exc__mach_exception_data_t((mach_exception_data_t *)(a), f, c) -#elif defined(__NDR_convert__char_rep__mach_exception_data_t__defined) -#define __NDR_convert__char_rep__Request__mach_exception_raise_state_identity_t__code__defined -#define __NDR_convert__char_rep__Request__mach_exception_raise_state_identity_t__code(a, f, c) \ - __NDR_convert__char_rep__mach_exception_data_t((mach_exception_data_t *)(a), f, c) -#elif defined(__NDR_convert__char_rep__mach_exc__int64_t__defined) -#define __NDR_convert__char_rep__Request__mach_exception_raise_state_identity_t__code__defined -#define __NDR_convert__char_rep__Request__mach_exception_raise_state_identity_t__code(a, f, c) \ - __NDR_convert__ARRAY((int64_t *)(a), f, c, __NDR_convert__char_rep__mach_exc__int64_t) -#elif defined(__NDR_convert__char_rep__int64_t__defined) -#define __NDR_convert__char_rep__Request__mach_exception_raise_state_identity_t__code__defined -#define __NDR_convert__char_rep__Request__mach_exception_raise_state_identity_t__code(a, f, c) \ - __NDR_convert__ARRAY((int64_t *)(a), f, c, __NDR_convert__char_rep__int64_t) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__char_rep__Request__mach_exception_raise_state_identity_t__code__defined */ - -#ifndef __NDR_convert__char_rep__Request__mach_exception_raise_state_identity_t__flavor__defined -#if defined(__NDR_convert__char_rep__mach_exc__int__defined) -#define __NDR_convert__char_rep__Request__mach_exception_raise_state_identity_t__flavor__defined -#define __NDR_convert__char_rep__Request__mach_exception_raise_state_identity_t__flavor(a, f) \ - __NDR_convert__char_rep__mach_exc__int((int *)(a), f) -#elif defined(__NDR_convert__char_rep__int__defined) -#define __NDR_convert__char_rep__Request__mach_exception_raise_state_identity_t__flavor__defined -#define __NDR_convert__char_rep__Request__mach_exception_raise_state_identity_t__flavor(a, f) \ - __NDR_convert__char_rep__int((int *)(a), f) -#elif defined(__NDR_convert__char_rep__mach_exc__int32_t__defined) -#define __NDR_convert__char_rep__Request__mach_exception_raise_state_identity_t__flavor__defined -#define __NDR_convert__char_rep__Request__mach_exception_raise_state_identity_t__flavor(a, f) \ - __NDR_convert__char_rep__mach_exc__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__char_rep__int32_t__defined) -#define __NDR_convert__char_rep__Request__mach_exception_raise_state_identity_t__flavor__defined -#define __NDR_convert__char_rep__Request__mach_exception_raise_state_identity_t__flavor(a, f) \ - __NDR_convert__char_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__char_rep__Request__mach_exception_raise_state_identity_t__flavor__defined */ - -#ifndef __NDR_convert__char_rep__Request__mach_exception_raise_state_identity_t__old_state__defined -#if defined(__NDR_convert__char_rep__mach_exc__thread_state_t__defined) -#define __NDR_convert__char_rep__Request__mach_exception_raise_state_identity_t__old_state__defined -#define __NDR_convert__char_rep__Request__mach_exception_raise_state_identity_t__old_state(a, f, c) \ - __NDR_convert__char_rep__mach_exc__thread_state_t((thread_state_t *)(a), f, c) -#elif defined(__NDR_convert__char_rep__thread_state_t__defined) -#define __NDR_convert__char_rep__Request__mach_exception_raise_state_identity_t__old_state__defined -#define __NDR_convert__char_rep__Request__mach_exception_raise_state_identity_t__old_state(a, f, c) \ - __NDR_convert__char_rep__thread_state_t((thread_state_t *)(a), f, c) -#elif defined(__NDR_convert__char_rep__mach_exc__natural_t__defined) -#define __NDR_convert__char_rep__Request__mach_exception_raise_state_identity_t__old_state__defined -#define __NDR_convert__char_rep__Request__mach_exception_raise_state_identity_t__old_state(a, f, c) \ - __NDR_convert__ARRAY((natural_t *)(a), f, c, __NDR_convert__char_rep__mach_exc__natural_t) -#elif defined(__NDR_convert__char_rep__natural_t__defined) -#define __NDR_convert__char_rep__Request__mach_exception_raise_state_identity_t__old_state__defined -#define __NDR_convert__char_rep__Request__mach_exception_raise_state_identity_t__old_state(a, f, c) \ - __NDR_convert__ARRAY((natural_t *)(a), f, c, __NDR_convert__char_rep__natural_t) -#elif defined(__NDR_convert__char_rep__mach_exc__uint32_t__defined) -#define __NDR_convert__char_rep__Request__mach_exception_raise_state_identity_t__old_state__defined -#define __NDR_convert__char_rep__Request__mach_exception_raise_state_identity_t__old_state(a, f, c) \ - __NDR_convert__ARRAY((uint32_t *)(a), f, c, __NDR_convert__char_rep__mach_exc__uint32_t) -#elif defined(__NDR_convert__char_rep__uint32_t__defined) -#define __NDR_convert__char_rep__Request__mach_exception_raise_state_identity_t__old_state__defined -#define __NDR_convert__char_rep__Request__mach_exception_raise_state_identity_t__old_state(a, f, c) \ - __NDR_convert__ARRAY((uint32_t *)(a), f, c, __NDR_convert__char_rep__uint32_t) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__char_rep__Request__mach_exception_raise_state_identity_t__old_state__defined */ - -#ifndef __NDR_convert__float_rep__Request__mach_exception_raise_state_identity_t__exception__defined -#if defined(__NDR_convert__float_rep__mach_exc__exception_type_t__defined) -#define __NDR_convert__float_rep__Request__mach_exception_raise_state_identity_t__exception__defined -#define __NDR_convert__float_rep__Request__mach_exception_raise_state_identity_t__exception(a, f) \ - __NDR_convert__float_rep__mach_exc__exception_type_t((exception_type_t *)(a), f) -#elif defined(__NDR_convert__float_rep__exception_type_t__defined) -#define __NDR_convert__float_rep__Request__mach_exception_raise_state_identity_t__exception__defined -#define __NDR_convert__float_rep__Request__mach_exception_raise_state_identity_t__exception(a, f) \ - __NDR_convert__float_rep__exception_type_t((exception_type_t *)(a), f) -#elif defined(__NDR_convert__float_rep__mach_exc__int__defined) -#define __NDR_convert__float_rep__Request__mach_exception_raise_state_identity_t__exception__defined -#define __NDR_convert__float_rep__Request__mach_exception_raise_state_identity_t__exception(a, f) \ - __NDR_convert__float_rep__mach_exc__int((int *)(a), f) -#elif defined(__NDR_convert__float_rep__int__defined) -#define __NDR_convert__float_rep__Request__mach_exception_raise_state_identity_t__exception__defined -#define __NDR_convert__float_rep__Request__mach_exception_raise_state_identity_t__exception(a, f) \ - __NDR_convert__float_rep__int((int *)(a), f) -#elif defined(__NDR_convert__float_rep__mach_exc__int32_t__defined) -#define __NDR_convert__float_rep__Request__mach_exception_raise_state_identity_t__exception__defined -#define __NDR_convert__float_rep__Request__mach_exception_raise_state_identity_t__exception(a, f) \ - __NDR_convert__float_rep__mach_exc__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__float_rep__int32_t__defined) -#define __NDR_convert__float_rep__Request__mach_exception_raise_state_identity_t__exception__defined -#define __NDR_convert__float_rep__Request__mach_exception_raise_state_identity_t__exception(a, f) \ - __NDR_convert__float_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__float_rep__Request__mach_exception_raise_state_identity_t__exception__defined */ - -#ifndef __NDR_convert__float_rep__Request__mach_exception_raise_state_identity_t__code__defined -#if defined(__NDR_convert__float_rep__mach_exc__mach_exception_data_t__defined) -#define __NDR_convert__float_rep__Request__mach_exception_raise_state_identity_t__code__defined -#define __NDR_convert__float_rep__Request__mach_exception_raise_state_identity_t__code(a, f, c) \ - __NDR_convert__float_rep__mach_exc__mach_exception_data_t((mach_exception_data_t *)(a), f, c) -#elif defined(__NDR_convert__float_rep__mach_exception_data_t__defined) -#define __NDR_convert__float_rep__Request__mach_exception_raise_state_identity_t__code__defined -#define __NDR_convert__float_rep__Request__mach_exception_raise_state_identity_t__code(a, f, c) \ - __NDR_convert__float_rep__mach_exception_data_t((mach_exception_data_t *)(a), f, c) -#elif defined(__NDR_convert__float_rep__mach_exc__int64_t__defined) -#define __NDR_convert__float_rep__Request__mach_exception_raise_state_identity_t__code__defined -#define __NDR_convert__float_rep__Request__mach_exception_raise_state_identity_t__code(a, f, c) \ - __NDR_convert__ARRAY((int64_t *)(a), f, c, __NDR_convert__float_rep__mach_exc__int64_t) -#elif defined(__NDR_convert__float_rep__int64_t__defined) -#define __NDR_convert__float_rep__Request__mach_exception_raise_state_identity_t__code__defined -#define __NDR_convert__float_rep__Request__mach_exception_raise_state_identity_t__code(a, f, c) \ - __NDR_convert__ARRAY((int64_t *)(a), f, c, __NDR_convert__float_rep__int64_t) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__float_rep__Request__mach_exception_raise_state_identity_t__code__defined */ - -#ifndef __NDR_convert__float_rep__Request__mach_exception_raise_state_identity_t__flavor__defined -#if defined(__NDR_convert__float_rep__mach_exc__int__defined) -#define __NDR_convert__float_rep__Request__mach_exception_raise_state_identity_t__flavor__defined -#define __NDR_convert__float_rep__Request__mach_exception_raise_state_identity_t__flavor(a, f) \ - __NDR_convert__float_rep__mach_exc__int((int *)(a), f) -#elif defined(__NDR_convert__float_rep__int__defined) -#define __NDR_convert__float_rep__Request__mach_exception_raise_state_identity_t__flavor__defined -#define __NDR_convert__float_rep__Request__mach_exception_raise_state_identity_t__flavor(a, f) \ - __NDR_convert__float_rep__int((int *)(a), f) -#elif defined(__NDR_convert__float_rep__mach_exc__int32_t__defined) -#define __NDR_convert__float_rep__Request__mach_exception_raise_state_identity_t__flavor__defined -#define __NDR_convert__float_rep__Request__mach_exception_raise_state_identity_t__flavor(a, f) \ - __NDR_convert__float_rep__mach_exc__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__float_rep__int32_t__defined) -#define __NDR_convert__float_rep__Request__mach_exception_raise_state_identity_t__flavor__defined -#define __NDR_convert__float_rep__Request__mach_exception_raise_state_identity_t__flavor(a, f) \ - __NDR_convert__float_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__float_rep__Request__mach_exception_raise_state_identity_t__flavor__defined */ - -#ifndef __NDR_convert__float_rep__Request__mach_exception_raise_state_identity_t__old_state__defined -#if defined(__NDR_convert__float_rep__mach_exc__thread_state_t__defined) -#define __NDR_convert__float_rep__Request__mach_exception_raise_state_identity_t__old_state__defined -#define __NDR_convert__float_rep__Request__mach_exception_raise_state_identity_t__old_state(a, f, c) \ - __NDR_convert__float_rep__mach_exc__thread_state_t((thread_state_t *)(a), f, c) -#elif defined(__NDR_convert__float_rep__thread_state_t__defined) -#define __NDR_convert__float_rep__Request__mach_exception_raise_state_identity_t__old_state__defined -#define __NDR_convert__float_rep__Request__mach_exception_raise_state_identity_t__old_state(a, f, c) \ - __NDR_convert__float_rep__thread_state_t((thread_state_t *)(a), f, c) -#elif defined(__NDR_convert__float_rep__mach_exc__natural_t__defined) -#define __NDR_convert__float_rep__Request__mach_exception_raise_state_identity_t__old_state__defined -#define __NDR_convert__float_rep__Request__mach_exception_raise_state_identity_t__old_state(a, f, c) \ - __NDR_convert__ARRAY((natural_t *)(a), f, c, __NDR_convert__float_rep__mach_exc__natural_t) -#elif defined(__NDR_convert__float_rep__natural_t__defined) -#define __NDR_convert__float_rep__Request__mach_exception_raise_state_identity_t__old_state__defined -#define __NDR_convert__float_rep__Request__mach_exception_raise_state_identity_t__old_state(a, f, c) \ - __NDR_convert__ARRAY((natural_t *)(a), f, c, __NDR_convert__float_rep__natural_t) -#elif defined(__NDR_convert__float_rep__mach_exc__uint32_t__defined) -#define __NDR_convert__float_rep__Request__mach_exception_raise_state_identity_t__old_state__defined -#define __NDR_convert__float_rep__Request__mach_exception_raise_state_identity_t__old_state(a, f, c) \ - __NDR_convert__ARRAY((uint32_t *)(a), f, c, __NDR_convert__float_rep__mach_exc__uint32_t) -#elif defined(__NDR_convert__float_rep__uint32_t__defined) -#define __NDR_convert__float_rep__Request__mach_exception_raise_state_identity_t__old_state__defined -#define __NDR_convert__float_rep__Request__mach_exception_raise_state_identity_t__old_state(a, f, c) \ - __NDR_convert__ARRAY((uint32_t *)(a), f, c, __NDR_convert__float_rep__uint32_t) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__float_rep__Request__mach_exception_raise_state_identity_t__old_state__defined */ - - -mig_internal kern_return_t __MIG_check__Request__mach_exception_raise_state_identity_t_OVR(__attribute__((__unused__)) __Request__mach_exception_raise_state_identity_t *In0P, __attribute__((__unused__)) __Request__mach_exception_raise_state_identity_t **In1PP) -{ - const size_t sizeofRequest = sizeof(__Request__mach_exception_raise_state_identity_t); - - typedef __Request__mach_exception_raise_state_identity_t __Request; - __Request *In1P; - #if __MigTypeCheck - unsigned int msgh_size; - #endif /* __MigTypeCheck */ - unsigned int msgh_size_delta; - - #if __MigTypeCheck - msgh_size = In0P->Head.msgh_size; - if (!(In0P->Head.msgh_bits & MACH_MSGH_BITS_COMPLEX) || - (In0P->msgh_body.msgh_descriptor_count != 2) || - (msgh_size < (mach_msg_size_t)(sizeofRequest - 592)) || (msgh_size > (mach_msg_size_t)sizeofRequest)) - return MIG_BAD_ARGUMENTS; - #endif /* __MigTypeCheck */ - - #if __MigTypeCheck - if (In0P->thread.type != MACH_MSG_PORT_DESCRIPTOR || - In0P->thread.disposition != 17) - return MIG_TYPE_ERROR; - #endif /* __MigTypeCheck */ - - #if __MigTypeCheck - if (In0P->task.type != MACH_MSG_PORT_DESCRIPTOR || - In0P->task.disposition != 17) - return MIG_TYPE_ERROR; - #endif /* __MigTypeCheck */ - - #if defined(__NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__codeCnt__defined) - if (In0P->NDR.int_rep != NDR_record.int_rep) - __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__codeCnt(&In0P->codeCnt, In0P->NDR.int_rep); - #endif /* __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__codeCnt__defined */ - msgh_size_delta = (8 * In0P->codeCnt); - #if __MigTypeCheck - if ( In0P->codeCnt > 2 ) - return MIG_BAD_ARGUMENTS; - if (((msgh_size - (mach_msg_size_t)(sizeofRequest - 592)) / 8 < In0P->codeCnt) || - (msgh_size < (mach_msg_size_t)(sizeofRequest - 592) + (8 * In0P->codeCnt))) - return MIG_BAD_ARGUMENTS; - msgh_size -= msgh_size_delta; - #endif /* __MigTypeCheck */ - - *In1PP = In1P = (__Request *) ((pointer_t) In0P + msgh_size_delta - 16); - - #if defined(__NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__old_stateCnt__defined) - if (In0P->NDR.int_rep != NDR_record.int_rep) - __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__old_stateCnt(&In1P->old_stateCnt, In1P->NDR.int_rep); - #endif /* __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__old_stateCnt__defined */ - #if __MigTypeCheck - if ( In1P->old_stateCnt > 144 ) - return MIG_BAD_ARGUMENTS; - if (((msgh_size - (mach_msg_size_t)(sizeofRequest - 592)) / 4 != In1P->old_stateCnt) || - (msgh_size != (mach_msg_size_t)(sizeofRequest - 592) + (4 * In1P->old_stateCnt))) - return MIG_BAD_ARGUMENTS; - #endif /* __MigTypeCheck */ - - #if defined(__NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__exception__defined) || \ - defined(__NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__code__defined) || \ - defined(__NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__codeCnt__defined) || \ - defined(__NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__flavor__defined) || \ - defined(__NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__old_state__defined) || \ - defined(__NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__old_stateCnt__defined) - if (In0P->NDR.int_rep != NDR_record.int_rep) { - #if defined(__NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__exception__defined) - __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__exception(&In0P->exception, In0P->NDR.int_rep); - #endif /* __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__exception__defined */ - #if defined(__NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__code__defined) - __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__code(&In0P->code, In0P->NDR.int_rep, In0P->codeCnt); - #endif /* __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__code__defined */ - #if defined(__NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__flavor__defined) - __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__flavor(&In1P->flavor, In0P->NDR.int_rep); - #endif /* __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__flavor__defined */ - #if defined(__NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__old_state__defined) - __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__old_state(&In1P->old_state, In0P->NDR.int_rep, In1P->old_stateCnt); - #endif /* __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__old_state__defined */ - } - #endif /* defined(__NDR_convert__int_rep...) */ - - #if defined(__NDR_convert__char_rep__Request__mach_exception_raise_state_identity_t__exception__defined) || \ - defined(__NDR_convert__char_rep__Request__mach_exception_raise_state_identity_t__code__defined) || \ - 0 || \ - defined(__NDR_convert__char_rep__Request__mach_exception_raise_state_identity_t__flavor__defined) || \ - defined(__NDR_convert__char_rep__Request__mach_exception_raise_state_identity_t__old_state__defined) || \ - 0 - if (In0P->NDR.char_rep != NDR_record.char_rep) { - #if defined(__NDR_convert__char_rep__Request__mach_exception_raise_state_identity_t__exception__defined) - __NDR_convert__char_rep__Request__mach_exception_raise_state_identity_t__exception(&In0P->exception, In0P->NDR.char_rep); - #endif /* __NDR_convert__char_rep__Request__mach_exception_raise_state_identity_t__exception__defined */ - #if defined(__NDR_convert__char_rep__Request__mach_exception_raise_state_identity_t__code__defined) - __NDR_convert__char_rep__Request__mach_exception_raise_state_identity_t__code(&In0P->code, In0P->NDR.char_rep, In0P->codeCnt); - #endif /* __NDR_convert__char_rep__Request__mach_exception_raise_state_identity_t__code__defined */ - #if defined(__NDR_convert__char_rep__Request__mach_exception_raise_state_identity_t__flavor__defined) - __NDR_convert__char_rep__Request__mach_exception_raise_state_identity_t__flavor(&In1P->flavor, In0P->NDR.char_rep); - #endif /* __NDR_convert__char_rep__Request__mach_exception_raise_state_identity_t__flavor__defined */ - #if defined(__NDR_convert__char_rep__Request__mach_exception_raise_state_identity_t__old_state__defined) - __NDR_convert__char_rep__Request__mach_exception_raise_state_identity_t__old_state(&In1P->old_state, In0P->NDR.char_rep, In1P->old_stateCnt); - #endif /* __NDR_convert__char_rep__Request__mach_exception_raise_state_identity_t__old_state__defined */ - } - #endif /* defined(__NDR_convert__char_rep...) */ - - #if defined(__NDR_convert__float_rep__Request__mach_exception_raise_state_identity_t__exception__defined) || \ - defined(__NDR_convert__float_rep__Request__mach_exception_raise_state_identity_t__code__defined) || \ - 0 || \ - defined(__NDR_convert__float_rep__Request__mach_exception_raise_state_identity_t__flavor__defined) || \ - defined(__NDR_convert__float_rep__Request__mach_exception_raise_state_identity_t__old_state__defined) || \ - 0 - if (In0P->NDR.float_rep != NDR_record.float_rep) { - #if defined(__NDR_convert__float_rep__Request__mach_exception_raise_state_identity_t__exception__defined) - __NDR_convert__float_rep__Request__mach_exception_raise_state_identity_t__exception(&In0P->exception, In0P->NDR.float_rep); - #endif /* __NDR_convert__float_rep__Request__mach_exception_raise_state_identity_t__exception__defined */ - #if defined(__NDR_convert__float_rep__Request__mach_exception_raise_state_identity_t__code__defined) - __NDR_convert__float_rep__Request__mach_exception_raise_state_identity_t__code(&In0P->code, In0P->NDR.float_rep, In0P->codeCnt); - #endif /* __NDR_convert__float_rep__Request__mach_exception_raise_state_identity_t__code__defined */ - #if defined(__NDR_convert__float_rep__Request__mach_exception_raise_state_identity_t__flavor__defined) - __NDR_convert__float_rep__Request__mach_exception_raise_state_identity_t__flavor(&In1P->flavor, In0P->NDR.float_rep); - #endif /* __NDR_convert__float_rep__Request__mach_exception_raise_state_identity_t__flavor__defined */ - #if defined(__NDR_convert__float_rep__Request__mach_exception_raise_state_identity_t__old_state__defined) - __NDR_convert__float_rep__Request__mach_exception_raise_state_identity_t__old_state(&In1P->old_state, In0P->NDR.float_rep, In1P->old_stateCnt); - #endif /* __NDR_convert__float_rep__Request__mach_exception_raise_state_identity_t__old_state__defined */ - } - #endif /* defined(__NDR_convert__float_rep...) */ - - return MACH_MSG_SUCCESS; -} -#endif /* !defined(__MIG_check__Request__mach_exception_raise_state_identity_t__defined) */ -#endif /* __MIG_check__Request__mach_exc_subsystem__ */ -#endif /* ( __MigTypeCheck || __NDR_convert__ ) */ - - -/* Routine catch_mach_exception_raise_state_identity_OVR */ -#ifdef mig_external -mig_external -#else -extern -#endif /* mig_external */ -kern_return_t catch_mach_exception_raise_state_identity_OVR -( - mach_port_t exception_port, - mach_port_t thread, - mach_port_t task, - exception_type_t exception, - mach_exception_data_t code, - mach_msg_type_number_t codeCnt, - int *flavor, - thread_state_t old_state, - mach_msg_type_number_t old_stateCnt, - thread_state_t new_state, - mach_msg_type_number_t *new_stateCnt -); - -/* Routine mach_exception_raise_state_identity_OVR */ -mig_internal novalue _Xmach_exception_raise_state_identity_OVR - (mach_msg_header_t *InHeadP, mach_msg_header_t *OutHeadP) -{ - - #ifdef __MigPackStructs - #pragma pack(4) - #endif - typedef struct { - mach_msg_header_t Head; - /* start of the kernel processed data */ - mach_msg_body_t msgh_body; - mach_msg_port_descriptor_t thread; - mach_msg_port_descriptor_t task; - /* end of the kernel processed data */ - NDR_record_t NDR; - exception_type_t exception; - mach_msg_type_number_t codeCnt; - int64_t code[2]; - int flavor; - mach_msg_type_number_t old_stateCnt; - natural_t old_state[144]; - mach_msg_trailer_t trailer; - } Request; - #ifdef __MigPackStructs - #pragma pack() - #endif - typedef __Request__mach_exception_raise_state_identity_t __Request; - typedef __Reply__mach_exception_raise_state_identity_t Reply; - - /* - * typedef struct { - * mach_msg_header_t Head; - * NDR_record_t NDR; - * kern_return_t RetCode; - * } mig_reply_error_t; - */ - - Request *In0P = (Request *) InHeadP; - Request *In1P; - Reply *OutP = (Reply *) OutHeadP; - #ifdef __MIG_check__Request__mach_exception_raise_state_identity_t__defined - kern_return_t check_result; - #endif /* __MIG_check__Request__mach_exception_raise_state_identity_t__defined */ - - __DeclareRcvRpc(2407, "mach_exception_raise_state_identity_OVR") - __BeforeRcvRpc(2407, "mach_exception_raise_state_identity_OVR") - - #if defined(__MIG_check__Request__mach_exception_raise_state_identity_t__defined) - check_result = __MIG_check__Request__mach_exception_raise_state_identity_t_OVR((__Request *)In0P, (__Request **)&In1P); - if (check_result != MACH_MSG_SUCCESS) - { MIG_RETURN_ERROR(OutP, check_result); } - #endif /* defined(__MIG_check__Request__mach_exception_raise_state_identity_t__defined) */ - - OutP->new_stateCnt = 144; - - OutP->RetCode = catch_mach_exception_raise_state_identity_OVR(In0P->Head.msgh_request_port, In0P->thread.name, In0P->task.name, In0P->exception, In0P->code, In0P->codeCnt, &In1P->flavor, In1P->old_state, In1P->old_stateCnt, OutP->new_state, &OutP->new_stateCnt); - if (OutP->RetCode != KERN_SUCCESS) { - MIG_RETURN_ERROR(OutP, OutP->RetCode); - } - - OutP->NDR = NDR_record; - - - OutP->flavor = In1P->flavor; - OutP->Head.msgh_size = (mach_msg_size_t)(sizeof(Reply) - 576) + (((4 * OutP->new_stateCnt))); - - __AfterRcvRpc(2407, "mach_exception_raise_state_identity_OVR") -} - - -#ifdef mig_external - mig_external -#else - extern -#endif /* mig_external */ - boolean_t mach_exc_server_OVR(mach_msg_header_t *InHeadP, mach_msg_header_t *OutHeadP); - -#ifdef mig_external - mig_external -#else - extern -#endif /* mig_external */ - mig_routine_t mach_exc_server_routine_OVR(mach_msg_header_t *InHeadP); - - -/* Description of this subsystem, for use in direct RPC */ -const struct catch_mach_exc_subsystem_OVR { - mig_server_routine_t server; /* Server routine */ - mach_msg_id_t start; /* Min routine number */ - mach_msg_id_t end; /* Max routine number + 1 */ - unsigned int maxsize; /* Max msg size */ - vm_address_t reserved; /* Reserved */ - struct routine_descriptor /*Array of routine descriptors */ - routine[3]; -} catch_mach_exc_subsystem_OVR = { - mach_exc_server_routine_OVR, - 2405, - 2408, - (mach_msg_size_t)sizeof(union __ReplyUnion__catch_mach_exc_subsystem), - (vm_address_t)0, - { - { (mig_impl_routine_t) 0, - (mig_stub_routine_t) _Xmach_exception_raise_OVR, 6, 0, (routine_arg_descriptor_t)0, (mach_msg_size_t)sizeof(__Reply__mach_exception_raise_t)}, - { (mig_impl_routine_t) 0, - (mig_stub_routine_t) _Xmach_exception_raise_state_OVR, 9, 0, (routine_arg_descriptor_t)0, (mach_msg_size_t)sizeof(__Reply__mach_exception_raise_state_t)}, - { (mig_impl_routine_t) 0, - (mig_stub_routine_t) _Xmach_exception_raise_state_identity_OVR, 11, 0, (routine_arg_descriptor_t)0, (mach_msg_size_t)sizeof(__Reply__mach_exception_raise_state_identity_t)}, - } -}; - -mig_external boolean_t mach_exc_server_OVR - (mach_msg_header_t *InHeadP, mach_msg_header_t *OutHeadP) -{ - /* - * typedef struct { - * mach_msg_header_t Head; - * NDR_record_t NDR; - * kern_return_t RetCode; - * } mig_reply_error_t; - */ - - register mig_routine_t routine; - - OutHeadP->msgh_bits = MACH_MSGH_BITS(MACH_MSGH_BITS_REPLY(InHeadP->msgh_bits), 0); - OutHeadP->msgh_remote_port = InHeadP->msgh_reply_port; - /* Minimal size: routine() will update it if different */ - OutHeadP->msgh_size = (mach_msg_size_t)sizeof(mig_reply_error_t); - OutHeadP->msgh_local_port = MACH_PORT_NULL; - OutHeadP->msgh_id = InHeadP->msgh_id + 100; - - if ((InHeadP->msgh_id > 2407) || (InHeadP->msgh_id < 2405) || - ((routine = catch_mach_exc_subsystem_OVR.routine[InHeadP->msgh_id - 2405].stub_routine) == 0)) - { - ((mig_reply_error_t *)OutHeadP)->NDR = NDR_record; - ((mig_reply_error_t *)OutHeadP)->RetCode = MIG_BAD_ID; - return FALSE; - } - (*routine) (InHeadP, OutHeadP); - return TRUE; -} - -mig_external mig_routine_t mach_exc_server_routine_OVR - (mach_msg_header_t *InHeadP) -{ - register int msgh_id; - - msgh_id = InHeadP->msgh_id - 2405; - - if ((msgh_id > 2) || (msgh_id < 0)) - return 0; - - return catch_mach_exc_subsystem_OVR.routine[msgh_id].stub_routine; -} - -#if defined(__cplusplus) - } /* extern "C" */ -#endif -/* End mach_excServer.c */ - - - diff --git a/LibOVR/Src/Kernel/OVR_mach_exc_OSX.h b/LibOVR/Src/Kernel/OVR_mach_exc_OSX.h deleted file mode 100644 index 4a1bcf0..0000000 --- a/LibOVR/Src/Kernel/OVR_mach_exc_OSX.h +++ /dev/null @@ -1,277 +0,0 @@ -#ifndef _mach_exc_user_ -#define _mach_exc_user_ - -/* Module mach_exc */ - -#include <string.h> -#include <mach/ndr.h> -#include <mach/boolean.h> -#include <mach/kern_return.h> -#include <mach/notify.h> -#include <mach/mach_types.h> -#include <mach/message.h> -#include <mach/mig_errors.h> -#include <mach/port.h> - -#ifdef AUTOTEST -#ifndef FUNCTION_PTR_T -#define FUNCTION_PTR_T -typedef void (*function_ptr_t)(mach_port_t, char *, mach_msg_type_number_t); -typedef struct { - char *name; - function_ptr_t function; -} function_table_entry; -typedef function_table_entry *function_table_t; -#endif /* FUNCTION_PTR_T */ -#endif /* AUTOTEST */ - -#ifndef mach_exc_MSG_COUNT -#define mach_exc_MSG_COUNT 3 -#endif /* mach_exc_MSG_COUNT */ - -#include <mach/std_types.h> -#include <mach/mig.h> -#include <mach/mig.h> -#include <mach/mach_types.h> - -#ifdef __BeforeMigUserHeader -__BeforeMigUserHeader -#endif /* __BeforeMigUserHeader */ - -#include <sys/cdefs.h> -__BEGIN_DECLS - -#if defined(__cplusplus) - extern "C" { -#endif - -/* Routine mach_exception_raise_OVR */ -#ifdef mig_external -mig_external -#else -extern -#endif /* mig_external */ -kern_return_t mach_exception_raise_OVR -( - mach_port_t exception_port, - mach_port_t thread, - mach_port_t task, - exception_type_t exception, - mach_exception_data_t code, - mach_msg_type_number_t codeCnt -); - -/* Routine mach_exception_raise_state_OVR */ -#ifdef mig_external -mig_external -#else -extern -#endif /* mig_external */ -kern_return_t mach_exception_raise_state_OVR -( - mach_port_t exception_port, - exception_type_t exception, - const mach_exception_data_t code, - mach_msg_type_number_t codeCnt, - int *flavor, - const thread_state_t old_state, - mach_msg_type_number_t old_stateCnt, - thread_state_t new_state, - mach_msg_type_number_t *new_stateCnt -); - -/* Routine mach_exception_raise_state_identity_OVR */ -#ifdef mig_external -mig_external -#else -extern -#endif /* mig_external */ -kern_return_t mach_exception_raise_state_identity_OVR -( - mach_port_t exception_port, - mach_port_t thread, - mach_port_t task, - exception_type_t exception, - mach_exception_data_t code, - mach_msg_type_number_t codeCnt, - int *flavor, - thread_state_t old_state, - mach_msg_type_number_t old_stateCnt, - thread_state_t new_state, - mach_msg_type_number_t *new_stateCnt -); - -__END_DECLS - -/********************** Caution **************************/ -/* The following data types should be used to calculate */ -/* maximum message sizes only. The actual message may be */ -/* smaller, and the position of the arguments within the */ -/* message layout may vary from what is presented here. */ -/* For example, if any of the arguments are variable- */ -/* sized, and less than the maximum is sent, the data */ -/* will be packed tight in the actual message to reduce */ -/* the presence of holes. */ -/********************** Caution **************************/ - -/* typedefs for all requests */ - -#ifndef __Request__mach_exc_subsystem__defined -#define __Request__mach_exc_subsystem__defined - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - /* start of the kernel processed data */ - mach_msg_body_t msgh_body; - mach_msg_port_descriptor_t thread; - mach_msg_port_descriptor_t task; - /* end of the kernel processed data */ - NDR_record_t NDR; - exception_type_t exception; - mach_msg_type_number_t codeCnt; - int64_t code[2]; - } __Request__mach_exception_raise_t; -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - exception_type_t exception; - mach_msg_type_number_t codeCnt; - int64_t code[2]; - int flavor; - mach_msg_type_number_t old_stateCnt; - natural_t old_state[144]; - } __Request__mach_exception_raise_state_t; -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - /* start of the kernel processed data */ - mach_msg_body_t msgh_body; - mach_msg_port_descriptor_t thread; - mach_msg_port_descriptor_t task; - /* end of the kernel processed data */ - NDR_record_t NDR; - exception_type_t exception; - mach_msg_type_number_t codeCnt; - int64_t code[2]; - int flavor; - mach_msg_type_number_t old_stateCnt; - natural_t old_state[144]; - } __Request__mach_exception_raise_state_identity_t; -#ifdef __MigPackStructs -#pragma pack() -#endif -#endif /* !__Request__mach_exc_subsystem__defined */ - -/* union of all requests */ - -#ifndef __RequestUnion__mach_exc_subsystem__defined -#define __RequestUnion__mach_exc_subsystem__defined -union __RequestUnion__mach_exc_subsystem { - __Request__mach_exception_raise_t Request_mach_exception_raise; - __Request__mach_exception_raise_state_t Request_mach_exception_raise_state; - __Request__mach_exception_raise_state_identity_t Request_mach_exception_raise_state_identity; -}; -#endif /* !__RequestUnion__mach_exc_subsystem__defined */ -/* typedefs for all replies */ - -#ifndef __Reply__mach_exc_subsystem__defined -#define __Reply__mach_exc_subsystem__defined - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - kern_return_t RetCode; - } __Reply__mach_exception_raise_t; -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - kern_return_t RetCode; - int flavor; - mach_msg_type_number_t new_stateCnt; - natural_t new_state[144]; - } __Reply__mach_exception_raise_state_t; -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - kern_return_t RetCode; - int flavor; - mach_msg_type_number_t new_stateCnt; - natural_t new_state[144]; - } __Reply__mach_exception_raise_state_identity_t; -#ifdef __MigPackStructs -#pragma pack() -#endif -#endif /* !__Reply__mach_exc_subsystem__defined */ - -/* union of all replies */ - -#ifndef __ReplyUnion__mach_exc_subsystem__defined -#define __ReplyUnion__mach_exc_subsystem__defined -union __ReplyUnion__mach_exc_subsystem { - __Reply__mach_exception_raise_t Reply_mach_exception_raise; - __Reply__mach_exception_raise_state_t Reply_mach_exception_raise_state; - __Reply__mach_exception_raise_state_identity_t Reply_mach_exception_raise_state_identity; -}; -#endif /* !__RequestUnion__mach_exc_subsystem__defined */ - -#ifndef subsystem_to_name_map_mach_exc -#define subsystem_to_name_map_mach_exc \ - { "mach_exception_raise_OVR", 2405 },\ - { "mach_exception_raise_state_OVR", 2406 },\ - { "mach_exception_raise_state_identity_OVR", 2407 } -#endif - -#ifdef __AfterMigUserHeader -__AfterMigUserHeader -#endif /* __AfterMigUserHeader */ - - -#ifdef mig_external -mig_external -#else -extern -#endif /* mig_external */ -boolean_t mach_exc_server_OVR( - mach_msg_header_t *InHeadP, - mach_msg_header_t *OutHeadP); - - -#if defined(__cplusplus) - } // extern"C" -#endif - - -#endif /* _mach_exc_user_ */ |