oculus1

changeset 3:b069a5c27388

added a couple more stuff, fixed all the LibOVR line endings
author John Tsiombikas <nuclear@member.fsf.org>
date Sun, 15 Sep 2013 04:10:05 +0300
parents 59fc487ba58e
children bb81990dc7c8
files libovr/Src/Kernel/OVR_Alg.cpp libovr/Src/Kernel/OVR_Alg.h libovr/Src/Kernel/OVR_Allocator.cpp libovr/Src/Kernel/OVR_Allocator.h libovr/Src/Kernel/OVR_Array.h libovr/Src/Kernel/OVR_Atomic.cpp libovr/Src/Kernel/OVR_Atomic.h libovr/Src/Kernel/OVR_Color.h libovr/Src/Kernel/OVR_ContainerAllocator.h libovr/Src/Kernel/OVR_File.cpp libovr/Src/Kernel/OVR_File.h libovr/Src/Kernel/OVR_FileFILE.cpp libovr/Src/Kernel/OVR_Hash.h libovr/Src/Kernel/OVR_KeyCodes.h libovr/Src/Kernel/OVR_List.h libovr/Src/Kernel/OVR_Log.cpp libovr/Src/Kernel/OVR_Log.h libovr/Src/Kernel/OVR_Math.cpp libovr/Src/Kernel/OVR_Math.h libovr/Src/Kernel/OVR_RefCount.cpp libovr/Src/Kernel/OVR_RefCount.h libovr/Src/Kernel/OVR_Std.cpp libovr/Src/Kernel/OVR_Std.h libovr/Src/Kernel/OVR_String.cpp libovr/Src/Kernel/OVR_String.h libovr/Src/Kernel/OVR_StringHash.h libovr/Src/Kernel/OVR_String_FormatUtil.cpp libovr/Src/Kernel/OVR_String_PathUtil.cpp libovr/Src/Kernel/OVR_SysFile.cpp libovr/Src/Kernel/OVR_SysFile.h libovr/Src/Kernel/OVR_System.cpp libovr/Src/Kernel/OVR_System.h libovr/Src/Kernel/OVR_Threads.h libovr/Src/Kernel/OVR_Timer.cpp libovr/Src/Kernel/OVR_Timer.h libovr/Src/Kernel/OVR_Types.h libovr/Src/Kernel/OVR_UTF8Util.cpp libovr/Src/Kernel/OVR_UTF8Util.h libovr/Src/Util/Util_LatencyTest.cpp libovr/Src/Util/Util_LatencyTest.h libovr/Src/Util/Util_MagCalibration.cpp libovr/Src/Util/Util_MagCalibration.h libovr/Src/Util/Util_Render_Stereo.cpp libovr/Src/Util/Util_Render_Stereo.h libovr/Src/linux/OVR_ThreadsPthread.cpp libovr/Src/osx/OVR_ThreadsPthread.cpp libovr/Src/win32/OVR_ThreadsWinAPI.cpp src/main.cc src/vr.cc src/vr.h src/vr_impl.h
diffstat 51 files changed, 19047 insertions(+), 67 deletions(-) [+]
line diff
     1.1 --- a/libovr/Src/Kernel/OVR_Alg.cpp	Sat Sep 14 17:51:03 2013 +0300
     1.2 +++ b/libovr/Src/Kernel/OVR_Alg.cpp	Sun Sep 15 04:10:05 2013 +0300
     1.3 @@ -1,1 +1,46 @@
     1.4 -/************************************************************************************
     1.5 
     1.6 Filename    :   OVR_Alg.cpp
     1.7 Content     :   Static lookup tables for Alg functions
     1.8 Created     :   September 19, 2012
     1.9 Notes       : 
    1.10 
    1.11 Copyright   :   Copyright 2012 Oculus VR, Inc. All Rights reserved.
    1.12 
    1.13 Use of this software is subject to the terms of the Oculus license
    1.14 agreement provided at the time of installation or download, or which
    1.15 otherwise accompanies this software in either electronic or hard copy form.
    1.16 
    1.17 ************************************************************************************/
    1.18 
    1.19 #include "OVR_Types.h"
    1.20 
    1.21 namespace OVR { namespace Alg {
    1.22 
    1.23 //------------------------------------------------------------------------
    1.24 extern const UByte UpperBitTable[256] =
    1.25 {
    1.26     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,
    1.27     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,
    1.28     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,
    1.29     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,
    1.30     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,
    1.31     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,
    1.32     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,
    1.33     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
    1.34 };
    1.35 
    1.36 extern const UByte LowerBitTable[256] =
    1.37 {
    1.38     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,
    1.39     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,
    1.40     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,
    1.41     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,
    1.42     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,
    1.43     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,
    1.44     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,
    1.45     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
    1.46 };
    1.47 
    1.48 
    1.49 }} // OVE::Alg
    1.50 \ No newline at end of file
    1.51 +/************************************************************************************
    1.52 +
    1.53 +Filename    :   OVR_Alg.cpp
    1.54 +Content     :   Static lookup tables for Alg functions
    1.55 +Created     :   September 19, 2012
    1.56 +Notes       : 
    1.57 +
    1.58 +Copyright   :   Copyright 2012 Oculus VR, Inc. All Rights reserved.
    1.59 +
    1.60 +Use of this software is subject to the terms of the Oculus license
    1.61 +agreement provided at the time of installation or download, or which
    1.62 +otherwise accompanies this software in either electronic or hard copy form.
    1.63 +
    1.64 +************************************************************************************/
    1.65 +
    1.66 +#include "OVR_Types.h"
    1.67 +
    1.68 +namespace OVR { namespace Alg {
    1.69 +
    1.70 +//------------------------------------------------------------------------
    1.71 +extern const UByte UpperBitTable[256] =
    1.72 +{
    1.73 +    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,
    1.74 +    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,
    1.75 +    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,
    1.76 +    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,
    1.77 +    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,
    1.78 +    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,
    1.79 +    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,
    1.80 +    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
    1.81 +};
    1.82 +
    1.83 +extern const UByte LowerBitTable[256] =
    1.84 +{
    1.85 +    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,
    1.86 +    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,
    1.87 +    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,
    1.88 +    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,
    1.89 +    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,
    1.90 +    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,
    1.91 +    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,
    1.92 +    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
    1.93 +};
    1.94 +
    1.95 +
    1.96 +}} // OVE::Alg
     2.1 --- a/libovr/Src/Kernel/OVR_Alg.h	Sat Sep 14 17:51:03 2013 +0300
     2.2 +++ b/libovr/Src/Kernel/OVR_Alg.h	Sun Sep 15 04:10:05 2013 +0300
     2.3 @@ -1,1 +1,953 @@
     2.4 -/************************************************************************************
     2.5 
     2.6 PublicHeader:   OVR.h
     2.7 Filename    :   OVR_Alg.h
     2.8 Content     :   Simple general purpose algorithms: Sort, Binary Search, etc.
     2.9 Created     :   September 19, 2012
    2.10 Notes       : 
    2.11 
    2.12 Copyright   :   Copyright 2012 Oculus VR, Inc. All Rights reserved.
    2.13 
    2.14 Use of this software is subject to the terms of the Oculus license
    2.15 agreement provided at the time of installation or download, or which
    2.16 otherwise accompanies this software in either electronic or hard copy form.
    2.17 
    2.18 ************************************************************************************/
    2.19 
    2.20 #ifndef OVR_Alg_h
    2.21 #define OVR_Alg_h
    2.22 
    2.23 #include "OVR_Types.h"
    2.24 #include <string.h>
    2.25 
    2.26 namespace OVR { namespace Alg {
    2.27 
    2.28 
    2.29 //-----------------------------------------------------------------------------------
    2.30 // ***** Operator extensions
    2.31 
    2.32 template <typename T> OVR_FORCE_INLINE void Swap(T &a, T &b) 
    2.33 {  T temp(a); a = b; b = temp; }
    2.34 
    2.35 
    2.36 // ***** min/max are not implemented in Visual Studio 6 standard STL
    2.37 
    2.38 template <typename T> OVR_FORCE_INLINE const T Min(const T a, const T b)
    2.39 { return (a < b) ? a : b; }
    2.40 
    2.41 template <typename T> OVR_FORCE_INLINE const T Max(const T a, const T b)
    2.42 { return (b < a) ? a : b; }
    2.43 
    2.44 template <typename T> OVR_FORCE_INLINE const T Clamp(const T v, const T minVal, const T maxVal)
    2.45 { return Max<T>(minVal, Min<T>(v, maxVal)); }
    2.46 
    2.47 template <typename T> OVR_FORCE_INLINE int     Chop(T f)
    2.48 { return (int)f; }
    2.49 
    2.50 template <typename T> OVR_FORCE_INLINE T       Lerp(T a, T b, T f) 
    2.51 { return (b - a) * f + a; }
    2.52 
    2.53 
    2.54 // These functions stand to fix a stupid VC++ warning (with /Wp64 on):
    2.55 // "warning C4267: 'argument' : conversion from 'size_t' to 'const unsigned', possible loss of data"
    2.56 // Use these functions instead of gmin/gmax if the argument has size
    2.57 // of the pointer to avoid the warning. Though, functionally they are
    2.58 // absolutelly the same as regular gmin/gmax.
    2.59 template <typename T>   OVR_FORCE_INLINE const T PMin(const T a, const T b)
    2.60 {
    2.61     OVR_COMPILER_ASSERT(sizeof(T) == sizeof(UPInt));
    2.62     return (a < b) ? a : b;
    2.63 }
    2.64 template <typename T>   OVR_FORCE_INLINE const T PMax(const T a, const T b)
    2.65 {
    2.66     OVR_COMPILER_ASSERT(sizeof(T) == sizeof(UPInt));
    2.67     return (b < a) ? a : b;
    2.68 }
    2.69 
    2.70 
    2.71 template <typename T>   OVR_FORCE_INLINE const T Abs(const T v)
    2.72 { return (v>=0) ? v : -v; }
    2.73 
    2.74 
    2.75 //-----------------------------------------------------------------------------------
    2.76 // ***** OperatorLess
    2.77 //
    2.78 template<class T> struct OperatorLess
    2.79 {
    2.80     static bool Compare(const T& a, const T& b)
    2.81     {
    2.82         return a < b;
    2.83     }
    2.84 };
    2.85 
    2.86 
    2.87 //-----------------------------------------------------------------------------------
    2.88 // ***** QuickSortSliced
    2.89 //
    2.90 // Sort any part of any array: plain, Array, ArrayPaged, ArrayUnsafe.
    2.91 // The range is specified with start, end, where "end" is exclusive!
    2.92 // The comparison predicate must be specified.
    2.93 template<class Array, class Less> 
    2.94 void QuickSortSliced(Array& arr, UPInt start, UPInt end, Less less)
    2.95 {
    2.96     enum 
    2.97     {
    2.98         Threshold = 9
    2.99     };
   2.100 
   2.101     if(end - start <  2) return;
   2.102 
   2.103     SPInt  stack[80];
   2.104     SPInt* top   = stack; 
   2.105     SPInt  base  = (SPInt)start;
   2.106     SPInt  limit = (SPInt)end;
   2.107 
   2.108     for(;;)
   2.109     {
   2.110         SPInt len = limit - base;
   2.111         SPInt i, j, pivot;
   2.112 
   2.113         if(len > Threshold)
   2.114         {
   2.115             // we use base + len/2 as the pivot
   2.116             pivot = base + len / 2;
   2.117             Swap(arr[base], arr[pivot]);
   2.118 
   2.119             i = base + 1;
   2.120             j = limit - 1;
   2.121 
   2.122             // now ensure that *i <= *base <= *j 
   2.123             if(less(arr[j],    arr[i])) Swap(arr[j],    arr[i]);
   2.124             if(less(arr[base], arr[i])) Swap(arr[base], arr[i]);
   2.125             if(less(arr[j], arr[base])) Swap(arr[j], arr[base]);
   2.126 
   2.127             for(;;)
   2.128             {
   2.129                 do i++; while( less(arr[i], arr[base]) );
   2.130                 do j--; while( less(arr[base], arr[j]) );
   2.131 
   2.132                 if( i > j )
   2.133                 {
   2.134                     break;
   2.135                 }
   2.136 
   2.137                 Swap(arr[i], arr[j]);
   2.138             }
   2.139 
   2.140             Swap(arr[base], arr[j]);
   2.141 
   2.142             // now, push the largest sub-array
   2.143             if(j - base > limit - i)
   2.144             {
   2.145                 top[0] = base;
   2.146                 top[1] = j;
   2.147                 base   = i;
   2.148             }
   2.149             else
   2.150             {
   2.151                 top[0] = i;
   2.152                 top[1] = limit;
   2.153                 limit  = j;
   2.154             }
   2.155             top += 2;
   2.156         }
   2.157         else
   2.158         {
   2.159             // the sub-array is small, perform insertion sort
   2.160             j = base;
   2.161             i = j + 1;
   2.162 
   2.163             for(; i < limit; j = i, i++)
   2.164             {
   2.165                 for(; less(arr[j + 1], arr[j]); j--)
   2.166                 {
   2.167                     Swap(arr[j + 1], arr[j]);
   2.168                     if(j == base)
   2.169                     {
   2.170                         break;
   2.171                     }
   2.172                 }
   2.173             }
   2.174             if(top > stack)
   2.175             {
   2.176                 top  -= 2;
   2.177                 base  = top[0];
   2.178                 limit = top[1];
   2.179             }
   2.180             else
   2.181             {
   2.182                 break;
   2.183             }
   2.184         }
   2.185     }
   2.186 }
   2.187 
   2.188 
   2.189 //-----------------------------------------------------------------------------------
   2.190 // ***** QuickSortSliced
   2.191 //
   2.192 // Sort any part of any array: plain, Array, ArrayPaged, ArrayUnsafe.
   2.193 // The range is specified with start, end, where "end" is exclusive!
   2.194 // The data type must have a defined "<" operator.
   2.195 template<class Array> 
   2.196 void QuickSortSliced(Array& arr, UPInt start, UPInt end)
   2.197 {
   2.198     typedef typename Array::ValueType ValueType;
   2.199     QuickSortSliced(arr, start, end, OperatorLess<ValueType>::Compare);
   2.200 }
   2.201 
   2.202 // Same as corresponding G_QuickSortSliced but with checking array limits to avoid
   2.203 // crash in the case of wrong comparator functor.
   2.204 template<class Array, class Less> 
   2.205 bool QuickSortSlicedSafe(Array& arr, UPInt start, UPInt end, Less less)
   2.206 {
   2.207     enum 
   2.208     {
   2.209         Threshold = 9
   2.210     };
   2.211 
   2.212     if(end - start <  2) return true;
   2.213 
   2.214     SPInt  stack[80];
   2.215     SPInt* top   = stack; 
   2.216     SPInt  base  = (SPInt)start;
   2.217     SPInt  limit = (SPInt)end;
   2.218 
   2.219     for(;;)
   2.220     {
   2.221         SPInt len = limit - base;
   2.222         SPInt i, j, pivot;
   2.223 
   2.224         if(len > Threshold)
   2.225         {
   2.226             // we use base + len/2 as the pivot
   2.227             pivot = base + len / 2;
   2.228             Swap(arr[base], arr[pivot]);
   2.229 
   2.230             i = base + 1;
   2.231             j = limit - 1;
   2.232 
   2.233             // now ensure that *i <= *base <= *j 
   2.234             if(less(arr[j],    arr[i])) Swap(arr[j],    arr[i]);
   2.235             if(less(arr[base], arr[i])) Swap(arr[base], arr[i]);
   2.236             if(less(arr[j], arr[base])) Swap(arr[j], arr[base]);
   2.237 
   2.238             for(;;)
   2.239             {
   2.240                 do 
   2.241                 {   
   2.242                     i++; 
   2.243                     if (i >= limit)
   2.244                         return false;
   2.245                 } while( less(arr[i], arr[base]) );
   2.246                 do 
   2.247                 {
   2.248                     j--; 
   2.249                     if (j < 0)
   2.250                         return false;
   2.251                 } while( less(arr[base], arr[j]) );
   2.252 
   2.253                 if( i > j )
   2.254                 {
   2.255                     break;
   2.256                 }
   2.257 
   2.258                 Swap(arr[i], arr[j]);
   2.259             }
   2.260 
   2.261             Swap(arr[base], arr[j]);
   2.262 
   2.263             // now, push the largest sub-array
   2.264             if(j - base > limit - i)
   2.265             {
   2.266                 top[0] = base;
   2.267                 top[1] = j;
   2.268                 base   = i;
   2.269             }
   2.270             else
   2.271             {
   2.272                 top[0] = i;
   2.273                 top[1] = limit;
   2.274                 limit  = j;
   2.275             }
   2.276             top += 2;
   2.277         }
   2.278         else
   2.279         {
   2.280             // the sub-array is small, perform insertion sort
   2.281             j = base;
   2.282             i = j + 1;
   2.283 
   2.284             for(; i < limit; j = i, i++)
   2.285             {
   2.286                 for(; less(arr[j + 1], arr[j]); j--)
   2.287                 {
   2.288                     Swap(arr[j + 1], arr[j]);
   2.289                     if(j == base)
   2.290                     {
   2.291                         break;
   2.292                     }
   2.293                 }
   2.294             }
   2.295             if(top > stack)
   2.296             {
   2.297                 top  -= 2;
   2.298                 base  = top[0];
   2.299                 limit = top[1];
   2.300             }
   2.301             else
   2.302             {
   2.303                 break;
   2.304             }
   2.305         }
   2.306     }
   2.307     return true;
   2.308 }
   2.309 
   2.310 template<class Array> 
   2.311 bool QuickSortSlicedSafe(Array& arr, UPInt start, UPInt end)
   2.312 {
   2.313     typedef typename Array::ValueType ValueType;
   2.314     return QuickSortSlicedSafe(arr, start, end, OperatorLess<ValueType>::Compare);
   2.315 }
   2.316 
   2.317 //-----------------------------------------------------------------------------------
   2.318 // ***** QuickSort
   2.319 //
   2.320 // Sort an array Array, ArrayPaged, ArrayUnsafe.
   2.321 // The array must have GetSize() function.
   2.322 // The comparison predicate must be specified.
   2.323 template<class Array, class Less> 
   2.324 void QuickSort(Array& arr, Less less)
   2.325 {
   2.326     QuickSortSliced(arr, 0, arr.GetSize(), less);
   2.327 }
   2.328 
   2.329 // checks for boundaries
   2.330 template<class Array, class Less> 
   2.331 bool QuickSortSafe(Array& arr, Less less)
   2.332 {
   2.333     return QuickSortSlicedSafe(arr, 0, arr.GetSize(), less);
   2.334 }
   2.335 
   2.336 
   2.337 //-----------------------------------------------------------------------------------
   2.338 // ***** QuickSort
   2.339 //
   2.340 // Sort an array Array, ArrayPaged, ArrayUnsafe.
   2.341 // The array must have GetSize() function.
   2.342 // The data type must have a defined "<" operator.
   2.343 template<class Array> 
   2.344 void QuickSort(Array& arr)
   2.345 {
   2.346     typedef typename Array::ValueType ValueType;
   2.347     QuickSortSliced(arr, 0, arr.GetSize(), OperatorLess<ValueType>::Compare);
   2.348 }
   2.349 
   2.350 template<class Array> 
   2.351 bool QuickSortSafe(Array& arr)
   2.352 {
   2.353     typedef typename Array::ValueType ValueType;
   2.354     return QuickSortSlicedSafe(arr, 0, arr.GetSize(), OperatorLess<ValueType>::Compare);
   2.355 }
   2.356 
   2.357 //-----------------------------------------------------------------------------------
   2.358 // ***** InsertionSortSliced
   2.359 //
   2.360 // Sort any part of any array: plain, Array, ArrayPaged, ArrayUnsafe.
   2.361 // The range is specified with start, end, where "end" is exclusive!
   2.362 // The comparison predicate must be specified.
   2.363 // Unlike Quick Sort, the Insertion Sort works much slower in average, 
   2.364 // but may be much faster on almost sorted arrays. Besides, it guarantees
   2.365 // that the elements will not be swapped if not necessary. For example, 
   2.366 // an array with all equal elements will remain "untouched", while 
   2.367 // Quick Sort will considerably shuffle the elements in this case.
   2.368 template<class Array, class Less> 
   2.369 void InsertionSortSliced(Array& arr, UPInt start, UPInt end, Less less)
   2.370 {
   2.371     UPInt j = start;
   2.372     UPInt i = j + 1;
   2.373     UPInt limit = end;
   2.374 
   2.375     for(; i < limit; j = i, i++)
   2.376     {
   2.377         for(; less(arr[j + 1], arr[j]); j--)
   2.378         {
   2.379             Swap(arr[j + 1], arr[j]);
   2.380             if(j <= start)
   2.381             {
   2.382                 break;
   2.383             }
   2.384         }
   2.385     }
   2.386 }
   2.387 
   2.388 
   2.389 //-----------------------------------------------------------------------------------
   2.390 // ***** InsertionSortSliced
   2.391 //
   2.392 // Sort any part of any array: plain, Array, ArrayPaged, ArrayUnsafe.
   2.393 // The range is specified with start, end, where "end" is exclusive!
   2.394 // The data type must have a defined "<" operator.
   2.395 template<class Array> 
   2.396 void InsertionSortSliced(Array& arr, UPInt start, UPInt end)
   2.397 {
   2.398     typedef typename Array::ValueType ValueType;
   2.399     InsertionSortSliced(arr, start, end, OperatorLess<ValueType>::Compare);
   2.400 }
   2.401 
   2.402 //-----------------------------------------------------------------------------------
   2.403 // ***** InsertionSort
   2.404 //
   2.405 // Sort an array Array, ArrayPaged, ArrayUnsafe.
   2.406 // The array must have GetSize() function.
   2.407 // The comparison predicate must be specified.
   2.408 
   2.409 template<class Array, class Less> 
   2.410 void InsertionSort(Array& arr, Less less)
   2.411 {
   2.412     InsertionSortSliced(arr, 0, arr.GetSize(), less);
   2.413 }
   2.414 
   2.415 //-----------------------------------------------------------------------------------
   2.416 // ***** InsertionSort
   2.417 //
   2.418 // Sort an array Array, ArrayPaged, ArrayUnsafe.
   2.419 // The array must have GetSize() function.
   2.420 // The data type must have a defined "<" operator.
   2.421 template<class Array> 
   2.422 void InsertionSort(Array& arr)
   2.423 {
   2.424     typedef typename Array::ValueType ValueType;
   2.425     InsertionSortSliced(arr, 0, arr.GetSize(), OperatorLess<ValueType>::Compare);
   2.426 }
   2.427 
   2.428 
   2.429 
   2.430 //-----------------------------------------------------------------------------------
   2.431 // ***** LowerBoundSliced
   2.432 //
   2.433 template<class Array, class Value, class Less>
   2.434 UPInt LowerBoundSliced(const Array& arr, UPInt start, UPInt end, const Value& val, Less less)
   2.435 {
   2.436     SPInt first = (SPInt)start;
   2.437     SPInt len   = (SPInt)(end - start);
   2.438     SPInt half;
   2.439     SPInt middle;
   2.440     
   2.441     while(len > 0) 
   2.442     {
   2.443         half = len >> 1;
   2.444         middle = first + half;
   2.445         if(less(arr[middle], val)) 
   2.446         {
   2.447             first = middle + 1;
   2.448             len   = len - half - 1;
   2.449         }
   2.450         else
   2.451         {
   2.452             len = half;
   2.453         }
   2.454     }
   2.455     return (UPInt)first;
   2.456 }
   2.457 
   2.458 
   2.459 //-----------------------------------------------------------------------------------
   2.460 // ***** LowerBoundSliced
   2.461 //
   2.462 template<class Array, class Value>
   2.463 UPInt LowerBoundSliced(const Array& arr, UPInt start, UPInt end, const Value& val)
   2.464 {
   2.465     return LowerBoundSliced(arr, start, end, val, OperatorLess<Value>::Compare);
   2.466 }
   2.467 
   2.468 //-----------------------------------------------------------------------------------
   2.469 // ***** LowerBoundSized
   2.470 //
   2.471 template<class Array, class Value>
   2.472 UPInt LowerBoundSized(const Array& arr, UPInt size, const Value& val)
   2.473 {
   2.474     return LowerBoundSliced(arr, 0, size, val, OperatorLess<Value>::Compare);
   2.475 }
   2.476 
   2.477 //-----------------------------------------------------------------------------------
   2.478 // ***** LowerBound
   2.479 //
   2.480 template<class Array, class Value, class Less>
   2.481 UPInt LowerBound(const Array& arr, const Value& val, Less less)
   2.482 {
   2.483     return LowerBoundSliced(arr, 0, arr.GetSize(), val, less);
   2.484 }
   2.485 
   2.486 
   2.487 //-----------------------------------------------------------------------------------
   2.488 // ***** LowerBound
   2.489 //
   2.490 template<class Array, class Value>
   2.491 UPInt LowerBound(const Array& arr, const Value& val)
   2.492 {
   2.493     return LowerBoundSliced(arr, 0, arr.GetSize(), val, OperatorLess<Value>::Compare);
   2.494 }
   2.495 
   2.496 
   2.497 
   2.498 //-----------------------------------------------------------------------------------
   2.499 // ***** UpperBoundSliced
   2.500 //
   2.501 template<class Array, class Value, class Less>
   2.502 UPInt UpperBoundSliced(const Array& arr, UPInt start, UPInt end, const Value& val, Less less)
   2.503 {
   2.504     SPInt first = (SPInt)start;
   2.505     SPInt len   = (SPInt)(end - start);
   2.506     SPInt half;
   2.507     SPInt middle;
   2.508     
   2.509     while(len > 0) 
   2.510     {
   2.511         half = len >> 1;
   2.512         middle = first + half;
   2.513         if(less(val, arr[middle]))
   2.514         {
   2.515             len = half;
   2.516         }
   2.517         else 
   2.518         {
   2.519             first = middle + 1;
   2.520             len   = len - half - 1;
   2.521         }
   2.522     }
   2.523     return (UPInt)first;
   2.524 }
   2.525 
   2.526 
   2.527 //-----------------------------------------------------------------------------------
   2.528 // ***** UpperBoundSliced
   2.529 //
   2.530 template<class Array, class Value>
   2.531 UPInt UpperBoundSliced(const Array& arr, UPInt start, UPInt end, const Value& val)
   2.532 {
   2.533     return UpperBoundSliced(arr, start, end, val, OperatorLess<Value>::Compare);
   2.534 }
   2.535 
   2.536 
   2.537 //-----------------------------------------------------------------------------------
   2.538 // ***** UpperBoundSized
   2.539 //
   2.540 template<class Array, class Value>
   2.541 UPInt UpperBoundSized(const Array& arr, UPInt size, const Value& val)
   2.542 {
   2.543     return UpperBoundSliced(arr, 0, size, val, OperatorLess<Value>::Compare);
   2.544 }
   2.545 
   2.546 
   2.547 //-----------------------------------------------------------------------------------
   2.548 // ***** UpperBound
   2.549 //
   2.550 template<class Array, class Value, class Less>
   2.551 UPInt UpperBound(const Array& arr, const Value& val, Less less)
   2.552 {
   2.553     return UpperBoundSliced(arr, 0, arr.GetSize(), val, less);
   2.554 }
   2.555 
   2.556 
   2.557 //-----------------------------------------------------------------------------------
   2.558 // ***** UpperBound
   2.559 //
   2.560 template<class Array, class Value>
   2.561 UPInt UpperBound(const Array& arr, const Value& val)
   2.562 {
   2.563     return UpperBoundSliced(arr, 0, arr.GetSize(), val, OperatorLess<Value>::Compare);
   2.564 }
   2.565 
   2.566 
   2.567 //-----------------------------------------------------------------------------------
   2.568 // ***** ReverseArray
   2.569 //
   2.570 template<class Array> void ReverseArray(Array& arr)
   2.571 {
   2.572     SPInt from = 0;
   2.573     SPInt to   = arr.GetSize() - 1;
   2.574     while(from < to)
   2.575     {
   2.576         Swap(arr[from], arr[to]);
   2.577         ++from;
   2.578         --to;
   2.579     }
   2.580 }
   2.581 
   2.582 
   2.583 // ***** AppendArray
   2.584 //
   2.585 template<class CDst, class CSrc> 
   2.586 void AppendArray(CDst& dst, const CSrc& src)
   2.587 {
   2.588     UPInt i;
   2.589     for(i = 0; i < src.GetSize(); i++) 
   2.590         dst.PushBack(src[i]);
   2.591 }
   2.592 
   2.593 //-----------------------------------------------------------------------------------
   2.594 // ***** ArrayAdaptor
   2.595 //
   2.596 // A simple adapter that provides the GetSize() method and overloads 
   2.597 // operator []. Used to wrap plain arrays in QuickSort and such.
   2.598 template<class T> class ArrayAdaptor
   2.599 {
   2.600 public:
   2.601     typedef T ValueType;
   2.602     ArrayAdaptor() : Data(0), Size(0) {}
   2.603     ArrayAdaptor(T* ptr, UPInt size) : Data(ptr), Size(size) {}
   2.604     UPInt GetSize() const { return Size; }
   2.605     const T& operator [] (UPInt i) const { return Data[i]; }
   2.606           T& operator [] (UPInt i)       { return Data[i]; }
   2.607 private:
   2.608     T*      Data;
   2.609     UPInt   Size;
   2.610 };
   2.611 
   2.612 
   2.613 //-----------------------------------------------------------------------------------
   2.614 // ***** GConstArrayAdaptor
   2.615 //
   2.616 // A simple const adapter that provides the GetSize() method and overloads 
   2.617 // operator []. Used to wrap plain arrays in LowerBound and such.
   2.618 template<class T> class ConstArrayAdaptor
   2.619 {
   2.620 public:
   2.621     typedef T ValueType;
   2.622     ConstArrayAdaptor() : Data(0), Size(0) {}
   2.623     ConstArrayAdaptor(const T* ptr, UPInt size) : Data(ptr), Size(size) {}
   2.624     UPInt GetSize() const { return Size; }
   2.625     const T& operator [] (UPInt i) const { return Data[i]; }
   2.626 private:
   2.627     const T* Data;
   2.628     UPInt    Size;
   2.629 };
   2.630 
   2.631 
   2.632 
   2.633 //-----------------------------------------------------------------------------------
   2.634 extern const UByte UpperBitTable[256];
   2.635 extern const UByte LowerBitTable[256];
   2.636 
   2.637 
   2.638 
   2.639 //-----------------------------------------------------------------------------------
   2.640 inline UByte UpperBit(UPInt val)
   2.641 {
   2.642 #ifndef OVR_64BIT_POINTERS
   2.643 
   2.644     if (val & 0xFFFF0000)
   2.645     {
   2.646         return (val & 0xFF000000) ? 
   2.647             UpperBitTable[(val >> 24)       ] + 24: 
   2.648             UpperBitTable[(val >> 16) & 0xFF] + 16;
   2.649     }
   2.650     return (val & 0xFF00) ?
   2.651         UpperBitTable[(val >> 8) & 0xFF] + 8:
   2.652         UpperBitTable[(val     ) & 0xFF];
   2.653 
   2.654 #else
   2.655 
   2.656     if (val & 0xFFFFFFFF00000000)
   2.657     {
   2.658         if (val & 0xFFFF000000000000)
   2.659         {
   2.660             return (val & 0xFF00000000000000) ?
   2.661                 UpperBitTable[(val >> 56)       ] + 56: 
   2.662                 UpperBitTable[(val >> 48) & 0xFF] + 48;
   2.663         }
   2.664         return (val & 0xFF0000000000) ?
   2.665             UpperBitTable[(val >> 40) & 0xFF] + 40:
   2.666             UpperBitTable[(val >> 32) & 0xFF] + 32;
   2.667     }
   2.668     else
   2.669     {
   2.670         if (val & 0xFFFF0000)
   2.671         {
   2.672             return (val & 0xFF000000) ? 
   2.673                 UpperBitTable[(val >> 24)       ] + 24: 
   2.674                 UpperBitTable[(val >> 16) & 0xFF] + 16;
   2.675         }
   2.676         return (val & 0xFF00) ?
   2.677             UpperBitTable[(val >> 8) & 0xFF] + 8:
   2.678             UpperBitTable[(val     ) & 0xFF];
   2.679     }
   2.680 
   2.681 #endif
   2.682 }
   2.683 
   2.684 //-----------------------------------------------------------------------------------
   2.685 inline UByte LowerBit(UPInt val)
   2.686 {
   2.687 #ifndef OVR_64BIT_POINTERS
   2.688 
   2.689     if (val & 0xFFFF)
   2.690     {
   2.691         return (val & 0xFF) ?
   2.692             LowerBitTable[ val & 0xFF]:
   2.693             LowerBitTable[(val >> 8) & 0xFF] + 8;
   2.694     }
   2.695     return (val & 0xFF0000) ?
   2.696             LowerBitTable[(val >> 16) & 0xFF] + 16:
   2.697             LowerBitTable[(val >> 24) & 0xFF] + 24;
   2.698 
   2.699 #else
   2.700 
   2.701     if (val & 0xFFFFFFFF)
   2.702     {
   2.703         if (val & 0xFFFF)
   2.704         {
   2.705             return (val & 0xFF) ?
   2.706                 LowerBitTable[ val & 0xFF]:
   2.707                 LowerBitTable[(val >> 8) & 0xFF] + 8;
   2.708         }
   2.709         return (val & 0xFF0000) ?
   2.710                 LowerBitTable[(val >> 16) & 0xFF] + 16:
   2.711                 LowerBitTable[(val >> 24) & 0xFF] + 24;
   2.712     }
   2.713     else
   2.714     {
   2.715         if (val & 0xFFFF00000000)
   2.716         {
   2.717              return (val & 0xFF00000000) ?
   2.718                 LowerBitTable[(val >> 32) & 0xFF] + 32:
   2.719                 LowerBitTable[(val >> 40) & 0xFF] + 40;
   2.720         }
   2.721         return (val & 0xFF000000000000) ?
   2.722             LowerBitTable[(val >> 48) & 0xFF] + 48:
   2.723             LowerBitTable[(val >> 56) & 0xFF] + 56;
   2.724     }
   2.725 
   2.726 #endif
   2.727 }
   2.728 
   2.729 
   2.730 
   2.731 // ******* Special (optimized) memory routines
   2.732 // Note: null (bad) pointer is not tested
   2.733 class MemUtil
   2.734 {
   2.735 public:
   2.736                                     
   2.737     // Memory compare
   2.738     static int      Cmp  (const void* p1, const void* p2, UPInt byteCount)      { return memcmp(p1, p2, byteCount); }
   2.739     static int      Cmp16(const void* p1, const void* p2, UPInt int16Count);
   2.740     static int      Cmp32(const void* p1, const void* p2, UPInt int32Count);
   2.741     static int      Cmp64(const void* p1, const void* p2, UPInt int64Count); 
   2.742 };
   2.743 
   2.744 // ** Inline Implementation
   2.745 
   2.746 inline int MemUtil::Cmp16(const void* p1, const void* p2, UPInt int16Count)
   2.747 {
   2.748     SInt16*  pa  = (SInt16*)p1; 
   2.749     SInt16*  pb  = (SInt16*)p2;
   2.750     unsigned ic  = 0;
   2.751     if (int16Count == 0)
   2.752         return 0;
   2.753     while (pa[ic] == pb[ic])
   2.754         if (++ic==int16Count)
   2.755             return 0;
   2.756     return pa[ic] > pb[ic] ? 1 : -1;
   2.757 }
   2.758 inline int MemUtil::Cmp32(const void* p1, const void* p2, UPInt int32Count)
   2.759 {
   2.760     SInt32*  pa  = (SInt32*)p1;
   2.761     SInt32*  pb  = (SInt32*)p2;
   2.762     unsigned ic  = 0;
   2.763     if (int32Count == 0)
   2.764         return 0;
   2.765     while (pa[ic] == pb[ic])
   2.766         if (++ic==int32Count)
   2.767             return 0;
   2.768     return pa[ic] > pb[ic] ? 1 : -1;
   2.769 }
   2.770 inline int MemUtil::Cmp64(const void* p1, const void* p2, UPInt int64Count)
   2.771 {
   2.772     SInt64*  pa  = (SInt64*)p1;
   2.773     SInt64*  pb  = (SInt64*)p2;
   2.774     unsigned ic  = 0;
   2.775     if (int64Count == 0)
   2.776         return 0;
   2.777     while (pa[ic] == pb[ic])
   2.778         if (++ic==int64Count)
   2.779             return 0;
   2.780     return pa[ic] > pb[ic] ? 1 : -1;
   2.781 }
   2.782 
   2.783 // ** End Inline Implementation
   2.784 
   2.785 
   2.786 //-----------------------------------------------------------------------------------
   2.787 // ******* Byte Order Conversions
   2.788 namespace ByteUtil {
   2.789 
   2.790     // *** Swap Byte Order
   2.791 
   2.792     // Swap the byte order of a byte array
   2.793     inline void     SwapOrder(void* pv, int size)
   2.794     {
   2.795         UByte*  pb = (UByte*)pv;
   2.796         UByte   temp;
   2.797         for (int i = 0; i < size>>1; i++)
   2.798         { 
   2.799             temp            = pb[size-1-i];
   2.800             pb[size-1-i]    = pb[i];
   2.801             pb[i]           = temp; 
   2.802         }
   2.803     }
   2.804 
   2.805     // Swap the byte order of primitive types
   2.806     inline UByte    SwapOrder(UByte v)      { return v; }
   2.807     inline SByte    SwapOrder(SByte v)      { return v; }
   2.808     inline UInt16   SwapOrder(UInt16 v)     { return UInt16(v>>8)|UInt16(v<<8); }
   2.809     inline SInt16   SwapOrder(SInt16 v)     { return SInt16((UInt16(v)>>8)|(v<<8)); }
   2.810     inline UInt32   SwapOrder(UInt32 v)     { return (v>>24)|((v&0x00FF0000)>>8)|((v&0x0000FF00)<<8)|(v<<24); }
   2.811     inline SInt32   SwapOrder(SInt32 p)     { return (SInt32)SwapOrder(UInt32(p)); }
   2.812     inline UInt64   SwapOrder(UInt64 v)
   2.813     { 
   2.814         return   (v>>56) |
   2.815                  ((v&UInt64(0x00FF000000000000))>>40) |
   2.816                  ((v&UInt64(0x0000FF0000000000))>>24) |
   2.817                  ((v&UInt64(0x000000FF00000000))>>8)  |
   2.818                  ((v&UInt64(0x00000000FF000000))<<8)  |
   2.819                  ((v&UInt64(0x0000000000FF0000))<<24) |
   2.820                  ((v&UInt64(0x000000000000FF00))<<40) |
   2.821                  (v<<56); 
   2.822     }
   2.823     inline SInt64   SwapOrder(SInt64 v)     { return (SInt64)SwapOrder(UInt64(v)); }
   2.824     inline float    SwapOrder(float p)      
   2.825     { 
   2.826         union {
   2.827             float p;
   2.828             UInt32 v;
   2.829         } u;
   2.830         u.p = p;
   2.831         u.v = SwapOrder(u.v);
   2.832         return u.p;
   2.833     }
   2.834 
   2.835     inline double   SwapOrder(double p)
   2.836     { 
   2.837         union {
   2.838             double p;
   2.839             UInt64 v;
   2.840         } u;
   2.841         u.p = p;
   2.842         u.v = SwapOrder(u.v);
   2.843         return u.p;
   2.844     }
   2.845     
   2.846     // *** Byte-order conversion
   2.847 
   2.848 #if (OVR_BYTE_ORDER == OVR_LITTLE_ENDIAN)
   2.849     // Little Endian to System (LE)
   2.850     inline UByte    LEToSystem(UByte  v)    { return v; }
   2.851     inline SByte    LEToSystem(SByte  v)    { return v; }
   2.852     inline UInt16   LEToSystem(UInt16 v)    { return v; }
   2.853     inline SInt16   LEToSystem(SInt16 v)    { return v; }
   2.854     inline UInt32   LEToSystem(UInt32 v)    { return v; }
   2.855     inline SInt32   LEToSystem(SInt32 v)    { return v; }
   2.856     inline UInt64   LEToSystem(UInt64 v)    { return v; }
   2.857     inline SInt64   LEToSystem(SInt64 v)    { return v; }
   2.858     inline float    LEToSystem(float  v)    { return v; }
   2.859     inline double   LEToSystem(double v)    { return v; }
   2.860 
   2.861     // Big Endian to System (LE)
   2.862     inline UByte    BEToSystem(UByte  v)    { return SwapOrder(v); }
   2.863     inline SByte    BEToSystem(SByte  v)    { return SwapOrder(v); }
   2.864     inline UInt16   BEToSystem(UInt16 v)    { return SwapOrder(v); }
   2.865     inline SInt16   BEToSystem(SInt16 v)    { return SwapOrder(v); }
   2.866     inline UInt32   BEToSystem(UInt32 v)    { return SwapOrder(v); }
   2.867     inline SInt32   BEToSystem(SInt32 v)    { return SwapOrder(v); }
   2.868     inline UInt64   BEToSystem(UInt64 v)    { return SwapOrder(v); }
   2.869     inline SInt64   BEToSystem(SInt64 v)    { return SwapOrder(v); }
   2.870     inline float    BEToSystem(float  v)    { return SwapOrder(v); }
   2.871     inline double   BEToSystem(double v)    { return SwapOrder(v); }
   2.872 
   2.873     // System (LE) to Little Endian
   2.874     inline UByte    SystemToLE(UByte  v)    { return v; }
   2.875     inline SByte    SystemToLE(SByte  v)    { return v; }
   2.876     inline UInt16   SystemToLE(UInt16 v)    { return v; }
   2.877     inline SInt16   SystemToLE(SInt16 v)    { return v; }
   2.878     inline UInt32   SystemToLE(UInt32 v)    { return v; }
   2.879     inline SInt32   SystemToLE(SInt32 v)    { return v; }
   2.880     inline UInt64   SystemToLE(UInt64 v)    { return v; }
   2.881     inline SInt64   SystemToLE(SInt64 v)    { return v; }
   2.882     inline float    SystemToLE(float  v)    { return v; }
   2.883     inline double   SystemToLE(double v)    { return v; }   
   2.884 
   2.885     // System (LE) to Big Endian
   2.886     inline UByte    SystemToBE(UByte  v)    { return SwapOrder(v); }
   2.887     inline SByte    SystemToBE(SByte  v)    { return SwapOrder(v); }
   2.888     inline UInt16   SystemToBE(UInt16 v)    { return SwapOrder(v); }
   2.889     inline SInt16   SystemToBE(SInt16 v)    { return SwapOrder(v); }
   2.890     inline UInt32   SystemToBE(UInt32 v)    { return SwapOrder(v); }
   2.891     inline SInt32   SystemToBE(SInt32 v)    { return SwapOrder(v); }
   2.892     inline UInt64   SystemToBE(UInt64 v)    { return SwapOrder(v); }
   2.893     inline SInt64   SystemToBE(SInt64 v)    { return SwapOrder(v); }
   2.894     inline float    SystemToBE(float  v)    { return SwapOrder(v); }
   2.895     inline double   SystemToBE(double v)    { return SwapOrder(v); }
   2.896 
   2.897 #elif (OVR_BYTE_ORDER == OVR_BIG_ENDIAN)
   2.898     // Little Endian to System (BE)
   2.899     inline UByte    LEToSystem(UByte  v)    { return SwapOrder(v); }
   2.900     inline SByte    LEToSystem(SByte  v)    { return SwapOrder(v); }
   2.901     inline UInt16   LEToSystem(UInt16 v)    { return SwapOrder(v); }
   2.902     inline SInt16   LEToSystem(SInt16 v)    { return SwapOrder(v); }
   2.903     inline UInt32   LEToSystem(UInt32 v)    { return SwapOrder(v); }
   2.904     inline SInt32   LEToSystem(SInt32 v)    { return SwapOrder(v); }
   2.905     inline UInt64   LEToSystem(UInt64 v)    { return SwapOrder(v); }
   2.906     inline SInt64   LEToSystem(SInt64 v)    { return SwapOrder(v); }
   2.907     inline float    LEToSystem(float  v)    { return SwapOrder(v); }
   2.908     inline double   LEToSystem(double v)    { return SwapOrder(v); }
   2.909 
   2.910     // Big Endian to System (BE)
   2.911     inline UByte    BEToSystem(UByte  v)    { return v; }
   2.912     inline SByte    BEToSystem(SByte  v)    { return v; }
   2.913     inline UInt16   BEToSystem(UInt16 v)    { return v; }
   2.914     inline SInt16   BEToSystem(SInt16 v)    { return v; }
   2.915     inline UInt32   BEToSystem(UInt32 v)    { return v; }
   2.916     inline SInt32   BEToSystem(SInt32 v)    { return v; }
   2.917     inline UInt64   BEToSystem(UInt64 v)    { return v; }
   2.918     inline SInt64   BEToSystem(SInt64 v)    { return v; }
   2.919     inline float    BEToSystem(float  v)    { return v; }
   2.920     inline double   BEToSystem(double v)    { return v; }
   2.921 
   2.922     // System (BE) to Little Endian
   2.923     inline UByte    SystemToLE(UByte  v)    { return SwapOrder(v); }
   2.924     inline SByte    SystemToLE(SByte  v)    { return SwapOrder(v); }
   2.925     inline UInt16   SystemToLE(UInt16 v)    { return SwapOrder(v); }
   2.926     inline SInt16   SystemToLE(SInt16 v)    { return SwapOrder(v); }
   2.927     inline UInt32   SystemToLE(UInt32 v)    { return SwapOrder(v); }
   2.928     inline SInt32   SystemToLE(SInt32 v)    { return SwapOrder(v); }
   2.929     inline UInt64   SystemToLE(UInt64 v)    { return SwapOrder(v); }
   2.930     inline SInt64   SystemToLE(SInt64 v)    { return SwapOrder(v); }
   2.931     inline float    SystemToLE(float  v)    { return SwapOrder(v); }
   2.932     inline double   SystemToLE(double v)    { return SwapOrder(v); }
   2.933 
   2.934     // System (BE) to Big Endian
   2.935     inline UByte    SystemToBE(UByte  v)    { return v; }
   2.936     inline SByte    SystemToBE(SByte  v)    { return v; }
   2.937     inline UInt16   SystemToBE(UInt16 v)    { return v; }
   2.938     inline SInt16   SystemToBE(SInt16 v)    { return v; }
   2.939     inline UInt32   SystemToBE(UInt32 v)    { return v; }
   2.940     inline SInt32   SystemToBE(SInt32 v)    { return v; }
   2.941     inline UInt64   SystemToBE(UInt64 v)    { return v; }
   2.942     inline SInt64   SystemToBE(SInt64 v)    { return v; }
   2.943     inline float    SystemToBE(float  v)    { return v; }
   2.944     inline double   SystemToBE(double v)    { return v; }
   2.945 
   2.946 #else
   2.947     #error "OVR_BYTE_ORDER must be defined to OVR_LITTLE_ENDIAN or OVR_BIG_ENDIAN"
   2.948 #endif
   2.949 
   2.950 } // namespace ByteUtil
   2.951 
   2.952 
   2.953 
   2.954 }} // OVR::Alg
   2.955 
   2.956 #endif
   2.957 \ No newline at end of file
   2.958 +/************************************************************************************
   2.959 +
   2.960 +PublicHeader:   OVR.h
   2.961 +Filename    :   OVR_Alg.h
   2.962 +Content     :   Simple general purpose algorithms: Sort, Binary Search, etc.
   2.963 +Created     :   September 19, 2012
   2.964 +Notes       : 
   2.965 +
   2.966 +Copyright   :   Copyright 2012 Oculus VR, Inc. All Rights reserved.
   2.967 +
   2.968 +Use of this software is subject to the terms of the Oculus license
   2.969 +agreement provided at the time of installation or download, or which
   2.970 +otherwise accompanies this software in either electronic or hard copy form.
   2.971 +
   2.972 +************************************************************************************/
   2.973 +
   2.974 +#ifndef OVR_Alg_h
   2.975 +#define OVR_Alg_h
   2.976 +
   2.977 +#include "OVR_Types.h"
   2.978 +#include <string.h>
   2.979 +
   2.980 +namespace OVR { namespace Alg {
   2.981 +
   2.982 +
   2.983 +//-----------------------------------------------------------------------------------
   2.984 +// ***** Operator extensions
   2.985 +
   2.986 +template <typename T> OVR_FORCE_INLINE void Swap(T &a, T &b) 
   2.987 +{  T temp(a); a = b; b = temp; }
   2.988 +
   2.989 +
   2.990 +// ***** min/max are not implemented in Visual Studio 6 standard STL
   2.991 +
   2.992 +template <typename T> OVR_FORCE_INLINE const T Min(const T a, const T b)
   2.993 +{ return (a < b) ? a : b; }
   2.994 +
   2.995 +template <typename T> OVR_FORCE_INLINE const T Max(const T a, const T b)
   2.996 +{ return (b < a) ? a : b; }
   2.997 +
   2.998 +template <typename T> OVR_FORCE_INLINE const T Clamp(const T v, const T minVal, const T maxVal)
   2.999 +{ return Max<T>(minVal, Min<T>(v, maxVal)); }
  2.1000 +
  2.1001 +template <typename T> OVR_FORCE_INLINE int     Chop(T f)
  2.1002 +{ return (int)f; }
  2.1003 +
  2.1004 +template <typename T> OVR_FORCE_INLINE T       Lerp(T a, T b, T f) 
  2.1005 +{ return (b - a) * f + a; }
  2.1006 +
  2.1007 +
  2.1008 +// These functions stand to fix a stupid VC++ warning (with /Wp64 on):
  2.1009 +// "warning C4267: 'argument' : conversion from 'size_t' to 'const unsigned', possible loss of data"
  2.1010 +// Use these functions instead of gmin/gmax if the argument has size
  2.1011 +// of the pointer to avoid the warning. Though, functionally they are
  2.1012 +// absolutelly the same as regular gmin/gmax.
  2.1013 +template <typename T>   OVR_FORCE_INLINE const T PMin(const T a, const T b)
  2.1014 +{
  2.1015 +    OVR_COMPILER_ASSERT(sizeof(T) == sizeof(UPInt));
  2.1016 +    return (a < b) ? a : b;
  2.1017 +}
  2.1018 +template <typename T>   OVR_FORCE_INLINE const T PMax(const T a, const T b)
  2.1019 +{
  2.1020 +    OVR_COMPILER_ASSERT(sizeof(T) == sizeof(UPInt));
  2.1021 +    return (b < a) ? a : b;
  2.1022 +}
  2.1023 +
  2.1024 +
  2.1025 +template <typename T>   OVR_FORCE_INLINE const T Abs(const T v)
  2.1026 +{ return (v>=0) ? v : -v; }
  2.1027 +
  2.1028 +
  2.1029 +//-----------------------------------------------------------------------------------
  2.1030 +// ***** OperatorLess
  2.1031 +//
  2.1032 +template<class T> struct OperatorLess
  2.1033 +{
  2.1034 +    static bool Compare(const T& a, const T& b)
  2.1035 +    {
  2.1036 +        return a < b;
  2.1037 +    }
  2.1038 +};
  2.1039 +
  2.1040 +
  2.1041 +//-----------------------------------------------------------------------------------
  2.1042 +// ***** QuickSortSliced
  2.1043 +//
  2.1044 +// Sort any part of any array: plain, Array, ArrayPaged, ArrayUnsafe.
  2.1045 +// The range is specified with start, end, where "end" is exclusive!
  2.1046 +// The comparison predicate must be specified.
  2.1047 +template<class Array, class Less> 
  2.1048 +void QuickSortSliced(Array& arr, UPInt start, UPInt end, Less less)
  2.1049 +{
  2.1050 +    enum 
  2.1051 +    {
  2.1052 +        Threshold = 9
  2.1053 +    };
  2.1054 +
  2.1055 +    if(end - start <  2) return;
  2.1056 +
  2.1057 +    SPInt  stack[80];
  2.1058 +    SPInt* top   = stack; 
  2.1059 +    SPInt  base  = (SPInt)start;
  2.1060 +    SPInt  limit = (SPInt)end;
  2.1061 +
  2.1062 +    for(;;)
  2.1063 +    {
  2.1064 +        SPInt len = limit - base;
  2.1065 +        SPInt i, j, pivot;
  2.1066 +
  2.1067 +        if(len > Threshold)
  2.1068 +        {
  2.1069 +            // we use base + len/2 as the pivot
  2.1070 +            pivot = base + len / 2;
  2.1071 +            Swap(arr[base], arr[pivot]);
  2.1072 +
  2.1073 +            i = base + 1;
  2.1074 +            j = limit - 1;
  2.1075 +
  2.1076 +            // now ensure that *i <= *base <= *j 
  2.1077 +            if(less(arr[j],    arr[i])) Swap(arr[j],    arr[i]);
  2.1078 +            if(less(arr[base], arr[i])) Swap(arr[base], arr[i]);
  2.1079 +            if(less(arr[j], arr[base])) Swap(arr[j], arr[base]);
  2.1080 +
  2.1081 +            for(;;)
  2.1082 +            {
  2.1083 +                do i++; while( less(arr[i], arr[base]) );
  2.1084 +                do j--; while( less(arr[base], arr[j]) );
  2.1085 +
  2.1086 +                if( i > j )
  2.1087 +                {
  2.1088 +                    break;
  2.1089 +                }
  2.1090 +
  2.1091 +                Swap(arr[i], arr[j]);
  2.1092 +            }
  2.1093 +
  2.1094 +            Swap(arr[base], arr[j]);
  2.1095 +
  2.1096 +            // now, push the largest sub-array
  2.1097 +            if(j - base > limit - i)
  2.1098 +            {
  2.1099 +                top[0] = base;
  2.1100 +                top[1] = j;
  2.1101 +                base   = i;
  2.1102 +            }
  2.1103 +            else
  2.1104 +            {
  2.1105 +                top[0] = i;
  2.1106 +                top[1] = limit;
  2.1107 +                limit  = j;
  2.1108 +            }
  2.1109 +            top += 2;
  2.1110 +        }
  2.1111 +        else
  2.1112 +        {
  2.1113 +            // the sub-array is small, perform insertion sort
  2.1114 +            j = base;
  2.1115 +            i = j + 1;
  2.1116 +
  2.1117 +            for(; i < limit; j = i, i++)
  2.1118 +            {
  2.1119 +                for(; less(arr[j + 1], arr[j]); j--)
  2.1120 +                {
  2.1121 +                    Swap(arr[j + 1], arr[j]);
  2.1122 +                    if(j == base)
  2.1123 +                    {
  2.1124 +                        break;
  2.1125 +                    }
  2.1126 +                }
  2.1127 +            }
  2.1128 +            if(top > stack)
  2.1129 +            {
  2.1130 +                top  -= 2;
  2.1131 +                base  = top[0];
  2.1132 +                limit = top[1];
  2.1133 +            }
  2.1134 +            else
  2.1135 +            {
  2.1136 +                break;
  2.1137 +            }
  2.1138 +        }
  2.1139 +    }
  2.1140 +}
  2.1141 +
  2.1142 +
  2.1143 +//-----------------------------------------------------------------------------------
  2.1144 +// ***** QuickSortSliced
  2.1145 +//
  2.1146 +// Sort any part of any array: plain, Array, ArrayPaged, ArrayUnsafe.
  2.1147 +// The range is specified with start, end, where "end" is exclusive!
  2.1148 +// The data type must have a defined "<" operator.
  2.1149 +template<class Array> 
  2.1150 +void QuickSortSliced(Array& arr, UPInt start, UPInt end)
  2.1151 +{
  2.1152 +    typedef typename Array::ValueType ValueType;
  2.1153 +    QuickSortSliced(arr, start, end, OperatorLess<ValueType>::Compare);
  2.1154 +}
  2.1155 +
  2.1156 +// Same as corresponding G_QuickSortSliced but with checking array limits to avoid
  2.1157 +// crash in the case of wrong comparator functor.
  2.1158 +template<class Array, class Less> 
  2.1159 +bool QuickSortSlicedSafe(Array& arr, UPInt start, UPInt end, Less less)
  2.1160 +{
  2.1161 +    enum 
  2.1162 +    {
  2.1163 +        Threshold = 9
  2.1164 +    };
  2.1165 +
  2.1166 +    if(end - start <  2) return true;
  2.1167 +
  2.1168 +    SPInt  stack[80];
  2.1169 +    SPInt* top   = stack; 
  2.1170 +    SPInt  base  = (SPInt)start;
  2.1171 +    SPInt  limit = (SPInt)end;
  2.1172 +
  2.1173 +    for(;;)
  2.1174 +    {
  2.1175 +        SPInt len = limit - base;
  2.1176 +        SPInt i, j, pivot;
  2.1177 +
  2.1178 +        if(len > Threshold)
  2.1179 +        {
  2.1180 +            // we use base + len/2 as the pivot
  2.1181 +            pivot = base + len / 2;
  2.1182 +            Swap(arr[base], arr[pivot]);
  2.1183 +
  2.1184 +            i = base + 1;
  2.1185 +            j = limit - 1;
  2.1186 +
  2.1187 +            // now ensure that *i <= *base <= *j 
  2.1188 +            if(less(arr[j],    arr[i])) Swap(arr[j],    arr[i]);
  2.1189 +            if(less(arr[base], arr[i])) Swap(arr[base], arr[i]);
  2.1190 +            if(less(arr[j], arr[base])) Swap(arr[j], arr[base]);
  2.1191 +
  2.1192 +            for(;;)
  2.1193 +            {
  2.1194 +                do 
  2.1195 +                {   
  2.1196 +                    i++; 
  2.1197 +                    if (i >= limit)
  2.1198 +                        return false;
  2.1199 +                } while( less(arr[i], arr[base]) );
  2.1200 +                do 
  2.1201 +                {
  2.1202 +                    j--; 
  2.1203 +                    if (j < 0)
  2.1204 +                        return false;
  2.1205 +                } while( less(arr[base], arr[j]) );
  2.1206 +
  2.1207 +                if( i > j )
  2.1208 +                {
  2.1209 +                    break;
  2.1210 +                }
  2.1211 +
  2.1212 +                Swap(arr[i], arr[j]);
  2.1213 +            }
  2.1214 +
  2.1215 +            Swap(arr[base], arr[j]);
  2.1216 +
  2.1217 +            // now, push the largest sub-array
  2.1218 +            if(j - base > limit - i)
  2.1219 +            {
  2.1220 +                top[0] = base;
  2.1221 +                top[1] = j;
  2.1222 +                base   = i;
  2.1223 +            }
  2.1224 +            else
  2.1225 +            {
  2.1226 +                top[0] = i;
  2.1227 +                top[1] = limit;
  2.1228 +                limit  = j;
  2.1229 +            }
  2.1230 +            top += 2;
  2.1231 +        }
  2.1232 +        else
  2.1233 +        {
  2.1234 +            // the sub-array is small, perform insertion sort
  2.1235 +            j = base;
  2.1236 +            i = j + 1;
  2.1237 +
  2.1238 +            for(; i < limit; j = i, i++)
  2.1239 +            {
  2.1240 +                for(; less(arr[j + 1], arr[j]); j--)
  2.1241 +                {
  2.1242 +                    Swap(arr[j + 1], arr[j]);
  2.1243 +                    if(j == base)
  2.1244 +                    {
  2.1245 +                        break;
  2.1246 +                    }
  2.1247 +                }
  2.1248 +            }
  2.1249 +            if(top > stack)
  2.1250 +            {
  2.1251 +                top  -= 2;
  2.1252 +                base  = top[0];
  2.1253 +                limit = top[1];
  2.1254 +            }
  2.1255 +            else
  2.1256 +            {
  2.1257 +                break;
  2.1258 +            }
  2.1259 +        }
  2.1260 +    }
  2.1261 +    return true;
  2.1262 +}
  2.1263 +
  2.1264 +template<class Array> 
  2.1265 +bool QuickSortSlicedSafe(Array& arr, UPInt start, UPInt end)
  2.1266 +{
  2.1267 +    typedef typename Array::ValueType ValueType;
  2.1268 +    return QuickSortSlicedSafe(arr, start, end, OperatorLess<ValueType>::Compare);
  2.1269 +}
  2.1270 +
  2.1271 +//-----------------------------------------------------------------------------------
  2.1272 +// ***** QuickSort
  2.1273 +//
  2.1274 +// Sort an array Array, ArrayPaged, ArrayUnsafe.
  2.1275 +// The array must have GetSize() function.
  2.1276 +// The comparison predicate must be specified.
  2.1277 +template<class Array, class Less> 
  2.1278 +void QuickSort(Array& arr, Less less)
  2.1279 +{
  2.1280 +    QuickSortSliced(arr, 0, arr.GetSize(), less);
  2.1281 +}
  2.1282 +
  2.1283 +// checks for boundaries
  2.1284 +template<class Array, class Less> 
  2.1285 +bool QuickSortSafe(Array& arr, Less less)
  2.1286 +{
  2.1287 +    return QuickSortSlicedSafe(arr, 0, arr.GetSize(), less);
  2.1288 +}
  2.1289 +
  2.1290 +
  2.1291 +//-----------------------------------------------------------------------------------
  2.1292 +// ***** QuickSort
  2.1293 +//
  2.1294 +// Sort an array Array, ArrayPaged, ArrayUnsafe.
  2.1295 +// The array must have GetSize() function.
  2.1296 +// The data type must have a defined "<" operator.
  2.1297 +template<class Array> 
  2.1298 +void QuickSort(Array& arr)
  2.1299 +{
  2.1300 +    typedef typename Array::ValueType ValueType;
  2.1301 +    QuickSortSliced(arr, 0, arr.GetSize(), OperatorLess<ValueType>::Compare);
  2.1302 +}
  2.1303 +
  2.1304 +template<class Array> 
  2.1305 +bool QuickSortSafe(Array& arr)
  2.1306 +{
  2.1307 +    typedef typename Array::ValueType ValueType;
  2.1308 +    return QuickSortSlicedSafe(arr, 0, arr.GetSize(), OperatorLess<ValueType>::Compare);
  2.1309 +}
  2.1310 +
  2.1311 +//-----------------------------------------------------------------------------------
  2.1312 +// ***** InsertionSortSliced
  2.1313 +//
  2.1314 +// Sort any part of any array: plain, Array, ArrayPaged, ArrayUnsafe.
  2.1315 +// The range is specified with start, end, where "end" is exclusive!
  2.1316 +// The comparison predicate must be specified.
  2.1317 +// Unlike Quick Sort, the Insertion Sort works much slower in average, 
  2.1318 +// but may be much faster on almost sorted arrays. Besides, it guarantees
  2.1319 +// that the elements will not be swapped if not necessary. For example, 
  2.1320 +// an array with all equal elements will remain "untouched", while 
  2.1321 +// Quick Sort will considerably shuffle the elements in this case.
  2.1322 +template<class Array, class Less> 
  2.1323 +void InsertionSortSliced(Array& arr, UPInt start, UPInt end, Less less)
  2.1324 +{
  2.1325 +    UPInt j = start;
  2.1326 +    UPInt i = j + 1;
  2.1327 +    UPInt limit = end;
  2.1328 +
  2.1329 +    for(; i < limit; j = i, i++)
  2.1330 +    {
  2.1331 +        for(; less(arr[j + 1], arr[j]); j--)
  2.1332 +        {
  2.1333 +            Swap(arr[j + 1], arr[j]);
  2.1334 +            if(j <= start)
  2.1335 +            {
  2.1336 +                break;
  2.1337 +            }
  2.1338 +        }
  2.1339 +    }
  2.1340 +}
  2.1341 +
  2.1342 +
  2.1343 +//-----------------------------------------------------------------------------------
  2.1344 +// ***** InsertionSortSliced
  2.1345 +//
  2.1346 +// Sort any part of any array: plain, Array, ArrayPaged, ArrayUnsafe.
  2.1347 +// The range is specified with start, end, where "end" is exclusive!
  2.1348 +// The data type must have a defined "<" operator.
  2.1349 +template<class Array> 
  2.1350 +void InsertionSortSliced(Array& arr, UPInt start, UPInt end)
  2.1351 +{
  2.1352 +    typedef typename Array::ValueType ValueType;
  2.1353 +    InsertionSortSliced(arr, start, end, OperatorLess<ValueType>::Compare);
  2.1354 +}
  2.1355 +
  2.1356 +//-----------------------------------------------------------------------------------
  2.1357 +// ***** InsertionSort
  2.1358 +//
  2.1359 +// Sort an array Array, ArrayPaged, ArrayUnsafe.
  2.1360 +// The array must have GetSize() function.
  2.1361 +// The comparison predicate must be specified.
  2.1362 +
  2.1363 +template<class Array, class Less> 
  2.1364 +void InsertionSort(Array& arr, Less less)
  2.1365 +{
  2.1366 +    InsertionSortSliced(arr, 0, arr.GetSize(), less);
  2.1367 +}
  2.1368 +
  2.1369 +//-----------------------------------------------------------------------------------
  2.1370 +// ***** InsertionSort
  2.1371 +//
  2.1372 +// Sort an array Array, ArrayPaged, ArrayUnsafe.
  2.1373 +// The array must have GetSize() function.
  2.1374 +// The data type must have a defined "<" operator.
  2.1375 +template<class Array> 
  2.1376 +void InsertionSort(Array& arr)
  2.1377 +{
  2.1378 +    typedef typename Array::ValueType ValueType;
  2.1379 +    InsertionSortSliced(arr, 0, arr.GetSize(), OperatorLess<ValueType>::Compare);
  2.1380 +}
  2.1381 +
  2.1382 +
  2.1383 +
  2.1384 +//-----------------------------------------------------------------------------------
  2.1385 +// ***** LowerBoundSliced
  2.1386 +//
  2.1387 +template<class Array, class Value, class Less>
  2.1388 +UPInt LowerBoundSliced(const Array& arr, UPInt start, UPInt end, const Value& val, Less less)
  2.1389 +{
  2.1390 +    SPInt first = (SPInt)start;
  2.1391 +    SPInt len   = (SPInt)(end - start);
  2.1392 +    SPInt half;
  2.1393 +    SPInt middle;
  2.1394 +    
  2.1395 +    while(len > 0) 
  2.1396 +    {
  2.1397 +        half = len >> 1;
  2.1398 +        middle = first + half;
  2.1399 +        if(less(arr[middle], val)) 
  2.1400 +        {
  2.1401 +            first = middle + 1;
  2.1402 +            len   = len - half - 1;
  2.1403 +        }
  2.1404 +        else
  2.1405 +        {
  2.1406 +            len = half;
  2.1407 +        }
  2.1408 +    }
  2.1409 +    return (UPInt)first;
  2.1410 +}
  2.1411 +
  2.1412 +
  2.1413 +//-----------------------------------------------------------------------------------
  2.1414 +// ***** LowerBoundSliced
  2.1415 +//
  2.1416 +template<class Array, class Value>
  2.1417 +UPInt LowerBoundSliced(const Array& arr, UPInt start, UPInt end, const Value& val)
  2.1418 +{
  2.1419 +    return LowerBoundSliced(arr, start, end, val, OperatorLess<Value>::Compare);
  2.1420 +}
  2.1421 +
  2.1422 +//-----------------------------------------------------------------------------------
  2.1423 +// ***** LowerBoundSized
  2.1424 +//
  2.1425 +template<class Array, class Value>
  2.1426 +UPInt LowerBoundSized(const Array& arr, UPInt size, const Value& val)
  2.1427 +{
  2.1428 +    return LowerBoundSliced(arr, 0, size, val, OperatorLess<Value>::Compare);
  2.1429 +}
  2.1430 +
  2.1431 +//-----------------------------------------------------------------------------------
  2.1432 +// ***** LowerBound
  2.1433 +//
  2.1434 +template<class Array, class Value, class Less>
  2.1435 +UPInt LowerBound(const Array& arr, const Value& val, Less less)
  2.1436 +{
  2.1437 +    return LowerBoundSliced(arr, 0, arr.GetSize(), val, less);
  2.1438 +}
  2.1439 +
  2.1440 +
  2.1441 +//-----------------------------------------------------------------------------------
  2.1442 +// ***** LowerBound
  2.1443 +//
  2.1444 +template<class Array, class Value>
  2.1445 +UPInt LowerBound(const Array& arr, const Value& val)
  2.1446 +{
  2.1447 +    return LowerBoundSliced(arr, 0, arr.GetSize(), val, OperatorLess<Value>::Compare);
  2.1448 +}
  2.1449 +
  2.1450 +
  2.1451 +
  2.1452 +//-----------------------------------------------------------------------------------
  2.1453 +// ***** UpperBoundSliced
  2.1454 +//
  2.1455 +template<class Array, class Value, class Less>
  2.1456 +UPInt UpperBoundSliced(const Array& arr, UPInt start, UPInt end, const Value& val, Less less)
  2.1457 +{
  2.1458 +    SPInt first = (SPInt)start;
  2.1459 +    SPInt len   = (SPInt)(end - start);
  2.1460 +    SPInt half;
  2.1461 +    SPInt middle;
  2.1462 +    
  2.1463 +    while(len > 0) 
  2.1464 +    {
  2.1465 +        half = len >> 1;
  2.1466 +        middle = first + half;
  2.1467 +        if(less(val, arr[middle]))
  2.1468 +        {
  2.1469 +            len = half;
  2.1470 +        }
  2.1471 +        else 
  2.1472 +        {
  2.1473 +            first = middle + 1;
  2.1474 +            len   = len - half - 1;
  2.1475 +        }
  2.1476 +    }
  2.1477 +    return (UPInt)first;
  2.1478 +}
  2.1479 +
  2.1480 +
  2.1481 +//-----------------------------------------------------------------------------------
  2.1482 +// ***** UpperBoundSliced
  2.1483 +//
  2.1484 +template<class Array, class Value>
  2.1485 +UPInt UpperBoundSliced(const Array& arr, UPInt start, UPInt end, const Value& val)
  2.1486 +{
  2.1487 +    return UpperBoundSliced(arr, start, end, val, OperatorLess<Value>::Compare);
  2.1488 +}
  2.1489 +
  2.1490 +
  2.1491 +//-----------------------------------------------------------------------------------
  2.1492 +// ***** UpperBoundSized
  2.1493 +//
  2.1494 +template<class Array, class Value>
  2.1495 +UPInt UpperBoundSized(const Array& arr, UPInt size, const Value& val)
  2.1496 +{
  2.1497 +    return UpperBoundSliced(arr, 0, size, val, OperatorLess<Value>::Compare);
  2.1498 +}
  2.1499 +
  2.1500 +
  2.1501 +//-----------------------------------------------------------------------------------
  2.1502 +// ***** UpperBound
  2.1503 +//
  2.1504 +template<class Array, class Value, class Less>
  2.1505 +UPInt UpperBound(const Array& arr, const Value& val, Less less)
  2.1506 +{
  2.1507 +    return UpperBoundSliced(arr, 0, arr.GetSize(), val, less);
  2.1508 +}
  2.1509 +
  2.1510 +
  2.1511 +//-----------------------------------------------------------------------------------
  2.1512 +// ***** UpperBound
  2.1513 +//
  2.1514 +template<class Array, class Value>
  2.1515 +UPInt UpperBound(const Array& arr, const Value& val)
  2.1516 +{
  2.1517 +    return UpperBoundSliced(arr, 0, arr.GetSize(), val, OperatorLess<Value>::Compare);
  2.1518 +}
  2.1519 +
  2.1520 +
  2.1521 +//-----------------------------------------------------------------------------------
  2.1522 +// ***** ReverseArray
  2.1523 +//
  2.1524 +template<class Array> void ReverseArray(Array& arr)
  2.1525 +{
  2.1526 +    SPInt from = 0;
  2.1527 +    SPInt to   = arr.GetSize() - 1;
  2.1528 +    while(from < to)
  2.1529 +    {
  2.1530 +        Swap(arr[from], arr[to]);
  2.1531 +        ++from;
  2.1532 +        --to;
  2.1533 +    }
  2.1534 +}
  2.1535 +
  2.1536 +
  2.1537 +// ***** AppendArray
  2.1538 +//
  2.1539 +template<class CDst, class CSrc> 
  2.1540 +void AppendArray(CDst& dst, const CSrc& src)
  2.1541 +{
  2.1542 +    UPInt i;
  2.1543 +    for(i = 0; i < src.GetSize(); i++) 
  2.1544 +        dst.PushBack(src[i]);
  2.1545 +}
  2.1546 +
  2.1547 +//-----------------------------------------------------------------------------------
  2.1548 +// ***** ArrayAdaptor
  2.1549 +//
  2.1550 +// A simple adapter that provides the GetSize() method and overloads 
  2.1551 +// operator []. Used to wrap plain arrays in QuickSort and such.
  2.1552 +template<class T> class ArrayAdaptor
  2.1553 +{
  2.1554 +public:
  2.1555 +    typedef T ValueType;
  2.1556 +    ArrayAdaptor() : Data(0), Size(0) {}
  2.1557 +    ArrayAdaptor(T* ptr, UPInt size) : Data(ptr), Size(size) {}
  2.1558 +    UPInt GetSize() const { return Size; }
  2.1559 +    const T& operator [] (UPInt i) const { return Data[i]; }
  2.1560 +          T& operator [] (UPInt i)       { return Data[i]; }
  2.1561 +private:
  2.1562 +    T*      Data;
  2.1563 +    UPInt   Size;
  2.1564 +};
  2.1565 +
  2.1566 +
  2.1567 +//-----------------------------------------------------------------------------------
  2.1568 +// ***** GConstArrayAdaptor
  2.1569 +//
  2.1570 +// A simple const adapter that provides the GetSize() method and overloads 
  2.1571 +// operator []. Used to wrap plain arrays in LowerBound and such.
  2.1572 +template<class T> class ConstArrayAdaptor
  2.1573 +{
  2.1574 +public:
  2.1575 +    typedef T ValueType;
  2.1576 +    ConstArrayAdaptor() : Data(0), Size(0) {}
  2.1577 +    ConstArrayAdaptor(const T* ptr, UPInt size) : Data(ptr), Size(size) {}
  2.1578 +    UPInt GetSize() const { return Size; }
  2.1579 +    const T& operator [] (UPInt i) const { return Data[i]; }
  2.1580 +private:
  2.1581 +    const T* Data;
  2.1582 +    UPInt    Size;
  2.1583 +};
  2.1584 +
  2.1585 +
  2.1586 +
  2.1587 +//-----------------------------------------------------------------------------------
  2.1588 +extern const UByte UpperBitTable[256];
  2.1589 +extern const UByte LowerBitTable[256];
  2.1590 +
  2.1591 +
  2.1592 +
  2.1593 +//-----------------------------------------------------------------------------------
  2.1594 +inline UByte UpperBit(UPInt val)
  2.1595 +{
  2.1596 +#ifndef OVR_64BIT_POINTERS
  2.1597 +
  2.1598 +    if (val & 0xFFFF0000)
  2.1599 +    {
  2.1600 +        return (val & 0xFF000000) ? 
  2.1601 +            UpperBitTable[(val >> 24)       ] + 24: 
  2.1602 +            UpperBitTable[(val >> 16) & 0xFF] + 16;
  2.1603 +    }
  2.1604 +    return (val & 0xFF00) ?
  2.1605 +        UpperBitTable[(val >> 8) & 0xFF] + 8:
  2.1606 +        UpperBitTable[(val     ) & 0xFF];
  2.1607 +
  2.1608 +#else
  2.1609 +
  2.1610 +    if (val & 0xFFFFFFFF00000000)
  2.1611 +    {
  2.1612 +        if (val & 0xFFFF000000000000)
  2.1613 +        {
  2.1614 +            return (val & 0xFF00000000000000) ?
  2.1615 +                UpperBitTable[(val >> 56)       ] + 56: 
  2.1616 +                UpperBitTable[(val >> 48) & 0xFF] + 48;
  2.1617 +        }
  2.1618 +        return (val & 0xFF0000000000) ?
  2.1619 +            UpperBitTable[(val >> 40) & 0xFF] + 40:
  2.1620 +            UpperBitTable[(val >> 32) & 0xFF] + 32;
  2.1621 +    }
  2.1622 +    else
  2.1623 +    {
  2.1624 +        if (val & 0xFFFF0000)
  2.1625 +        {
  2.1626 +            return (val & 0xFF000000) ? 
  2.1627 +                UpperBitTable[(val >> 24)       ] + 24: 
  2.1628 +                UpperBitTable[(val >> 16) & 0xFF] + 16;
  2.1629 +        }
  2.1630 +        return (val & 0xFF00) ?
  2.1631 +            UpperBitTable[(val >> 8) & 0xFF] + 8:
  2.1632 +            UpperBitTable[(val     ) & 0xFF];
  2.1633 +    }
  2.1634 +
  2.1635 +#endif
  2.1636 +}
  2.1637 +
  2.1638 +//-----------------------------------------------------------------------------------
  2.1639 +inline UByte LowerBit(UPInt val)
  2.1640 +{
  2.1641 +#ifndef OVR_64BIT_POINTERS
  2.1642 +
  2.1643 +    if (val & 0xFFFF)
  2.1644 +    {
  2.1645 +        return (val & 0xFF) ?
  2.1646 +            LowerBitTable[ val & 0xFF]:
  2.1647 +            LowerBitTable[(val >> 8) & 0xFF] + 8;
  2.1648 +    }
  2.1649 +    return (val & 0xFF0000) ?
  2.1650 +            LowerBitTable[(val >> 16) & 0xFF] + 16:
  2.1651 +            LowerBitTable[(val >> 24) & 0xFF] + 24;
  2.1652 +
  2.1653 +#else
  2.1654 +
  2.1655 +    if (val & 0xFFFFFFFF)
  2.1656 +    {
  2.1657 +        if (val & 0xFFFF)
  2.1658 +        {
  2.1659 +            return (val & 0xFF) ?
  2.1660 +                LowerBitTable[ val & 0xFF]:
  2.1661 +                LowerBitTable[(val >> 8) & 0xFF] + 8;
  2.1662 +        }
  2.1663 +        return (val & 0xFF0000) ?
  2.1664 +                LowerBitTable[(val >> 16) & 0xFF] + 16:
  2.1665 +                LowerBitTable[(val >> 24) & 0xFF] + 24;
  2.1666 +    }
  2.1667 +    else
  2.1668 +    {
  2.1669 +        if (val & 0xFFFF00000000)
  2.1670 +        {
  2.1671 +             return (val & 0xFF00000000) ?
  2.1672 +                LowerBitTable[(val >> 32) & 0xFF] + 32:
  2.1673 +                LowerBitTable[(val >> 40) & 0xFF] + 40;
  2.1674 +        }
  2.1675 +        return (val & 0xFF000000000000) ?
  2.1676 +            LowerBitTable[(val >> 48) & 0xFF] + 48:
  2.1677 +            LowerBitTable[(val >> 56) & 0xFF] + 56;
  2.1678 +    }
  2.1679 +
  2.1680 +#endif
  2.1681 +}
  2.1682 +
  2.1683 +
  2.1684 +
  2.1685 +// ******* Special (optimized) memory routines
  2.1686 +// Note: null (bad) pointer is not tested
  2.1687 +class MemUtil
  2.1688 +{
  2.1689 +public:
  2.1690 +                                    
  2.1691 +    // Memory compare
  2.1692 +    static int      Cmp  (const void* p1, const void* p2, UPInt byteCount)      { return memcmp(p1, p2, byteCount); }
  2.1693 +    static int      Cmp16(const void* p1, const void* p2, UPInt int16Count);
  2.1694 +    static int      Cmp32(const void* p1, const void* p2, UPInt int32Count);
  2.1695 +    static int      Cmp64(const void* p1, const void* p2, UPInt int64Count); 
  2.1696 +};
  2.1697 +
  2.1698 +// ** Inline Implementation
  2.1699 +
  2.1700 +inline int MemUtil::Cmp16(const void* p1, const void* p2, UPInt int16Count)
  2.1701 +{
  2.1702 +    SInt16*  pa  = (SInt16*)p1; 
  2.1703 +    SInt16*  pb  = (SInt16*)p2;
  2.1704 +    unsigned ic  = 0;
  2.1705 +    if (int16Count == 0)
  2.1706 +        return 0;
  2.1707 +    while (pa[ic] == pb[ic])
  2.1708 +        if (++ic==int16Count)
  2.1709 +            return 0;
  2.1710 +    return pa[ic] > pb[ic] ? 1 : -1;
  2.1711 +}
  2.1712 +inline int MemUtil::Cmp32(const void* p1, const void* p2, UPInt int32Count)
  2.1713 +{
  2.1714 +    SInt32*  pa  = (SInt32*)p1;
  2.1715 +    SInt32*  pb  = (SInt32*)p2;
  2.1716 +    unsigned ic  = 0;
  2.1717 +    if (int32Count == 0)
  2.1718 +        return 0;
  2.1719 +    while (pa[ic] == pb[ic])
  2.1720 +        if (++ic==int32Count)
  2.1721 +            return 0;
  2.1722 +    return pa[ic] > pb[ic] ? 1 : -1;
  2.1723 +}
  2.1724 +inline int MemUtil::Cmp64(const void* p1, const void* p2, UPInt int64Count)
  2.1725 +{
  2.1726 +    SInt64*  pa  = (SInt64*)p1;
  2.1727 +    SInt64*  pb  = (SInt64*)p2;
  2.1728 +    unsigned ic  = 0;
  2.1729 +    if (int64Count == 0)
  2.1730 +        return 0;
  2.1731 +    while (pa[ic] == pb[ic])
  2.1732 +        if (++ic==int64Count)
  2.1733 +            return 0;
  2.1734 +    return pa[ic] > pb[ic] ? 1 : -1;
  2.1735 +}
  2.1736 +
  2.1737 +// ** End Inline Implementation
  2.1738 +
  2.1739 +
  2.1740 +//-----------------------------------------------------------------------------------
  2.1741 +// ******* Byte Order Conversions
  2.1742 +namespace ByteUtil {
  2.1743 +
  2.1744 +    // *** Swap Byte Order
  2.1745 +
  2.1746 +    // Swap the byte order of a byte array
  2.1747 +    inline void     SwapOrder(void* pv, int size)
  2.1748 +    {
  2.1749 +        UByte*  pb = (UByte*)pv;
  2.1750 +        UByte   temp;
  2.1751 +        for (int i = 0; i < size>>1; i++)
  2.1752 +        { 
  2.1753 +            temp            = pb[size-1-i];
  2.1754 +            pb[size-1-i]    = pb[i];
  2.1755 +            pb[i]           = temp; 
  2.1756 +        }
  2.1757 +    }
  2.1758 +
  2.1759 +    // Swap the byte order of primitive types
  2.1760 +    inline UByte    SwapOrder(UByte v)      { return v; }
  2.1761 +    inline SByte    SwapOrder(SByte v)      { return v; }
  2.1762 +    inline UInt16   SwapOrder(UInt16 v)     { return UInt16(v>>8)|UInt16(v<<8); }
  2.1763 +    inline SInt16   SwapOrder(SInt16 v)     { return SInt16((UInt16(v)>>8)|(v<<8)); }
  2.1764 +    inline UInt32   SwapOrder(UInt32 v)     { return (v>>24)|((v&0x00FF0000)>>8)|((v&0x0000FF00)<<8)|(v<<24); }
  2.1765 +    inline SInt32   SwapOrder(SInt32 p)     { return (SInt32)SwapOrder(UInt32(p)); }
  2.1766 +    inline UInt64   SwapOrder(UInt64 v)
  2.1767 +    { 
  2.1768 +        return   (v>>56) |
  2.1769 +                 ((v&UInt64(0x00FF000000000000))>>40) |
  2.1770 +                 ((v&UInt64(0x0000FF0000000000))>>24) |
  2.1771 +                 ((v&UInt64(0x000000FF00000000))>>8)  |
  2.1772 +                 ((v&UInt64(0x00000000FF000000))<<8)  |
  2.1773 +                 ((v&UInt64(0x0000000000FF0000))<<24) |
  2.1774 +                 ((v&UInt64(0x000000000000FF00))<<40) |
  2.1775 +                 (v<<56); 
  2.1776 +    }
  2.1777 +    inline SInt64   SwapOrder(SInt64 v)     { return (SInt64)SwapOrder(UInt64(v)); }
  2.1778 +    inline float    SwapOrder(float p)      
  2.1779 +    { 
  2.1780 +        union {
  2.1781 +            float p;
  2.1782 +            UInt32 v;
  2.1783 +        } u;
  2.1784 +        u.p = p;
  2.1785 +        u.v = SwapOrder(u.v);
  2.1786 +        return u.p;
  2.1787 +    }
  2.1788 +
  2.1789 +    inline double   SwapOrder(double p)
  2.1790 +    { 
  2.1791 +        union {
  2.1792 +            double p;
  2.1793 +            UInt64 v;
  2.1794 +        } u;
  2.1795 +        u.p = p;
  2.1796 +        u.v = SwapOrder(u.v);
  2.1797 +        return u.p;
  2.1798 +    }
  2.1799 +    
  2.1800 +    // *** Byte-order conversion
  2.1801 +
  2.1802 +#if (OVR_BYTE_ORDER == OVR_LITTLE_ENDIAN)
  2.1803 +    // Little Endian to System (LE)
  2.1804 +    inline UByte    LEToSystem(UByte  v)    { return v; }
  2.1805 +    inline SByte    LEToSystem(SByte  v)    { return v; }
  2.1806 +    inline UInt16   LEToSystem(UInt16 v)    { return v; }
  2.1807 +    inline SInt16   LEToSystem(SInt16 v)    { return v; }
  2.1808 +    inline UInt32   LEToSystem(UInt32 v)    { return v; }
  2.1809 +    inline SInt32   LEToSystem(SInt32 v)    { return v; }
  2.1810 +    inline UInt64   LEToSystem(UInt64 v)    { return v; }
  2.1811 +    inline SInt64   LEToSystem(SInt64 v)    { return v; }
  2.1812 +    inline float    LEToSystem(float  v)    { return v; }
  2.1813 +    inline double   LEToSystem(double v)    { return v; }
  2.1814 +
  2.1815 +    // Big Endian to System (LE)
  2.1816 +    inline UByte    BEToSystem(UByte  v)    { return SwapOrder(v); }
  2.1817 +    inline SByte    BEToSystem(SByte  v)    { return SwapOrder(v); }
  2.1818 +    inline UInt16   BEToSystem(UInt16 v)    { return SwapOrder(v); }
  2.1819 +    inline SInt16   BEToSystem(SInt16 v)    { return SwapOrder(v); }
  2.1820 +    inline UInt32   BEToSystem(UInt32 v)    { return SwapOrder(v); }
  2.1821 +    inline SInt32   BEToSystem(SInt32 v)    { return SwapOrder(v); }
  2.1822 +    inline UInt64   BEToSystem(UInt64 v)    { return SwapOrder(v); }
  2.1823 +    inline SInt64   BEToSystem(SInt64 v)    { return SwapOrder(v); }
  2.1824 +    inline float    BEToSystem(float  v)    { return SwapOrder(v); }
  2.1825 +    inline double   BEToSystem(double v)    { return SwapOrder(v); }
  2.1826 +
  2.1827 +    // System (LE) to Little Endian
  2.1828 +    inline UByte    SystemToLE(UByte  v)    { return v; }
  2.1829 +    inline SByte    SystemToLE(SByte  v)    { return v; }
  2.1830 +    inline UInt16   SystemToLE(UInt16 v)    { return v; }
  2.1831 +    inline SInt16   SystemToLE(SInt16 v)    { return v; }
  2.1832 +    inline UInt32   SystemToLE(UInt32 v)    { return v; }
  2.1833 +    inline SInt32   SystemToLE(SInt32 v)    { return v; }
  2.1834 +    inline UInt64   SystemToLE(UInt64 v)    { return v; }
  2.1835 +    inline SInt64   SystemToLE(SInt64 v)    { return v; }
  2.1836 +    inline float    SystemToLE(float  v)    { return v; }
  2.1837 +    inline double   SystemToLE(double v)    { return v; }   
  2.1838 +
  2.1839 +    // System (LE) to Big Endian
  2.1840 +    inline UByte    SystemToBE(UByte  v)    { return SwapOrder(v); }
  2.1841 +    inline SByte    SystemToBE(SByte  v)    { return SwapOrder(v); }
  2.1842 +    inline UInt16   SystemToBE(UInt16 v)    { return SwapOrder(v); }
  2.1843 +    inline SInt16   SystemToBE(SInt16 v)    { return SwapOrder(v); }
  2.1844 +    inline UInt32   SystemToBE(UInt32 v)    { return SwapOrder(v); }
  2.1845 +    inline SInt32   SystemToBE(SInt32 v)    { return SwapOrder(v); }
  2.1846 +    inline UInt64   SystemToBE(UInt64 v)    { return SwapOrder(v); }
  2.1847 +    inline SInt64   SystemToBE(SInt64 v)    { return SwapOrder(v); }
  2.1848 +    inline float    SystemToBE(float  v)    { return SwapOrder(v); }
  2.1849 +    inline double   SystemToBE(double v)    { return SwapOrder(v); }
  2.1850 +
  2.1851 +#elif (OVR_BYTE_ORDER == OVR_BIG_ENDIAN)
  2.1852 +    // Little Endian to System (BE)
  2.1853 +    inline UByte    LEToSystem(UByte  v)    { return SwapOrder(v); }
  2.1854 +    inline SByte    LEToSystem(SByte  v)    { return SwapOrder(v); }
  2.1855 +    inline UInt16   LEToSystem(UInt16 v)    { return SwapOrder(v); }
  2.1856 +    inline SInt16   LEToSystem(SInt16 v)    { return SwapOrder(v); }
  2.1857 +    inline UInt32   LEToSystem(UInt32 v)    { return SwapOrder(v); }
  2.1858 +    inline SInt32   LEToSystem(SInt32 v)    { return SwapOrder(v); }
  2.1859 +    inline UInt64   LEToSystem(UInt64 v)    { return SwapOrder(v); }
  2.1860 +    inline SInt64   LEToSystem(SInt64 v)    { return SwapOrder(v); }
  2.1861 +    inline float    LEToSystem(float  v)    { return SwapOrder(v); }
  2.1862 +    inline double   LEToSystem(double v)    { return SwapOrder(v); }
  2.1863 +
  2.1864 +    // Big Endian to System (BE)
  2.1865 +    inline UByte    BEToSystem(UByte  v)    { return v; }
  2.1866 +    inline SByte    BEToSystem(SByte  v)    { return v; }
  2.1867 +    inline UInt16   BEToSystem(UInt16 v)    { return v; }
  2.1868 +    inline SInt16   BEToSystem(SInt16 v)    { return v; }
  2.1869 +    inline UInt32   BEToSystem(UInt32 v)    { return v; }
  2.1870 +    inline SInt32   BEToSystem(SInt32 v)    { return v; }
  2.1871 +    inline UInt64   BEToSystem(UInt64 v)    { return v; }
  2.1872 +    inline SInt64   BEToSystem(SInt64 v)    { return v; }
  2.1873 +    inline float    BEToSystem(float  v)    { return v; }
  2.1874 +    inline double   BEToSystem(double v)    { return v; }
  2.1875 +
  2.1876 +    // System (BE) to Little Endian
  2.1877 +    inline UByte    SystemToLE(UByte  v)    { return SwapOrder(v); }
  2.1878 +    inline SByte    SystemToLE(SByte  v)    { return SwapOrder(v); }
  2.1879 +    inline UInt16   SystemToLE(UInt16 v)    { return SwapOrder(v); }
  2.1880 +    inline SInt16   SystemToLE(SInt16 v)    { return SwapOrder(v); }
  2.1881 +    inline UInt32   SystemToLE(UInt32 v)    { return SwapOrder(v); }
  2.1882 +    inline SInt32   SystemToLE(SInt32 v)    { return SwapOrder(v); }
  2.1883 +    inline UInt64   SystemToLE(UInt64 v)    { return SwapOrder(v); }
  2.1884 +    inline SInt64   SystemToLE(SInt64 v)    { return SwapOrder(v); }
  2.1885 +    inline float    SystemToLE(float  v)    { return SwapOrder(v); }
  2.1886 +    inline double   SystemToLE(double v)    { return SwapOrder(v); }
  2.1887 +
  2.1888 +    // System (BE) to Big Endian
  2.1889 +    inline UByte    SystemToBE(UByte  v)    { return v; }
  2.1890 +    inline SByte    SystemToBE(SByte  v)    { return v; }
  2.1891 +    inline UInt16   SystemToBE(UInt16 v)    { return v; }
  2.1892 +    inline SInt16   SystemToBE(SInt16 v)    { return v; }
  2.1893 +    inline UInt32   SystemToBE(UInt32 v)    { return v; }
  2.1894 +    inline SInt32   SystemToBE(SInt32 v)    { return v; }
  2.1895 +    inline UInt64   SystemToBE(UInt64 v)    { return v; }
  2.1896 +    inline SInt64   SystemToBE(SInt64 v)    { return v; }
  2.1897 +    inline float    SystemToBE(float  v)    { return v; }
  2.1898 +    inline double   SystemToBE(double v)    { return v; }
  2.1899 +
  2.1900 +#else
  2.1901 +    #error "OVR_BYTE_ORDER must be defined to OVR_LITTLE_ENDIAN or OVR_BIG_ENDIAN"
  2.1902 +#endif
  2.1903 +
  2.1904 +} // namespace ByteUtil
  2.1905 +
  2.1906 +
  2.1907 +
  2.1908 +}} // OVR::Alg
  2.1909 +
  2.1910 +#endif
     3.1 --- a/libovr/Src/Kernel/OVR_Allocator.cpp	Sat Sep 14 17:51:03 2013 +0300
     3.2 +++ b/libovr/Src/Kernel/OVR_Allocator.cpp	Sun Sep 15 04:10:05 2013 +0300
     3.3 @@ -1,1 +1,84 @@
     3.4 -/************************************************************************************
     3.5 
     3.6 Filename    :   OVR_Allocator.cpp
     3.7 Content     :   Installable memory allocator implementation
     3.8 Created     :   September 19, 2012
     3.9 Notes       : 
    3.10 
    3.11 Copyright   :   Copyright 2012 Oculus VR, Inc. All Rights reserved.
    3.12 
    3.13 Use of this software is subject to the terms of the Oculus license
    3.14 agreement provided at the time of installation or download, or which
    3.15 otherwise accompanies this software in either electronic or hard copy form.
    3.16 
    3.17 ************************************************************************************/
    3.18 
    3.19 #include "OVR_Allocator.h"
    3.20 #ifdef OVR_OS_MAC
    3.21  #include <stdlib.h>
    3.22 #else
    3.23  #include <malloc.h>
    3.24 #endif
    3.25 
    3.26 namespace OVR {
    3.27 
    3.28 //-----------------------------------------------------------------------------------
    3.29 // ***** Allocator
    3.30 
    3.31 Allocator* Allocator::pInstance = 0;
    3.32 
    3.33 // Default AlignedAlloc implementation will delegate to Alloc/Free after doing rounding.
    3.34 void* Allocator::AllocAligned(UPInt size, UPInt align)
    3.35 {
    3.36     OVR_ASSERT((align & (align-1)) == 0);
    3.37     align = (align > sizeof(UPInt)) ? align : sizeof(UPInt);
    3.38     UPInt p = (UPInt)Alloc(size+align);
    3.39     UPInt aligned = 0;
    3.40     if (p)
    3.41     {
    3.42         aligned = (UPInt(p) + align-1) & ~(align-1);
    3.43         if (aligned == p) 
    3.44             aligned += align;
    3.45         *(((UPInt*)aligned)-1) = aligned-p;
    3.46     }
    3.47     return (void*)aligned;
    3.48 }
    3.49 
    3.50 void Allocator::FreeAligned(void* p)
    3.51 {
    3.52     UPInt src = UPInt(p) - *(((UPInt*)p)-1);
    3.53     Free((void*)src);
    3.54 }
    3.55 
    3.56 
    3.57 //------------------------------------------------------------------------
    3.58 // ***** Default Allocator
    3.59 
    3.60 // This allocator is created and used if no other allocator is installed.
    3.61 // Default allocator delegates to system malloc.
    3.62 
    3.63 void* DefaultAllocator::Alloc(UPInt size)
    3.64 {
    3.65     return malloc(size);
    3.66 }
    3.67 void* DefaultAllocator::AllocDebug(UPInt size, const char* file, unsigned line)
    3.68 {
    3.69 #if defined(OVR_CC_MSVC) && defined(_CRTDBG_MAP_ALLOC)
    3.70     return _malloc_dbg(size, _NORMAL_BLOCK, file, line);
    3.71 #else
    3.72     OVR_UNUSED2(file, line);
    3.73     return malloc(size);
    3.74 #endif
    3.75 }
    3.76 
    3.77 void* DefaultAllocator::Realloc(void* p, UPInt newSize)
    3.78 {
    3.79     return realloc(p, newSize);
    3.80 }
    3.81 void DefaultAllocator::Free(void *p)
    3.82 {
    3.83     return free(p);
    3.84 }
    3.85 
    3.86 
    3.87 } // OVR
    3.88 \ No newline at end of file
    3.89 +/************************************************************************************
    3.90 +
    3.91 +Filename    :   OVR_Allocator.cpp
    3.92 +Content     :   Installable memory allocator implementation
    3.93 +Created     :   September 19, 2012
    3.94 +Notes       : 
    3.95 +
    3.96 +Copyright   :   Copyright 2012 Oculus VR, Inc. All Rights reserved.
    3.97 +
    3.98 +Use of this software is subject to the terms of the Oculus license
    3.99 +agreement provided at the time of installation or download, or which
   3.100 +otherwise accompanies this software in either electronic or hard copy form.
   3.101 +
   3.102 +************************************************************************************/
   3.103 +
   3.104 +#include "OVR_Allocator.h"
   3.105 +#ifdef OVR_OS_MAC
   3.106 + #include <stdlib.h>
   3.107 +#else
   3.108 + #include <malloc.h>
   3.109 +#endif
   3.110 +
   3.111 +namespace OVR {
   3.112 +
   3.113 +//-----------------------------------------------------------------------------------
   3.114 +// ***** Allocator
   3.115 +
   3.116 +Allocator* Allocator::pInstance = 0;
   3.117 +
   3.118 +// Default AlignedAlloc implementation will delegate to Alloc/Free after doing rounding.
   3.119 +void* Allocator::AllocAligned(UPInt size, UPInt align)
   3.120 +{
   3.121 +    OVR_ASSERT((align & (align-1)) == 0);
   3.122 +    align = (align > sizeof(UPInt)) ? align : sizeof(UPInt);
   3.123 +    UPInt p = (UPInt)Alloc(size+align);
   3.124 +    UPInt aligned = 0;
   3.125 +    if (p)
   3.126 +    {
   3.127 +        aligned = (UPInt(p) + align-1) & ~(align-1);
   3.128 +        if (aligned == p) 
   3.129 +            aligned += align;
   3.130 +        *(((UPInt*)aligned)-1) = aligned-p;
   3.131 +    }
   3.132 +    return (void*)aligned;
   3.133 +}
   3.134 +
   3.135 +void Allocator::FreeAligned(void* p)
   3.136 +{
   3.137 +    UPInt src = UPInt(p) - *(((UPInt*)p)-1);
   3.138 +    Free((void*)src);
   3.139 +}
   3.140 +
   3.141 +
   3.142 +//------------------------------------------------------------------------
   3.143 +// ***** Default Allocator
   3.144 +
   3.145 +// This allocator is created and used if no other allocator is installed.
   3.146 +// Default allocator delegates to system malloc.
   3.147 +
   3.148 +void* DefaultAllocator::Alloc(UPInt size)
   3.149 +{
   3.150 +    return malloc(size);
   3.151 +}
   3.152 +void* DefaultAllocator::AllocDebug(UPInt size, const char* file, unsigned line)
   3.153 +{
   3.154 +#if defined(OVR_CC_MSVC) && defined(_CRTDBG_MAP_ALLOC)
   3.155 +    return _malloc_dbg(size, _NORMAL_BLOCK, file, line);
   3.156 +#else
   3.157 +    OVR_UNUSED2(file, line);
   3.158 +    return malloc(size);
   3.159 +#endif
   3.160 +}
   3.161 +
   3.162 +void* DefaultAllocator::Realloc(void* p, UPInt newSize)
   3.163 +{
   3.164 +    return realloc(p, newSize);
   3.165 +}
   3.166 +void DefaultAllocator::Free(void *p)
   3.167 +{
   3.168 +    return free(p);
   3.169 +}
   3.170 +
   3.171 +
   3.172 +} // OVR
     4.1 --- a/libovr/Src/Kernel/OVR_Allocator.h	Sat Sep 14 17:51:03 2013 +0300
     4.2 +++ b/libovr/Src/Kernel/OVR_Allocator.h	Sun Sep 15 04:10:05 2013 +0300
     4.3 @@ -1,1 +1,336 @@
     4.4 -/************************************************************************************
     4.5 
     4.6 PublicHeader:   OVR.h
     4.7 Filename    :   OVR_Allocator.h
     4.8 Content     :   Installable memory allocator
     4.9 Created     :   September 19, 2012
    4.10 Notes       : 
    4.11 
    4.12 Copyright   :   Copyright 2012 Oculus VR, Inc. All Rights reserved.
    4.13 
    4.14 Use of this software is subject to the terms of the Oculus license
    4.15 agreement provided at the time of installation or download, or which
    4.16 otherwise accompanies this software in either electronic or hard copy form.
    4.17 
    4.18 ************************************************************************************/
    4.19 
    4.20 #ifndef OVR_Allocator_h
    4.21 #define OVR_Allocator_h
    4.22 
    4.23 #include "OVR_Types.h"
    4.24 
    4.25 //-----------------------------------------------------------------------------------
    4.26 
    4.27 // ***** Disable template-unfriendly MS VC++ warnings
    4.28 #if defined(OVR_CC_MSVC)
    4.29 // Pragma to prevent long name warnings in in VC++
    4.30 #pragma warning(disable : 4503)
    4.31 #pragma warning(disable : 4786)
    4.32 // In MSVC 7.1, warning about placement new POD default initializer
    4.33 #pragma warning(disable : 4345)
    4.34 #endif
    4.35 
    4.36 // Un-define new so that placement constructors work
    4.37 #undef new
    4.38 
    4.39 
    4.40 //-----------------------------------------------------------------------------------
    4.41 // ***** Placement new overrides
    4.42 
    4.43 // Calls constructor on own memory created with "new(ptr) type"
    4.44 #ifndef __PLACEMENT_NEW_INLINE
    4.45 #define __PLACEMENT_NEW_INLINE
    4.46 
    4.47 #   if defined(OVR_CC_MWERKS) || defined(OVR_CC_BORLAND) || defined(OVR_CC_GNU)
    4.48 #      include <new>
    4.49 #   else
    4.50     // Useful on MSVC
    4.51     OVR_FORCE_INLINE void* operator new     (OVR::UPInt n, void *ptr) { OVR_UNUSED(n); return ptr; }
    4.52     OVR_FORCE_INLINE void  operator delete  (void *, void *)     { }
    4.53 #   endif
    4.54 
    4.55 #endif // __PLACEMENT_NEW_INLINE
    4.56 
    4.57 
    4.58 
    4.59 //------------------------------------------------------------------------
    4.60 // ***** Macros to redefine class new/delete operators
    4.61 
    4.62 // Types specifically declared to allow disambiguation of address in
    4.63 // class member operator new.
    4.64 
    4.65 #define OVR_MEMORY_REDEFINE_NEW_IMPL(class_name, check_delete)                          \
    4.66     void*   operator new(UPInt sz)                                                      \
    4.67     { void *p = OVR_ALLOC_DEBUG(sz, __FILE__, __LINE__); return p; }                                              \
    4.68     void*   operator new(UPInt sz, const char* file, int line)                          \
    4.69     { void* p = OVR_ALLOC_DEBUG(sz, file, line); OVR_UNUSED2(file, line); return p; }   \
    4.70     void    operator delete(void *p)                                                    \
    4.71     { check_delete(class_name, p); OVR_FREE(p); }                                       \
    4.72     void    operator delete(void *p, const char*, int)                                  \
    4.73     { check_delete(class_name, p); OVR_FREE(p); }                          
    4.74 
    4.75 #define OVR_MEMORY_DEFINE_PLACEMENT_NEW                                                 \
    4.76     void*   operator new        (UPInt n, void *ptr)    { OVR_UNUSED(n); return ptr; }  \
    4.77     void    operator delete     (void *ptr, void *ptr2) { OVR_UNUSED2(ptr,ptr2); }
    4.78 
    4.79 
    4.80 #define OVR_MEMORY_CHECK_DELETE_NONE(class_name, p)
    4.81 
    4.82 // Redefined all delete/new operators in a class without custom memory initialization
    4.83 #define OVR_MEMORY_REDEFINE_NEW(class_name) \
    4.84     OVR_MEMORY_REDEFINE_NEW_IMPL(class_name, OVR_MEMORY_CHECK_DELETE_NONE)
    4.85 
    4.86 
    4.87 namespace OVR {
    4.88 
    4.89 //-----------------------------------------------------------------------------------
    4.90 // ***** Construct / Destruct
    4.91 
    4.92 // Construct/Destruct functions are useful when new is redefined, as they can
    4.93 // be called instead of placement new constructors.
    4.94 
    4.95 
    4.96 template <class T>
    4.97 OVR_FORCE_INLINE T*  Construct(void *p)
    4.98 {
    4.99     return ::new(p) T;
   4.100 }
   4.101 
   4.102 template <class T>
   4.103 OVR_FORCE_INLINE T*  Construct(void *p, const T& source)
   4.104 {
   4.105     return ::new(p) T(source);
   4.106 }
   4.107 
   4.108 // Same as above, but allows for a different type of constructor.
   4.109 template <class T, class S>
   4.110 OVR_FORCE_INLINE T*  ConstructAlt(void *p, const S& source)
   4.111 {
   4.112     return ::new(p) T(source);
   4.113 }
   4.114 
   4.115 template <class T, class S1, class S2>
   4.116 OVR_FORCE_INLINE T*  ConstructAlt(void *p, const S1& src1, const S2& src2)
   4.117 {
   4.118     return ::new(p) T(src1, src2);
   4.119 }
   4.120 
   4.121 template <class T>
   4.122 OVR_FORCE_INLINE void ConstructArray(void *p, UPInt count)
   4.123 {
   4.124     UByte *pdata = (UByte*)p;
   4.125     for (UPInt i=0; i< count; ++i, pdata += sizeof(T))
   4.126     {
   4.127         Construct<T>(pdata);
   4.128     }
   4.129 }
   4.130 
   4.131 template <class T>
   4.132 OVR_FORCE_INLINE void ConstructArray(void *p, UPInt count, const T& source)
   4.133 {
   4.134     UByte *pdata = (UByte*)p;
   4.135     for (UPInt i=0; i< count; ++i, pdata += sizeof(T))
   4.136     {
   4.137         Construct<T>(pdata, source);
   4.138     }
   4.139 }
   4.140 
   4.141 template <class T>
   4.142 OVR_FORCE_INLINE void Destruct(T *pobj)
   4.143 {
   4.144     pobj->~T();
   4.145     OVR_UNUSED1(pobj); // Fix incorrect 'unused variable' MSVC warning.
   4.146 }
   4.147 
   4.148 template <class T>
   4.149 OVR_FORCE_INLINE void DestructArray(T *pobj, UPInt count)
   4.150 {   
   4.151     for (UPInt i=0; i<count; ++i, ++pobj)
   4.152         pobj->~T();
   4.153 }
   4.154 
   4.155 
   4.156 //-----------------------------------------------------------------------------------
   4.157 // ***** Allocator
   4.158 
   4.159 // Allocator defines a memory allocation interface that developers can override
   4.160 // to to provide memory for OVR; an instance of this class is typically created on
   4.161 // application startup and passed into System or OVR::System constructor.
   4.162 // 
   4.163 //
   4.164 // Users implementing this interface must provide three functions: Alloc, Free,
   4.165 // and Realloc. Implementations of these functions must honor the requested alignment.
   4.166 // Although arbitrary alignment requests are possible, requested alignment will
   4.167 // typically be small, such as 16 bytes or less.
   4.168 
   4.169 class Allocator
   4.170 {
   4.171     friend class System;
   4.172 public:
   4.173 
   4.174     // *** Standard Alignment Alloc/Free
   4.175 
   4.176     // Allocate memory of specified size with default alignment.
   4.177     // Alloc of size==0 will allocate a tiny block & return a valid pointer;
   4.178     // this makes it suitable for new operator.
   4.179     virtual void*   Alloc(UPInt size) = 0;
   4.180     // Same as Alloc, but provides an option of passing debug data.
   4.181     virtual void*   AllocDebug(UPInt size, const char* file, unsigned line)
   4.182     { OVR_UNUSED2(file, line); return Alloc(size); }
   4.183 
   4.184     // Reallocate memory block to a new size, copying data if necessary. Returns the pointer to
   4.185     // new memory block, which may be the same as original pointer. Will return 0 if reallocation
   4.186     // failed, in which case previous memory is still valid.
   4.187     // Realloc to decrease size will never fail.
   4.188     // Realloc of pointer == 0 is equivalent to Alloc
   4.189     // Realloc to size == 0, shrinks to the minimal size, pointer remains valid and requires Free().
   4.190     virtual void*   Realloc(void* p, UPInt newSize) = 0;
   4.191 
   4.192     // Frees memory allocated by Alloc/Realloc.
   4.193     // Free of null pointer is valid and will do nothing.
   4.194     virtual void    Free(void *p) = 0;
   4.195 
   4.196 
   4.197     // *** Standard Alignment Alloc/Free
   4.198 
   4.199     // Allocate memory of specified alignment.
   4.200     // Memory allocated with AllocAligned MUST be freed with FreeAligned.
   4.201     // Default implementation will delegate to Alloc/Free after doing rounding.
   4.202     virtual void*   AllocAligned(UPInt size, UPInt align);    
   4.203     // Frees memory allocated with AllocAligned.
   4.204     virtual void    FreeAligned(void* p);
   4.205     
   4.206     // Returns the pointer to the current globally installed Allocator instance.
   4.207     // This pointer is used for most of the memory allocations.
   4.208     static Allocator* GetInstance() { return pInstance; }
   4.209 
   4.210 
   4.211 protected:
   4.212     // onSystemShutdown is called on the allocator during System::Shutdown.
   4.213     // At this point, all allocations should've been freed.
   4.214     virtual void    onSystemShutdown() { }
   4.215 
   4.216 public:
   4.217     static  void    setInstance(Allocator* palloc)    
   4.218     {
   4.219         OVR_ASSERT((pInstance == 0) || (palloc == 0));
   4.220         pInstance = palloc;
   4.221     }
   4.222 
   4.223 private:
   4.224 
   4.225     static Allocator* pInstance;
   4.226 };
   4.227 
   4.228 
   4.229 
   4.230 //------------------------------------------------------------------------
   4.231 // ***** Allocator_SingletonSupport
   4.232 
   4.233 // Allocator_SingletonSupport is a Allocator wrapper class that implements
   4.234 // the InitSystemSingleton static function, used to create a global singleton
   4.235 // used for the OVR::System default argument initialization.
   4.236 //
   4.237 // End users implementing custom Allocator interface don't need to make use of this base
   4.238 // class; they can just create an instance of their own class on stack and pass it to System.
   4.239 
   4.240 template<class D>
   4.241 class Allocator_SingletonSupport : public Allocator
   4.242 {
   4.243     struct AllocContainer
   4.244     {        
   4.245         UPInt Data[(sizeof(D) + sizeof(UPInt)-1) / sizeof(UPInt)];
   4.246         bool  Initialized;
   4.247         AllocContainer() : Initialized(0) { }
   4.248     };
   4.249 
   4.250     AllocContainer* pContainer;
   4.251 
   4.252 public:
   4.253     Allocator_SingletonSupport() : pContainer(0) { }
   4.254 
   4.255     // Creates a singleton instance of this Allocator class used
   4.256     // on OVR_DEFAULT_ALLOCATOR during System initialization.
   4.257     static  D*  InitSystemSingleton()
   4.258     {
   4.259         static AllocContainer Container;
   4.260         OVR_ASSERT(Container.Initialized == false);
   4.261 
   4.262         Allocator_SingletonSupport<D> *presult = Construct<D>((void*)Container.Data);
   4.263         presult->pContainer   = &Container;
   4.264         Container.Initialized = true;
   4.265         return (D*)presult;
   4.266     }
   4.267 
   4.268 protected:
   4.269     virtual void onSystemShutdown()
   4.270     {
   4.271         Allocator::onSystemShutdown();
   4.272         if (pContainer)
   4.273         {
   4.274             pContainer->Initialized = false;
   4.275             Destruct((D*)this);
   4.276             pContainer = 0;
   4.277         }
   4.278     }
   4.279 };
   4.280 
   4.281 //------------------------------------------------------------------------
   4.282 // ***** Default Allocator
   4.283 
   4.284 // This allocator is created and used if no other allocator is installed.
   4.285 // Default allocator delegates to system malloc.
   4.286 
   4.287 class DefaultAllocator : public Allocator_SingletonSupport<DefaultAllocator>
   4.288 {
   4.289 public:
   4.290     virtual void*   Alloc(UPInt size);
   4.291     virtual void*   AllocDebug(UPInt size, const char* file, unsigned line);
   4.292     virtual void*   Realloc(void* p, UPInt newSize);
   4.293     virtual void    Free(void *p);
   4.294 };
   4.295 
   4.296 
   4.297 //------------------------------------------------------------------------
   4.298 // ***** Memory Allocation Macros
   4.299 
   4.300 // These macros should be used for global allocation. In the future, these
   4.301 // macros will allows allocation to be extended with debug file/line information
   4.302 // if necessary.
   4.303 
   4.304 #define OVR_REALLOC(p,s)        OVR::Allocator::GetInstance()->Realloc((p),(s))
   4.305 #define OVR_FREE(p)             OVR::Allocator::GetInstance()->Free((p))
   4.306 #define OVR_ALLOC_ALIGNED(s,a)  OVR::Allocator::GetInstance()->AllocAligned((s),(a))
   4.307 #define OVR_FREE_ALIGNED(p)     OVR::Allocator::GetInstance()->FreeAligned((p))
   4.308 
   4.309 #ifdef OVR_BUILD_DEBUG
   4.310 #define OVR_ALLOC(s)            OVR::Allocator::GetInstance()->AllocDebug((s), __FILE__, __LINE__)
   4.311 #define OVR_ALLOC_DEBUG(s,f,l)  OVR::Allocator::GetInstance()->AllocDebug((s), f, l)
   4.312 #else
   4.313 #define OVR_ALLOC(s)            OVR::Allocator::GetInstance()->Alloc((s))
   4.314 #define OVR_ALLOC_DEBUG(s,f,l)  OVR::Allocator::GetInstance()->Alloc((s))
   4.315 #endif
   4.316 
   4.317 //------------------------------------------------------------------------
   4.318 
   4.319 // Base class that overrides the new and delete operators.
   4.320 // Deriving from this class, even as a multiple base, incurs no space overhead.
   4.321 class NewOverrideBase
   4.322 {
   4.323 public:
   4.324 
   4.325     // Redefine all new & delete operators.
   4.326     OVR_MEMORY_REDEFINE_NEW(NewOverrideBase)
   4.327 };
   4.328 
   4.329 
   4.330 } // OVR
   4.331 
   4.332 
   4.333 // Redefine operator 'new' if necessary.
   4.334 #if defined(OVR_DEFINE_NEW)
   4.335 #define new OVR_DEFINE_NEW
   4.336 #endif
   4.337 
   4.338 
   4.339 #endif // OVR_Memory
   4.340 \ No newline at end of file
   4.341 +/************************************************************************************
   4.342 +
   4.343 +PublicHeader:   OVR.h
   4.344 +Filename    :   OVR_Allocator.h
   4.345 +Content     :   Installable memory allocator
   4.346 +Created     :   September 19, 2012
   4.347 +Notes       : 
   4.348 +
   4.349 +Copyright   :   Copyright 2012 Oculus VR, Inc. All Rights reserved.
   4.350 +
   4.351 +Use of this software is subject to the terms of the Oculus license
   4.352 +agreement provided at the time of installation or download, or which
   4.353 +otherwise accompanies this software in either electronic or hard copy form.
   4.354 +
   4.355 +************************************************************************************/
   4.356 +
   4.357 +#ifndef OVR_Allocator_h
   4.358 +#define OVR_Allocator_h
   4.359 +
   4.360 +#include "OVR_Types.h"
   4.361 +
   4.362 +//-----------------------------------------------------------------------------------
   4.363 +
   4.364 +// ***** Disable template-unfriendly MS VC++ warnings
   4.365 +#if defined(OVR_CC_MSVC)
   4.366 +// Pragma to prevent long name warnings in in VC++
   4.367 +#pragma warning(disable : 4503)
   4.368 +#pragma warning(disable : 4786)
   4.369 +// In MSVC 7.1, warning about placement new POD default initializer
   4.370 +#pragma warning(disable : 4345)
   4.371 +#endif
   4.372 +
   4.373 +// Un-define new so that placement constructors work
   4.374 +#undef new
   4.375 +
   4.376 +
   4.377 +//-----------------------------------------------------------------------------------
   4.378 +// ***** Placement new overrides
   4.379 +
   4.380 +// Calls constructor on own memory created with "new(ptr) type"
   4.381 +#ifndef __PLACEMENT_NEW_INLINE
   4.382 +#define __PLACEMENT_NEW_INLINE
   4.383 +
   4.384 +#   if defined(OVR_CC_MWERKS) || defined(OVR_CC_BORLAND) || defined(OVR_CC_GNU)
   4.385 +#      include <new>
   4.386 +#   else
   4.387 +    // Useful on MSVC
   4.388 +    OVR_FORCE_INLINE void* operator new     (OVR::UPInt n, void *ptr) { OVR_UNUSED(n); return ptr; }
   4.389 +    OVR_FORCE_INLINE void  operator delete  (void *, void *)     { }
   4.390 +#   endif
   4.391 +
   4.392 +#endif // __PLACEMENT_NEW_INLINE
   4.393 +
   4.394 +
   4.395 +
   4.396 +//------------------------------------------------------------------------
   4.397 +// ***** Macros to redefine class new/delete operators
   4.398 +
   4.399 +// Types specifically declared to allow disambiguation of address in
   4.400 +// class member operator new.
   4.401 +
   4.402 +#define OVR_MEMORY_REDEFINE_NEW_IMPL(class_name, check_delete)                          \
   4.403 +    void*   operator new(UPInt sz)                                                      \
   4.404 +    { void *p = OVR_ALLOC_DEBUG(sz, __FILE__, __LINE__); return p; }                                              \
   4.405 +    void*   operator new(UPInt sz, const char* file, int line)                          \
   4.406 +    { void* p = OVR_ALLOC_DEBUG(sz, file, line); OVR_UNUSED2(file, line); return p; }   \
   4.407 +    void    operator delete(void *p)                                                    \
   4.408 +    { check_delete(class_name, p); OVR_FREE(p); }                                       \
   4.409 +    void    operator delete(void *p, const char*, int)                                  \
   4.410 +    { check_delete(class_name, p); OVR_FREE(p); }                          
   4.411 +
   4.412 +#define OVR_MEMORY_DEFINE_PLACEMENT_NEW                                                 \
   4.413 +    void*   operator new        (UPInt n, void *ptr)    { OVR_UNUSED(n); return ptr; }  \
   4.414 +    void    operator delete     (void *ptr, void *ptr2) { OVR_UNUSED2(ptr,ptr2); }
   4.415 +
   4.416 +
   4.417 +#define OVR_MEMORY_CHECK_DELETE_NONE(class_name, p)
   4.418 +
   4.419 +// Redefined all delete/new operators in a class without custom memory initialization
   4.420 +#define OVR_MEMORY_REDEFINE_NEW(class_name) \
   4.421 +    OVR_MEMORY_REDEFINE_NEW_IMPL(class_name, OVR_MEMORY_CHECK_DELETE_NONE)
   4.422 +
   4.423 +
   4.424 +namespace OVR {
   4.425 +
   4.426 +//-----------------------------------------------------------------------------------
   4.427 +// ***** Construct / Destruct
   4.428 +
   4.429 +// Construct/Destruct functions are useful when new is redefined, as they can
   4.430 +// be called instead of placement new constructors.
   4.431 +
   4.432 +
   4.433 +template <class T>
   4.434 +OVR_FORCE_INLINE T*  Construct(void *p)
   4.435 +{
   4.436 +    return ::new(p) T;
   4.437 +}
   4.438 +
   4.439 +template <class T>
   4.440 +OVR_FORCE_INLINE T*  Construct(void *p, const T& source)
   4.441 +{
   4.442 +    return ::new(p) T(source);
   4.443 +}
   4.444 +
   4.445 +// Same as above, but allows for a different type of constructor.
   4.446 +template <class T, class S>
   4.447 +OVR_FORCE_INLINE T*  ConstructAlt(void *p, const S& source)
   4.448 +{
   4.449 +    return ::new(p) T(source);
   4.450 +}
   4.451 +
   4.452 +template <class T, class S1, class S2>
   4.453 +OVR_FORCE_INLINE T*  ConstructAlt(void *p, const S1& src1, const S2& src2)
   4.454 +{
   4.455 +    return ::new(p) T(src1, src2);
   4.456 +}
   4.457 +
   4.458 +template <class T>
   4.459 +OVR_FORCE_INLINE void ConstructArray(void *p, UPInt count)
   4.460 +{
   4.461 +    UByte *pdata = (UByte*)p;
   4.462 +    for (UPInt i=0; i< count; ++i, pdata += sizeof(T))
   4.463 +    {
   4.464 +        Construct<T>(pdata);
   4.465 +    }
   4.466 +}
   4.467 +
   4.468 +template <class T>
   4.469 +OVR_FORCE_INLINE void ConstructArray(void *p, UPInt count, const T& source)
   4.470 +{
   4.471 +    UByte *pdata = (UByte*)p;
   4.472 +    for (UPInt i=0; i< count; ++i, pdata += sizeof(T))
   4.473 +    {
   4.474 +        Construct<T>(pdata, source);
   4.475 +    }
   4.476 +}
   4.477 +
   4.478 +template <class T>
   4.479 +OVR_FORCE_INLINE void Destruct(T *pobj)
   4.480 +{
   4.481 +    pobj->~T();
   4.482 +    OVR_UNUSED1(pobj); // Fix incorrect 'unused variable' MSVC warning.
   4.483 +}
   4.484 +
   4.485 +template <class T>
   4.486 +OVR_FORCE_INLINE void DestructArray(T *pobj, UPInt count)
   4.487 +{   
   4.488 +    for (UPInt i=0; i<count; ++i, ++pobj)
   4.489 +        pobj->~T();
   4.490 +}
   4.491 +
   4.492 +
   4.493 +//-----------------------------------------------------------------------------------
   4.494 +// ***** Allocator
   4.495 +
   4.496 +// Allocator defines a memory allocation interface that developers can override
   4.497 +// to to provide memory for OVR; an instance of this class is typically created on
   4.498 +// application startup and passed into System or OVR::System constructor.
   4.499 +// 
   4.500 +//
   4.501 +// Users implementing this interface must provide three functions: Alloc, Free,
   4.502 +// and Realloc. Implementations of these functions must honor the requested alignment.
   4.503 +// Although arbitrary alignment requests are possible, requested alignment will
   4.504 +// typically be small, such as 16 bytes or less.
   4.505 +
   4.506 +class Allocator
   4.507 +{
   4.508 +    friend class System;
   4.509 +public:
   4.510 +
   4.511 +    // *** Standard Alignment Alloc/Free
   4.512 +
   4.513 +    // Allocate memory of specified size with default alignment.
   4.514 +    // Alloc of size==0 will allocate a tiny block & return a valid pointer;
   4.515 +    // this makes it suitable for new operator.
   4.516 +    virtual void*   Alloc(UPInt size) = 0;
   4.517 +    // Same as Alloc, but provides an option of passing debug data.
   4.518 +    virtual void*   AllocDebug(UPInt size, const char* file, unsigned line)
   4.519 +    { OVR_UNUSED2(file, line); return Alloc(size); }
   4.520 +
   4.521 +    // Reallocate memory block to a new size, copying data if necessary. Returns the pointer to
   4.522 +    // new memory block, which may be the same as original pointer. Will return 0 if reallocation
   4.523 +    // failed, in which case previous memory is still valid.
   4.524 +    // Realloc to decrease size will never fail.
   4.525 +    // Realloc of pointer == 0 is equivalent to Alloc
   4.526 +    // Realloc to size == 0, shrinks to the minimal size, pointer remains valid and requires Free().
   4.527 +    virtual void*   Realloc(void* p, UPInt newSize) = 0;
   4.528 +
   4.529 +    // Frees memory allocated by Alloc/Realloc.
   4.530 +    // Free of null pointer is valid and will do nothing.
   4.531 +    virtual void    Free(void *p) = 0;
   4.532 +
   4.533 +
   4.534 +    // *** Standard Alignment Alloc/Free
   4.535 +
   4.536 +    // Allocate memory of specified alignment.
   4.537 +    // Memory allocated with AllocAligned MUST be freed with FreeAligned.
   4.538 +    // Default implementation will delegate to Alloc/Free after doing rounding.
   4.539 +    virtual void*   AllocAligned(UPInt size, UPInt align);    
   4.540 +    // Frees memory allocated with AllocAligned.
   4.541 +    virtual void    FreeAligned(void* p);
   4.542 +    
   4.543 +    // Returns the pointer to the current globally installed Allocator instance.
   4.544 +    // This pointer is used for most of the memory allocations.
   4.545 +    static Allocator* GetInstance() { return pInstance; }
   4.546 +
   4.547 +
   4.548 +protected:
   4.549 +    // onSystemShutdown is called on the allocator during System::Shutdown.
   4.550 +    // At this point, all allocations should've been freed.
   4.551 +    virtual void    onSystemShutdown() { }
   4.552 +
   4.553 +public:
   4.554 +    static  void    setInstance(Allocator* palloc)    
   4.555 +    {
   4.556 +        OVR_ASSERT((pInstance == 0) || (palloc == 0));
   4.557 +        pInstance = palloc;
   4.558 +    }
   4.559 +
   4.560 +private:
   4.561 +
   4.562 +    static Allocator* pInstance;
   4.563 +};
   4.564 +
   4.565 +
   4.566 +
   4.567 +//------------------------------------------------------------------------
   4.568 +// ***** Allocator_SingletonSupport
   4.569 +
   4.570 +// Allocator_SingletonSupport is a Allocator wrapper class that implements
   4.571 +// the InitSystemSingleton static function, used to create a global singleton
   4.572 +// used for the OVR::System default argument initialization.
   4.573 +//
   4.574 +// End users implementing custom Allocator interface don't need to make use of this base
   4.575 +// class; they can just create an instance of their own class on stack and pass it to System.
   4.576 +
   4.577 +template<class D>
   4.578 +class Allocator_SingletonSupport : public Allocator
   4.579 +{
   4.580 +    struct AllocContainer
   4.581 +    {        
   4.582 +        UPInt Data[(sizeof(D) + sizeof(UPInt)-1) / sizeof(UPInt)];
   4.583 +        bool  Initialized;
   4.584 +        AllocContainer() : Initialized(0) { }
   4.585 +    };
   4.586 +
   4.587 +    AllocContainer* pContainer;
   4.588 +
   4.589 +public:
   4.590 +    Allocator_SingletonSupport() : pContainer(0) { }
   4.591 +
   4.592 +    // Creates a singleton instance of this Allocator class used
   4.593 +    // on OVR_DEFAULT_ALLOCATOR during System initialization.
   4.594 +    static  D*  InitSystemSingleton()
   4.595 +    {
   4.596 +        static AllocContainer Container;
   4.597 +        OVR_ASSERT(Container.Initialized == false);
   4.598 +
   4.599 +        Allocator_SingletonSupport<D> *presult = Construct<D>((void*)Container.Data);
   4.600 +        presult->pContainer   = &Container;
   4.601 +        Container.Initialized = true;
   4.602 +        return (D*)presult;
   4.603 +    }
   4.604 +
   4.605 +protected:
   4.606 +    virtual void onSystemShutdown()
   4.607 +    {
   4.608 +        Allocator::onSystemShutdown();
   4.609 +        if (pContainer)
   4.610 +        {
   4.611 +            pContainer->Initialized = false;
   4.612 +            Destruct((D*)this);
   4.613 +            pContainer = 0;
   4.614 +        }
   4.615 +    }
   4.616 +};
   4.617 +
   4.618 +//------------------------------------------------------------------------
   4.619 +// ***** Default Allocator
   4.620 +
   4.621 +// This allocator is created and used if no other allocator is installed.
   4.622 +// Default allocator delegates to system malloc.
   4.623 +
   4.624 +class DefaultAllocator : public Allocator_SingletonSupport<DefaultAllocator>
   4.625 +{
   4.626 +public:
   4.627 +    virtual void*   Alloc(UPInt size);
   4.628 +    virtual void*   AllocDebug(UPInt size, const char* file, unsigned line);
   4.629 +    virtual void*   Realloc(void* p, UPInt newSize);
   4.630 +    virtual void    Free(void *p);
   4.631 +};
   4.632 +
   4.633 +
   4.634 +//------------------------------------------------------------------------
   4.635 +// ***** Memory Allocation Macros
   4.636 +
   4.637 +// These macros should be used for global allocation. In the future, these
   4.638 +// macros will allows allocation to be extended with debug file/line information
   4.639 +// if necessary.
   4.640 +
   4.641 +#define OVR_REALLOC(p,s)        OVR::Allocator::GetInstance()->Realloc((p),(s))
   4.642 +#define OVR_FREE(p)             OVR::Allocator::GetInstance()->Free((p))
   4.643 +#define OVR_ALLOC_ALIGNED(s,a)  OVR::Allocator::GetInstance()->AllocAligned((s),(a))
   4.644 +#define OVR_FREE_ALIGNED(p)     OVR::Allocator::GetInstance()->FreeAligned((p))
   4.645 +
   4.646 +#ifdef OVR_BUILD_DEBUG
   4.647 +#define OVR_ALLOC(s)            OVR::Allocator::GetInstance()->AllocDebug((s), __FILE__, __LINE__)
   4.648 +#define OVR_ALLOC_DEBUG(s,f,l)  OVR::Allocator::GetInstance()->AllocDebug((s), f, l)
   4.649 +#else
   4.650 +#define OVR_ALLOC(s)            OVR::Allocator::GetInstance()->Alloc((s))
   4.651 +#define OVR_ALLOC_DEBUG(s,f,l)  OVR::Allocator::GetInstance()->Alloc((s))
   4.652 +#endif
   4.653 +
   4.654 +//------------------------------------------------------------------------
   4.655 +
   4.656 +// Base class that overrides the new and delete operators.
   4.657 +// Deriving from this class, even as a multiple base, incurs no space overhead.
   4.658 +class NewOverrideBase
   4.659 +{
   4.660 +public:
   4.661 +
   4.662 +    // Redefine all new & delete operators.
   4.663 +    OVR_MEMORY_REDEFINE_NEW(NewOverrideBase)
   4.664 +};
   4.665 +
   4.666 +
   4.667 +} // OVR
   4.668 +
   4.669 +
   4.670 +// Redefine operator 'new' if necessary.
   4.671 +#if defined(OVR_DEFINE_NEW)
   4.672 +#define new OVR_DEFINE_NEW
   4.673 +#endif
   4.674 +
   4.675 +
   4.676 +#endif // OVR_Memory
     5.1 --- a/libovr/Src/Kernel/OVR_Array.h	Sat Sep 14 17:51:03 2013 +0300
     5.2 +++ b/libovr/Src/Kernel/OVR_Array.h	Sun Sep 15 04:10:05 2013 +0300
     5.3 @@ -1,1 +1,793 @@
     5.4 -/************************************************************************************
     5.5 
     5.6 PublicHeader:   OVR.h
     5.7 Filename    :   OVR_Array.h
     5.8 Content     :   Template implementation for Array
     5.9 Created     :   September 19, 2012
    5.10 Notes       : 
    5.11 
    5.12 Copyright   :   Copyright 2012 Oculus VR, Inc. All Rights reserved.
    5.13 
    5.14 Use of this software is subject to the terms of the Oculus license
    5.15 agreement provided at the time of installation or download, or which
    5.16 otherwise accompanies this software in either electronic or hard copy form.
    5.17 
    5.18 ************************************************************************************/
    5.19 
    5.20 #ifndef OVR_Array_h
    5.21 #define OVR_Array_h
    5.22 
    5.23 #include "OVR_ContainerAllocator.h"
    5.24 
    5.25 namespace OVR {
    5.26 
    5.27 //-----------------------------------------------------------------------------------
    5.28 // ***** ArrayDefaultPolicy
    5.29 //
    5.30 // Default resize behavior. No minimal capacity, Granularity=4, 
    5.31 // Shrinking as needed. ArrayConstPolicy actually is the same as 
    5.32 // ArrayDefaultPolicy, but parametrized with constants. 
    5.33 // This struct is used only in order to reduce the template "matroska".
    5.34 struct ArrayDefaultPolicy
    5.35 {
    5.36     ArrayDefaultPolicy() : Capacity(0) {}
    5.37     ArrayDefaultPolicy(const ArrayDefaultPolicy&) : Capacity(0) {}
    5.38 
    5.39     UPInt GetMinCapacity() const { return 0; }
    5.40     UPInt GetGranularity() const { return 4; }
    5.41     bool  NeverShrinking() const { return 0; }
    5.42 
    5.43     UPInt GetCapacity()    const      { return Capacity; }
    5.44     void  SetCapacity(UPInt capacity) { Capacity = capacity; }
    5.45 private:
    5.46     UPInt Capacity;
    5.47 };
    5.48 
    5.49 
    5.50 //-----------------------------------------------------------------------------------
    5.51 // ***** ArrayConstPolicy
    5.52 //
    5.53 // Statically parametrized resizing behavior:
    5.54 // MinCapacity, Granularity, and Shrinking flag.
    5.55 template<int MinCapacity=0, int Granularity=4, bool NeverShrink=false>
    5.56 struct ArrayConstPolicy
    5.57 {
    5.58     typedef ArrayConstPolicy<MinCapacity, Granularity, NeverShrink> SelfType;
    5.59 
    5.60     ArrayConstPolicy() : Capacity(0) {}
    5.61     ArrayConstPolicy(const SelfType&) : Capacity(0) {}
    5.62 
    5.63     UPInt GetMinCapacity() const { return MinCapacity; }
    5.64     UPInt GetGranularity() const { return Granularity; }
    5.65     bool  NeverShrinking() const { return NeverShrink; }
    5.66 
    5.67     UPInt GetCapacity()    const      { return Capacity; }
    5.68     void  SetCapacity(UPInt capacity) { Capacity = capacity; }
    5.69 private:
    5.70     UPInt Capacity;
    5.71 };
    5.72 
    5.73 //-----------------------------------------------------------------------------------
    5.74 // ***** ArrayDataBase
    5.75 //
    5.76 // Basic operations with array data: Reserve, Resize, Free, ArrayPolicy.
    5.77 // For internal use only: ArrayData,ArrayDataCC and others.
    5.78 template<class T, class Allocator, class SizePolicy>
    5.79 struct ArrayDataBase
    5.80 {
    5.81     typedef T                                           ValueType;
    5.82     typedef Allocator                                   AllocatorType;
    5.83     typedef SizePolicy                                  SizePolicyType;
    5.84     typedef ArrayDataBase<T, Allocator, SizePolicy>     SelfType;
    5.85 
    5.86     ArrayDataBase()
    5.87         : Data(0), Size(0), Policy() {}
    5.88 
    5.89     ArrayDataBase(const SizePolicy& p)
    5.90         : Data(0), Size(0), Policy(p) {}
    5.91 
    5.92     ~ArrayDataBase() 
    5.93     {
    5.94         Allocator::DestructArray(Data, Size);
    5.95         Allocator::Free(Data);
    5.96     }
    5.97 
    5.98     UPInt GetCapacity() const 
    5.99     { 
   5.100         return Policy.GetCapacity(); 
   5.101     }
   5.102 
   5.103     void ClearAndRelease()
   5.104     {
   5.105         Allocator::DestructArray(Data, Size);
   5.106         Allocator::Free(Data);
   5.107         Data = 0;
   5.108         Size = 0;
   5.109         Policy.SetCapacity(0);
   5.110     }
   5.111 
   5.112     void Reserve(UPInt newCapacity)
   5.113     {
   5.114         if (Policy.NeverShrinking() && newCapacity < GetCapacity())
   5.115             return;
   5.116 
   5.117         if (newCapacity < Policy.GetMinCapacity())
   5.118             newCapacity = Policy.GetMinCapacity();
   5.119 
   5.120         // Resize the buffer.
   5.121         if (newCapacity == 0)
   5.122         {
   5.123             if (Data)
   5.124             {
   5.125                 Allocator::Free(Data);
   5.126                 Data = 0;
   5.127             }
   5.128             Policy.SetCapacity(0);
   5.129         }
   5.130         else
   5.131         {
   5.132             UPInt gran = Policy.GetGranularity();
   5.133             newCapacity = (newCapacity + gran - 1) / gran * gran;
   5.134             if (Data)
   5.135             {
   5.136                 if (Allocator::IsMovable())
   5.137                 {
   5.138                     Data = (T*)Allocator::Realloc(Data, sizeof(T) * newCapacity);
   5.139                 }
   5.140                 else
   5.141                 {
   5.142                     T* newData = (T*)Allocator::Alloc(sizeof(T) * newCapacity);
   5.143                     UPInt i, s;
   5.144                     s = (Size < newCapacity) ? Size : newCapacity;
   5.145                     for (i = 0; i < s; ++i)
   5.146                     {
   5.147                         Allocator::Construct(&newData[i], Data[i]);
   5.148                         Allocator::Destruct(&Data[i]);
   5.149                     }
   5.150                     for (i = s; i < Size; ++i)
   5.151                     {
   5.152                         Allocator::Destruct(&Data[i]);
   5.153                     }
   5.154                     Allocator::Free(Data);
   5.155                     Data = newData;
   5.156                 }
   5.157             }
   5.158             else
   5.159             {
   5.160                 Data = (T*)Allocator::Alloc(sizeof(T) * newCapacity);
   5.161                 //memset(Buffer, 0, (sizeof(ValueType) * newSize)); // Do we need this?
   5.162             }
   5.163             Policy.SetCapacity(newCapacity);
   5.164             // OVR_ASSERT(Data); // need to throw (or something) on alloc failure!
   5.165         }
   5.166     }
   5.167 
   5.168     // This version of Resize DOES NOT construct the elements.
   5.169     // It's done to optimize PushBack, which uses a copy constructor 
   5.170     // instead of the default constructor and assignment
   5.171     void ResizeNoConstruct(UPInt newSize)
   5.172     {
   5.173         UPInt oldSize = Size;
   5.174 
   5.175         if (newSize < oldSize)
   5.176         {
   5.177             Allocator::DestructArray(Data + newSize, oldSize - newSize);
   5.178             if (newSize < (Policy.GetCapacity() >> 1))
   5.179             {
   5.180                 Reserve(newSize);
   5.181             }
   5.182         }
   5.183         else if(newSize >= Policy.GetCapacity())
   5.184         {
   5.185             Reserve(newSize + (newSize >> 2));
   5.186         }
   5.187         //! IMPORTANT to modify Size only after Reserve completes, because garbage collectable
   5.188         // array may use this array and may traverse it during Reserve (in the case, if 
   5.189         // collection occurs because of heap limit exceeded).
   5.190         Size = newSize;
   5.191     }
   5.192 
   5.193     ValueType*  Data;
   5.194     UPInt       Size;
   5.195     SizePolicy  Policy;
   5.196 };
   5.197 
   5.198 
   5.199 
   5.200 //-----------------------------------------------------------------------------------
   5.201 // ***** ArrayData
   5.202 //
   5.203 // General purpose array data.
   5.204 // For internal use only in Array, ArrayLH, ArrayPOD and so on.
   5.205 template<class T, class Allocator, class SizePolicy>
   5.206 struct ArrayData : ArrayDataBase<T, Allocator, SizePolicy>
   5.207 {
   5.208     typedef T ValueType;
   5.209     typedef Allocator                                   AllocatorType;
   5.210     typedef SizePolicy                                  SizePolicyType;
   5.211     typedef ArrayDataBase<T, Allocator, SizePolicy>     BaseType;
   5.212     typedef ArrayData    <T, Allocator, SizePolicy>     SelfType;
   5.213 
   5.214     ArrayData()
   5.215         : BaseType() { }
   5.216 
   5.217     ArrayData(int size)
   5.218         : BaseType() { Resize(size); }
   5.219 
   5.220     ArrayData(const SelfType& a)
   5.221         : BaseType(a.Policy) { Append(a.Data, a.Size); }
   5.222 
   5.223 
   5.224     void Resize(UPInt newSize)
   5.225     {
   5.226         UPInt oldSize = this->Size;
   5.227         BaseType::ResizeNoConstruct(newSize);
   5.228         if(newSize > oldSize)
   5.229             Allocator::ConstructArray(this->Data + oldSize, newSize - oldSize);
   5.230     }
   5.231 
   5.232     void PushBack(const ValueType& val)
   5.233     {
   5.234         BaseType::ResizeNoConstruct(this->Size + 1);
   5.235         Allocator::Construct(this->Data + this->Size - 1, val);
   5.236     }
   5.237 
   5.238     template<class S>
   5.239     void PushBackAlt(const S& val)
   5.240     {
   5.241         BaseType::ResizeNoConstruct(this->Size + 1);
   5.242         Allocator::ConstructAlt(this->Data + this->Size - 1, val);
   5.243     }
   5.244 
   5.245     // Append the given data to the array.
   5.246     void Append(const ValueType other[], UPInt count)
   5.247     {
   5.248         if (count)
   5.249         {
   5.250             UPInt oldSize = this->Size;
   5.251             BaseType::ResizeNoConstruct(this->Size + count);
   5.252             Allocator::ConstructArray(this->Data + oldSize, count, other);
   5.253         }
   5.254     }
   5.255 };
   5.256 
   5.257 
   5.258 
   5.259 //-----------------------------------------------------------------------------------
   5.260 // ***** ArrayDataCC
   5.261 //
   5.262 // A modification of ArrayData that always copy-constructs new elements
   5.263 // using a specified DefaultValue. For internal use only in ArrayCC.
   5.264 template<class T, class Allocator, class SizePolicy>
   5.265 struct ArrayDataCC : ArrayDataBase<T, Allocator, SizePolicy>
   5.266 {
   5.267     typedef T                                           ValueType;
   5.268     typedef Allocator                                   AllocatorType;
   5.269     typedef SizePolicy                                  SizePolicyType;
   5.270     typedef ArrayDataBase<T, Allocator, SizePolicy>     BaseType;
   5.271     typedef ArrayDataCC  <T, Allocator, SizePolicy>     SelfType;
   5.272 
   5.273     ArrayDataCC(const ValueType& defval)
   5.274         : BaseType(), DefaultValue(defval) { }
   5.275 
   5.276     ArrayDataCC(const ValueType& defval, int size)
   5.277         : BaseType(), DefaultValue(defval) { Resize(size); }
   5.278 
   5.279     ArrayDataCC(const SelfType& a)
   5.280         : BaseType(a.Policy), DefaultValue(a.DefaultValue) { Append(a.Data, a.Size); }
   5.281 
   5.282 
   5.283     void Resize(UPInt newSize)
   5.284     {
   5.285         UPInt oldSize = this->Size;
   5.286         BaseType::ResizeNoConstruct(newSize);
   5.287         if(newSize > oldSize)
   5.288             Allocator::ConstructArray(this->Data + oldSize, newSize - oldSize, DefaultValue);
   5.289     }
   5.290 
   5.291     void PushBack(const ValueType& val)
   5.292     {
   5.293         BaseType::ResizeNoConstruct(this->Size + 1);
   5.294         Allocator::Construct(this->Data + this->Size - 1, val);
   5.295     }
   5.296 
   5.297     template<class S>
   5.298     void PushBackAlt(const S& val)
   5.299     {
   5.300         BaseType::ResizeNoConstruct(this->Size + 1);
   5.301         Allocator::ConstructAlt(this->Data + this->Size - 1, val);
   5.302     }
   5.303 
   5.304     // Append the given data to the array.
   5.305     void Append(const ValueType other[], UPInt count)
   5.306     {
   5.307         if (count)
   5.308         {
   5.309             UPInt oldSize = this->Size;
   5.310             BaseType::ResizeNoConstruct(this->Size + count);
   5.311             Allocator::ConstructArray(this->Data + oldSize, count, other);
   5.312         }
   5.313     }
   5.314 
   5.315     ValueType   DefaultValue;
   5.316 };
   5.317 
   5.318 
   5.319 
   5.320 
   5.321 
   5.322 //-----------------------------------------------------------------------------------
   5.323 // ***** ArrayBase
   5.324 //
   5.325 // Resizable array. The behavior can be POD (suffix _POD) and 
   5.326 // Movable (no suffix) depending on the allocator policy.
   5.327 // In case of _POD the constructors and destructors are not called.
   5.328 // 
   5.329 // Arrays can't handle non-movable objects! Don't put anything in here 
   5.330 // that can't be moved around by bitwise copy. 
   5.331 // 
   5.332 // The addresses of elements are not persistent! Don't keep the address 
   5.333 // of an element; the array contents will move around as it gets resized.
   5.334 template<class ArrayData>
   5.335 class ArrayBase
   5.336 {
   5.337 public:
   5.338     typedef typename ArrayData::ValueType       ValueType;
   5.339     typedef typename ArrayData::AllocatorType   AllocatorType;
   5.340     typedef typename ArrayData::SizePolicyType  SizePolicyType;
   5.341     typedef ArrayBase<ArrayData>                SelfType;
   5.342 
   5.343 
   5.344 #undef new
   5.345     OVR_MEMORY_REDEFINE_NEW(ArrayBase)
   5.346 // Redefine operator 'new' if necessary.
   5.347 #if defined(OVR_DEFINE_NEW)
   5.348 #define new OVR_DEFINE_NEW
   5.349 #endif
   5.350 
   5.351 
   5.352     ArrayBase()
   5.353         : Data() {}
   5.354     ArrayBase(int size)
   5.355         : Data(size) {}
   5.356     ArrayBase(const SelfType& a)
   5.357         : Data(a.Data) {}
   5.358 
   5.359     ArrayBase(const ValueType& defval)
   5.360         : Data(defval) {}
   5.361     ArrayBase(const ValueType& defval, int size)
   5.362         : Data(defval, size) {}
   5.363   
   5.364     SizePolicyType* GetSizePolicy() const                  { return Data.Policy; }
   5.365     void            SetSizePolicy(const SizePolicyType& p) { Data.Policy = p; }
   5.366 
   5.367     bool    NeverShrinking()const       { return Data.Policy.NeverShrinking(); }
   5.368     UPInt   GetSize()       const       { return Data.Size;  }
   5.369     bool    IsEmpty()       const       { return Data.Size == 0; }
   5.370     UPInt   GetCapacity()   const       { return Data.GetCapacity(); }
   5.371     UPInt   GetNumBytes()   const       { return Data.GetCapacity() * sizeof(ValueType); }
   5.372 
   5.373     void    ClearAndRelease()           { Data.ClearAndRelease(); }
   5.374     void    Clear()                     { Data.Resize(0); }
   5.375     void    Resize(UPInt newSize)       { Data.Resize(newSize); }
   5.376 
   5.377     // Reserve can only increase the capacity
   5.378     void    Reserve(UPInt newCapacity)  
   5.379     { 
   5.380         if (newCapacity > Data.GetCapacity())
   5.381             Data.Reserve(newCapacity); 
   5.382     }
   5.383 
   5.384     // Basic access.
   5.385     ValueType& At(UPInt index)
   5.386     {
   5.387         OVR_ASSERT(index < Data.Size);
   5.388         return Data.Data[index]; 
   5.389     }
   5.390     const ValueType& At(UPInt index) const
   5.391     {
   5.392         OVR_ASSERT(index < Data.Size);
   5.393         return Data.Data[index]; 
   5.394     }
   5.395 
   5.396     ValueType ValueAt(UPInt index) const
   5.397     {
   5.398         OVR_ASSERT(index < Data.Size);
   5.399         return Data.Data[index]; 
   5.400     }
   5.401 
   5.402     // Basic access.
   5.403     ValueType& operator [] (UPInt index)
   5.404     {
   5.405         OVR_ASSERT(index < Data.Size);
   5.406         return Data.Data[index]; 
   5.407     }
   5.408     const ValueType& operator [] (UPInt index) const
   5.409     {
   5.410         OVR_ASSERT(index < Data.Size);
   5.411         return Data.Data[index]; 
   5.412     }
   5.413 
   5.414     // Raw pointer to the data. Use with caution!
   5.415     const ValueType* GetDataPtr() const { return Data.Data; }
   5.416           ValueType* GetDataPtr()       { return Data.Data; }
   5.417 
   5.418     // Insert the given element at the end of the array.
   5.419     void    PushBack(const ValueType& val)
   5.420     {
   5.421         // DO NOT pass elements of your own vector into
   5.422         // push_back()!  Since we're using references,
   5.423         // resize() may munge the element storage!
   5.424         // OVR_ASSERT(&val < &Buffer[0] || &val > &Buffer[BufferSize]);
   5.425         Data.PushBack(val);
   5.426     }
   5.427 
   5.428     template<class S>
   5.429     void PushBackAlt(const S& val)
   5.430     {
   5.431         Data.PushBackAlt(val);
   5.432     }
   5.433 
   5.434     // Remove the last element.
   5.435     void    PopBack(UPInt count = 1)
   5.436     {
   5.437         OVR_ASSERT(Data.Size >= count);
   5.438         Data.Resize(Data.Size - count);
   5.439     }
   5.440 
   5.441     ValueType& PushDefault()
   5.442     {
   5.443         Data.PushBack(ValueType());
   5.444         return Back();
   5.445     }
   5.446 
   5.447     ValueType Pop()
   5.448     {
   5.449         ValueType t = Back();
   5.450         PopBack();
   5.451         return t;
   5.452     }
   5.453 
   5.454 
   5.455     // Access the first element.
   5.456     ValueType&          Front()         { return At(0); }
   5.457     const ValueType&    Front() const   { return At(0); }
   5.458 
   5.459     // Access the last element.
   5.460     ValueType&          Back()          { return At(Data.Size - 1); }
   5.461     const ValueType&    Back() const    { return At(Data.Size - 1); }
   5.462 
   5.463     // Array copy.  Copies the contents of a into this array.
   5.464     const SelfType& operator = (const SelfType& a)   
   5.465     {
   5.466         Resize(a.GetSize());
   5.467         for (UPInt i = 0; i < Data.Size; i++) {
   5.468             *(Data.Data + i) = a[i];
   5.469         }
   5.470         return *this;
   5.471     }
   5.472 
   5.473     // Removing multiple elements from the array.
   5.474     void    RemoveMultipleAt(UPInt index, UPInt num)
   5.475     {
   5.476         OVR_ASSERT(index + num <= Data.Size);
   5.477         if (Data.Size == num)
   5.478         {
   5.479             Clear();
   5.480         }
   5.481         else
   5.482         {
   5.483             AllocatorType::DestructArray(Data.Data + index, num);
   5.484             AllocatorType::CopyArrayForward(
   5.485                 Data.Data + index, 
   5.486                 Data.Data + index + num,
   5.487                 Data.Size - num - index);
   5.488             Data.Size -= num;
   5.489         }
   5.490     }
   5.491 
   5.492     // Removing an element from the array is an expensive operation!
   5.493     // It compacts only after removing the last element.
   5.494     void    RemoveAt(UPInt index)
   5.495     {
   5.496         OVR_ASSERT(index < Data.Size);
   5.497         if (Data.Size == 1)
   5.498         {
   5.499             Clear();
   5.500         }
   5.501         else
   5.502         {
   5.503             AllocatorType::Destruct(Data.Data + index);
   5.504             AllocatorType::CopyArrayForward(
   5.505                 Data.Data + index, 
   5.506                 Data.Data + index + 1,
   5.507                 Data.Size - 1 - index);
   5.508             --Data.Size;
   5.509         }
   5.510     }
   5.511 
   5.512     // Insert the given object at the given index shifting all the elements up.
   5.513     void    InsertAt(UPInt index, const ValueType& val = ValueType())
   5.514     {
   5.515         OVR_ASSERT(index <= Data.Size);
   5.516 
   5.517         Data.Resize(Data.Size + 1);
   5.518         if (index < Data.Size - 1)
   5.519         {
   5.520             AllocatorType::CopyArrayBackward(
   5.521                 Data.Data + index + 1, 
   5.522                 Data.Data + index, 
   5.523                 Data.Size - 1 - index);
   5.524         }
   5.525         AllocatorType::Construct(Data.Data + index, val);
   5.526     }
   5.527 
   5.528     // Insert the given object at the given index shifting all the elements up.
   5.529     void    InsertMultipleAt(UPInt index, UPInt num, const ValueType& val = ValueType())
   5.530     {
   5.531         OVR_ASSERT(index <= Data.Size);
   5.532 
   5.533         Data.Resize(Data.Size + num);
   5.534         if (index < Data.Size - num)
   5.535         {
   5.536             AllocatorType::CopyArrayBackward(
   5.537                 Data.Data + index + num,
   5.538                 Data.Data + index,
   5.539                 Data.Size - num - index);
   5.540         }
   5.541         for (UPInt i = 0; i < num; ++i)
   5.542             AllocatorType::Construct(Data.Data + index + i, val);
   5.543     }
   5.544 
   5.545     // Append the given data to the array.
   5.546     void    Append(const SelfType& other)
   5.547     {
   5.548         Append(other.Data.Data, other.GetSize());
   5.549     }
   5.550 
   5.551     // Append the given data to the array.
   5.552     void    Append(const ValueType other[], UPInt count)
   5.553     {
   5.554         Data.Append(other, count);
   5.555     }
   5.556 
   5.557     class Iterator
   5.558     {
   5.559         SelfType*       pArray;
   5.560         SPInt           CurIndex;
   5.561 
   5.562     public:
   5.563         Iterator() : pArray(0), CurIndex(-1) {}
   5.564         Iterator(SelfType* parr, SPInt idx = 0) : pArray(parr), CurIndex(idx) {}
   5.565 
   5.566         bool operator==(const Iterator& it) const { return pArray == it.pArray && CurIndex == it.CurIndex; }
   5.567         bool operator!=(const Iterator& it) const { return pArray != it.pArray || CurIndex != it.CurIndex; }
   5.568 
   5.569         Iterator& operator++()
   5.570         {
   5.571             if (pArray)
   5.572             {
   5.573                 if (CurIndex < (SPInt)pArray->GetSize())
   5.574                     ++CurIndex;
   5.575             }
   5.576             return *this;
   5.577         }
   5.578         Iterator operator++(int)
   5.579         {
   5.580             Iterator it(*this);
   5.581             operator++();
   5.582             return it;
   5.583         }
   5.584         Iterator& operator--()
   5.585         {
   5.586             if (pArray)
   5.587             {
   5.588                 if (CurIndex >= 0)
   5.589                     --CurIndex;
   5.590             }
   5.591             return *this;
   5.592         }
   5.593         Iterator operator--(int)
   5.594         {
   5.595             Iterator it(*this);
   5.596             operator--();
   5.597             return it;
   5.598         }
   5.599         Iterator operator+(int delta) const
   5.600         {
   5.601             return Iterator(pArray, CurIndex + delta);
   5.602         }
   5.603         Iterator operator-(int delta) const
   5.604         {
   5.605             return Iterator(pArray, CurIndex - delta);
   5.606         }
   5.607         SPInt operator-(const Iterator& right) const
   5.608         {
   5.609             OVR_ASSERT(pArray == right.pArray);
   5.610             return CurIndex - right.CurIndex;
   5.611         }
   5.612         ValueType& operator*() const    { OVR_ASSERT(pArray); return  (*pArray)[CurIndex]; }
   5.613         ValueType* operator->() const   { OVR_ASSERT(pArray); return &(*pArray)[CurIndex]; }
   5.614         ValueType* GetPtr() const       { OVR_ASSERT(pArray); return &(*pArray)[CurIndex]; }
   5.615 
   5.616         bool IsFinished() const { return !pArray || CurIndex < 0 || CurIndex >= (int)pArray->GetSize(); }
   5.617 
   5.618         void Remove()
   5.619         {
   5.620             if (!IsFinished())
   5.621                 pArray->RemoveAt(CurIndex);
   5.622         }
   5.623 
   5.624         SPInt GetIndex() const { return CurIndex; }
   5.625     };
   5.626 
   5.627     Iterator Begin() { return Iterator(this); }
   5.628     Iterator End()   { return Iterator(this, (SPInt)GetSize()); }
   5.629     Iterator Last()  { return Iterator(this, (SPInt)GetSize() - 1); }
   5.630 
   5.631     class ConstIterator
   5.632     {
   5.633         const SelfType* pArray;
   5.634         SPInt           CurIndex;
   5.635 
   5.636     public:
   5.637         ConstIterator() : pArray(0), CurIndex(-1) {}
   5.638         ConstIterator(const SelfType* parr, SPInt idx = 0) : pArray(parr), CurIndex(idx) {}
   5.639 
   5.640         bool operator==(const ConstIterator& it) const { return pArray == it.pArray && CurIndex == it.CurIndex; }
   5.641         bool operator!=(const ConstIterator& it) const { return pArray != it.pArray || CurIndex != it.CurIndex; }
   5.642 
   5.643         ConstIterator& operator++()
   5.644         {
   5.645             if (pArray)
   5.646             {
   5.647                 if (CurIndex < (int)pArray->GetSize())
   5.648                     ++CurIndex;
   5.649             }
   5.650             return *this;
   5.651         }
   5.652         ConstIterator operator++(int)
   5.653         {
   5.654             ConstIterator it(*this);
   5.655             operator++();
   5.656             return it;
   5.657         }
   5.658         ConstIterator& operator--()
   5.659         {
   5.660             if (pArray)
   5.661             {
   5.662                 if (CurIndex >= 0)
   5.663                     --CurIndex;
   5.664             }
   5.665             return *this;
   5.666         }
   5.667         ConstIterator operator--(int)
   5.668         {
   5.669             ConstIterator it(*this);
   5.670             operator--();
   5.671             return it;
   5.672         }
   5.673         ConstIterator operator+(int delta) const
   5.674         {
   5.675             return ConstIterator(pArray, CurIndex + delta);
   5.676         }
   5.677         ConstIterator operator-(int delta) const
   5.678         {
   5.679             return ConstIterator(pArray, CurIndex - delta);
   5.680         }
   5.681         SPInt operator-(const ConstIterator& right) const
   5.682         {
   5.683             OVR_ASSERT(pArray == right.pArray);
   5.684             return CurIndex - right.CurIndex;
   5.685         }
   5.686         const ValueType& operator*() const  { OVR_ASSERT(pArray); return  (*pArray)[CurIndex]; }
   5.687         const ValueType* operator->() const { OVR_ASSERT(pArray); return &(*pArray)[CurIndex]; }
   5.688         const ValueType* GetPtr() const     { OVR_ASSERT(pArray); return &(*pArray)[CurIndex]; }
   5.689 
   5.690         bool IsFinished() const { return !pArray || CurIndex < 0 || CurIndex >= (int)pArray->GetSize(); }
   5.691 
   5.692         SPInt GetIndex()  const { return CurIndex; }
   5.693     };
   5.694     ConstIterator Begin() const { return ConstIterator(this); }
   5.695     ConstIterator End() const   { return ConstIterator(this, (SPInt)GetSize()); }
   5.696     ConstIterator Last() const  { return ConstIterator(this, (SPInt)GetSize() - 1); }
   5.697 
   5.698 protected:
   5.699     ArrayData   Data;
   5.700 };
   5.701 
   5.702 
   5.703 
   5.704 //-----------------------------------------------------------------------------------
   5.705 // ***** Array
   5.706 //
   5.707 // General purpose array for movable objects that require explicit 
   5.708 // construction/destruction.
   5.709 template<class T, class SizePolicy=ArrayDefaultPolicy>
   5.710 class Array : public ArrayBase<ArrayData<T, ContainerAllocator<T>, SizePolicy> >
   5.711 {
   5.712 public:
   5.713     typedef T                                                           ValueType;
   5.714     typedef ContainerAllocator<T>                                       AllocatorType;
   5.715     typedef SizePolicy                                                  SizePolicyType;
   5.716     typedef Array<T, SizePolicy>                                        SelfType;
   5.717     typedef ArrayBase<ArrayData<T, ContainerAllocator<T>, SizePolicy> > BaseType;
   5.718 
   5.719     Array() : BaseType() {}
   5.720     Array(int size) : BaseType(size) {}
   5.721     Array(const SizePolicyType& p) : BaseType() { SetSizePolicy(p); }
   5.722     Array(const SelfType& a) : BaseType(a) {}
   5.723     const SelfType& operator=(const SelfType& a) { BaseType::operator=(a); return *this; }
   5.724 };
   5.725 
   5.726 // ***** ArrayPOD
   5.727 //
   5.728 // General purpose array for movable objects that DOES NOT require  
   5.729 // construction/destruction. Constructors and destructors are not called! 
   5.730 // Global heap is in use.
   5.731 template<class T, class SizePolicy=ArrayDefaultPolicy>
   5.732 class ArrayPOD : public ArrayBase<ArrayData<T, ContainerAllocator_POD<T>, SizePolicy> >
   5.733 {
   5.734 public:
   5.735     typedef T                                                               ValueType;
   5.736     typedef ContainerAllocator_POD<T>                                       AllocatorType;
   5.737     typedef SizePolicy                                                      SizePolicyType;
   5.738     typedef ArrayPOD<T, SizePolicy>                                         SelfType;
   5.739     typedef ArrayBase<ArrayData<T, ContainerAllocator_POD<T>, SizePolicy> > BaseType;
   5.740 
   5.741     ArrayPOD() : BaseType() {}
   5.742     ArrayPOD(int size) : BaseType(size) {}
   5.743     ArrayPOD(const SizePolicyType& p) : BaseType() { SetSizePolicy(p); }
   5.744     ArrayPOD(const SelfType& a) : BaseType(a) {}
   5.745     const SelfType& operator=(const SelfType& a) { BaseType::operator=(a); return *this; }
   5.746 };
   5.747 
   5.748 
   5.749 // ***** ArrayCPP
   5.750 //
   5.751 // General purpose, fully C++ compliant array. Can be used with non-movable data.
   5.752 // Global heap is in use.
   5.753 template<class T, class SizePolicy=ArrayDefaultPolicy>
   5.754 class ArrayCPP : public ArrayBase<ArrayData<T, ContainerAllocator_CPP<T>, SizePolicy> >
   5.755 {
   5.756 public:
   5.757     typedef T                                                               ValueType;
   5.758     typedef ContainerAllocator_CPP<T>                                       AllocatorType;
   5.759     typedef SizePolicy                                                      SizePolicyType;
   5.760     typedef ArrayCPP<T, SizePolicy>                                         SelfType;
   5.761     typedef ArrayBase<ArrayData<T, ContainerAllocator_CPP<T>, SizePolicy> > BaseType;
   5.762 
   5.763     ArrayCPP() : BaseType() {}
   5.764     ArrayCPP(int size) : BaseType(size) {}
   5.765     ArrayCPP(const SizePolicyType& p) : BaseType() { SetSizePolicy(p); }
   5.766     ArrayCPP(const SelfType& a) : BaseType(a) {}
   5.767     const SelfType& operator=(const SelfType& a) { BaseType::operator=(a); return *this; }
   5.768 };
   5.769 
   5.770 
   5.771 // ***** ArrayCC
   5.772 //
   5.773 // A modification of the array that uses the given default value to
   5.774 // construct the elements. The constructors and destructors are 
   5.775 // properly called, the objects must be movable.
   5.776 
   5.777 template<class T, class SizePolicy=ArrayDefaultPolicy>
   5.778 class ArrayCC : public ArrayBase<ArrayDataCC<T, ContainerAllocator<T>, SizePolicy> >
   5.779 {
   5.780 public:
   5.781     typedef T                                                               ValueType;
   5.782     typedef ContainerAllocator<T>                                           AllocatorType;
   5.783     typedef SizePolicy                                                      SizePolicyType;
   5.784     typedef ArrayCC<T, SizePolicy>                                          SelfType;
   5.785     typedef ArrayBase<ArrayDataCC<T, ContainerAllocator<T>, SizePolicy> >   BaseType;
   5.786 
   5.787     ArrayCC(const ValueType& defval) : BaseType(defval) {}
   5.788     ArrayCC(const ValueType& defval, int size) : BaseType(defval, size) {}
   5.789     ArrayCC(const ValueType& defval, const SizePolicyType& p) : BaseType(defval) { SetSizePolicy(p); }
   5.790     ArrayCC(const SelfType& a) : BaseType(a) {}
   5.791     const SelfType& operator=(const SelfType& a) { BaseType::operator=(a); return *this; }
   5.792 };
   5.793 
   5.794 } // OVR
   5.795 
   5.796 #endif
   5.797 \ No newline at end of file
   5.798 +/************************************************************************************
   5.799 +
   5.800 +PublicHeader:   OVR.h
   5.801 +Filename    :   OVR_Array.h
   5.802 +Content     :   Template implementation for Array
   5.803 +Created     :   September 19, 2012
   5.804 +Notes       : 
   5.805 +
   5.806 +Copyright   :   Copyright 2012 Oculus VR, Inc. All Rights reserved.
   5.807 +
   5.808 +Use of this software is subject to the terms of the Oculus license
   5.809 +agreement provided at the time of installation or download, or which
   5.810 +otherwise accompanies this software in either electronic or hard copy form.
   5.811 +
   5.812 +************************************************************************************/
   5.813 +
   5.814 +#ifndef OVR_Array_h
   5.815 +#define OVR_Array_h
   5.816 +
   5.817 +#include "OVR_ContainerAllocator.h"
   5.818 +
   5.819 +namespace OVR {
   5.820 +
   5.821 +//-----------------------------------------------------------------------------------
   5.822 +// ***** ArrayDefaultPolicy
   5.823 +//
   5.824 +// Default resize behavior. No minimal capacity, Granularity=4, 
   5.825 +// Shrinking as needed. ArrayConstPolicy actually is the same as 
   5.826 +// ArrayDefaultPolicy, but parametrized with constants. 
   5.827 +// This struct is used only in order to reduce the template "matroska".
   5.828 +struct ArrayDefaultPolicy
   5.829 +{
   5.830 +    ArrayDefaultPolicy() : Capacity(0) {}
   5.831 +    ArrayDefaultPolicy(const ArrayDefaultPolicy&) : Capacity(0) {}
   5.832 +
   5.833 +    UPInt GetMinCapacity() const { return 0; }
   5.834 +    UPInt GetGranularity() const { return 4; }
   5.835 +    bool  NeverShrinking() const { return 0; }
   5.836 +
   5.837 +    UPInt GetCapacity()    const      { return Capacity; }
   5.838 +    void  SetCapacity(UPInt capacity) { Capacity = capacity; }
   5.839 +private:
   5.840 +    UPInt Capacity;
   5.841 +};
   5.842 +
   5.843 +
   5.844 +//-----------------------------------------------------------------------------------
   5.845 +// ***** ArrayConstPolicy
   5.846 +//
   5.847 +// Statically parametrized resizing behavior:
   5.848 +// MinCapacity, Granularity, and Shrinking flag.
   5.849 +template<int MinCapacity=0, int Granularity=4, bool NeverShrink=false>
   5.850 +struct ArrayConstPolicy
   5.851 +{
   5.852 +    typedef ArrayConstPolicy<MinCapacity, Granularity, NeverShrink> SelfType;
   5.853 +
   5.854 +    ArrayConstPolicy() : Capacity(0) {}
   5.855 +    ArrayConstPolicy(const SelfType&) : Capacity(0) {}
   5.856 +
   5.857 +    UPInt GetMinCapacity() const { return MinCapacity; }
   5.858 +    UPInt GetGranularity() const { return Granularity; }
   5.859 +    bool  NeverShrinking() const { return NeverShrink; }
   5.860 +
   5.861 +    UPInt GetCapacity()    const      { return Capacity; }
   5.862 +    void  SetCapacity(UPInt capacity) { Capacity = capacity; }
   5.863 +private:
   5.864 +    UPInt Capacity;
   5.865 +};
   5.866 +
   5.867 +//-----------------------------------------------------------------------------------
   5.868 +// ***** ArrayDataBase
   5.869 +//
   5.870 +// Basic operations with array data: Reserve, Resize, Free, ArrayPolicy.
   5.871 +// For internal use only: ArrayData,ArrayDataCC and others.
   5.872 +template<class T, class Allocator, class SizePolicy>
   5.873 +struct ArrayDataBase
   5.874 +{
   5.875 +    typedef T                                           ValueType;
   5.876 +    typedef Allocator                                   AllocatorType;
   5.877 +    typedef SizePolicy                                  SizePolicyType;
   5.878 +    typedef ArrayDataBase<T, Allocator, SizePolicy>     SelfType;
   5.879 +
   5.880 +    ArrayDataBase()
   5.881 +        : Data(0), Size(0), Policy() {}
   5.882 +
   5.883 +    ArrayDataBase(const SizePolicy& p)
   5.884 +        : Data(0), Size(0), Policy(p) {}
   5.885 +
   5.886 +    ~ArrayDataBase() 
   5.887 +    {
   5.888 +        Allocator::DestructArray(Data, Size);
   5.889 +        Allocator::Free(Data);
   5.890 +    }
   5.891 +
   5.892 +    UPInt GetCapacity() const 
   5.893 +    { 
   5.894 +        return Policy.GetCapacity(); 
   5.895 +    }
   5.896 +
   5.897 +    void ClearAndRelease()
   5.898 +    {
   5.899 +        Allocator::DestructArray(Data, Size);
   5.900 +        Allocator::Free(Data);
   5.901 +        Data = 0;
   5.902 +        Size = 0;
   5.903 +        Policy.SetCapacity(0);
   5.904 +    }
   5.905 +
   5.906 +    void Reserve(UPInt newCapacity)
   5.907 +    {
   5.908 +        if (Policy.NeverShrinking() && newCapacity < GetCapacity())
   5.909 +            return;
   5.910 +
   5.911 +        if (newCapacity < Policy.GetMinCapacity())
   5.912 +            newCapacity = Policy.GetMinCapacity();
   5.913 +
   5.914 +        // Resize the buffer.
   5.915 +        if (newCapacity == 0)
   5.916 +        {
   5.917 +            if (Data)
   5.918 +            {
   5.919 +                Allocator::Free(Data);
   5.920 +                Data = 0;
   5.921 +            }
   5.922 +            Policy.SetCapacity(0);
   5.923 +        }
   5.924 +        else
   5.925 +        {
   5.926 +            UPInt gran = Policy.GetGranularity();
   5.927 +            newCapacity = (newCapacity + gran - 1) / gran * gran;
   5.928 +            if (Data)
   5.929 +            {
   5.930 +                if (Allocator::IsMovable())
   5.931 +                {
   5.932 +                    Data = (T*)Allocator::Realloc(Data, sizeof(T) * newCapacity);
   5.933 +                }
   5.934 +                else
   5.935 +                {
   5.936 +                    T* newData = (T*)Allocator::Alloc(sizeof(T) * newCapacity);
   5.937 +                    UPInt i, s;
   5.938 +                    s = (Size < newCapacity) ? Size : newCapacity;
   5.939 +                    for (i = 0; i < s; ++i)
   5.940 +                    {
   5.941 +                        Allocator::Construct(&newData[i], Data[i]);
   5.942 +                        Allocator::Destruct(&Data[i]);
   5.943 +                    }
   5.944 +                    for (i = s; i < Size; ++i)
   5.945 +                    {
   5.946 +                        Allocator::Destruct(&Data[i]);
   5.947 +                    }
   5.948 +                    Allocator::Free(Data);
   5.949 +                    Data = newData;
   5.950 +                }
   5.951 +            }
   5.952 +            else
   5.953 +            {
   5.954 +                Data = (T*)Allocator::Alloc(sizeof(T) * newCapacity);
   5.955 +                //memset(Buffer, 0, (sizeof(ValueType) * newSize)); // Do we need this?
   5.956 +            }
   5.957 +            Policy.SetCapacity(newCapacity);
   5.958 +            // OVR_ASSERT(Data); // need to throw (or something) on alloc failure!
   5.959 +        }
   5.960 +    }
   5.961 +
   5.962 +    // This version of Resize DOES NOT construct the elements.
   5.963 +    // It's done to optimize PushBack, which uses a copy constructor 
   5.964 +    // instead of the default constructor and assignment
   5.965 +    void ResizeNoConstruct(UPInt newSize)
   5.966 +    {
   5.967 +        UPInt oldSize = Size;
   5.968 +
   5.969 +        if (newSize < oldSize)
   5.970 +        {
   5.971 +            Allocator::DestructArray(Data + newSize, oldSize - newSize);
   5.972 +            if (newSize < (Policy.GetCapacity() >> 1))
   5.973 +            {
   5.974 +                Reserve(newSize);
   5.975 +            }
   5.976 +        }
   5.977 +        else if(newSize >= Policy.GetCapacity())
   5.978 +        {
   5.979 +            Reserve(newSize + (newSize >> 2));
   5.980 +        }
   5.981 +        //! IMPORTANT to modify Size only after Reserve completes, because garbage collectable
   5.982 +        // array may use this array and may traverse it during Reserve (in the case, if 
   5.983 +        // collection occurs because of heap limit exceeded).
   5.984 +        Size = newSize;
   5.985 +    }
   5.986 +
   5.987 +    ValueType*  Data;
   5.988 +    UPInt       Size;
   5.989 +    SizePolicy  Policy;
   5.990 +};
   5.991 +
   5.992 +
   5.993 +
   5.994 +//-----------------------------------------------------------------------------------
   5.995 +// ***** ArrayData
   5.996 +//
   5.997 +// General purpose array data.
   5.998 +// For internal use only in Array, ArrayLH, ArrayPOD and so on.
   5.999 +template<class T, class Allocator, class SizePolicy>
  5.1000 +struct ArrayData : ArrayDataBase<T, Allocator, SizePolicy>
  5.1001 +{
  5.1002 +    typedef T ValueType;
  5.1003 +    typedef Allocator                                   AllocatorType;
  5.1004 +    typedef SizePolicy                                  SizePolicyType;
  5.1005 +    typedef ArrayDataBase<T, Allocator, SizePolicy>     BaseType;
  5.1006 +    typedef ArrayData    <T, Allocator, SizePolicy>     SelfType;
  5.1007 +
  5.1008 +    ArrayData()
  5.1009 +        : BaseType() { }
  5.1010 +
  5.1011 +    ArrayData(int size)
  5.1012 +        : BaseType() { Resize(size); }
  5.1013 +
  5.1014 +    ArrayData(const SelfType& a)
  5.1015 +        : BaseType(a.Policy) { Append(a.Data, a.Size); }
  5.1016 +
  5.1017 +
  5.1018 +    void Resize(UPInt newSize)
  5.1019 +    {
  5.1020 +        UPInt oldSize = this->Size;
  5.1021 +        BaseType::ResizeNoConstruct(newSize);
  5.1022 +        if(newSize > oldSize)
  5.1023 +            Allocator::ConstructArray(this->Data + oldSize, newSize - oldSize);
  5.1024 +    }
  5.1025 +
  5.1026 +    void PushBack(const ValueType& val)
  5.1027 +    {
  5.1028 +        BaseType::ResizeNoConstruct(this->Size + 1);
  5.1029 +        Allocator::Construct(this->Data + this->Size - 1, val);
  5.1030 +    }
  5.1031 +
  5.1032 +    template<class S>
  5.1033 +    void PushBackAlt(const S& val)
  5.1034 +    {
  5.1035 +        BaseType::ResizeNoConstruct(this->Size + 1);
  5.1036 +        Allocator::ConstructAlt(this->Data + this->Size - 1, val);
  5.1037 +    }
  5.1038 +
  5.1039 +    // Append the given data to the array.
  5.1040 +    void Append(const ValueType other[], UPInt count)
  5.1041 +    {
  5.1042 +        if (count)
  5.1043 +        {
  5.1044 +            UPInt oldSize = this->Size;
  5.1045 +            BaseType::ResizeNoConstruct(this->Size + count);
  5.1046 +            Allocator::ConstructArray(this->Data + oldSize, count, other);
  5.1047 +        }
  5.1048 +    }
  5.1049 +};
  5.1050 +
  5.1051 +
  5.1052 +
  5.1053 +//-----------------------------------------------------------------------------------
  5.1054 +// ***** ArrayDataCC
  5.1055 +//
  5.1056 +// A modification of ArrayData that always copy-constructs new elements
  5.1057 +// using a specified DefaultValue. For internal use only in ArrayCC.
  5.1058 +template<class T, class Allocator, class SizePolicy>
  5.1059 +struct ArrayDataCC : ArrayDataBase<T, Allocator, SizePolicy>
  5.1060 +{
  5.1061 +    typedef T                                           ValueType;
  5.1062 +    typedef Allocator                                   AllocatorType;
  5.1063 +    typedef SizePolicy                                  SizePolicyType;
  5.1064 +    typedef ArrayDataBase<T, Allocator, SizePolicy>     BaseType;
  5.1065 +    typedef ArrayDataCC  <T, Allocator, SizePolicy>     SelfType;
  5.1066 +
  5.1067 +    ArrayDataCC(const ValueType& defval)
  5.1068 +        : BaseType(), DefaultValue(defval) { }
  5.1069 +
  5.1070 +    ArrayDataCC(const ValueType& defval, int size)
  5.1071 +        : BaseType(), DefaultValue(defval) { Resize(size); }
  5.1072 +
  5.1073 +    ArrayDataCC(const SelfType& a)
  5.1074 +        : BaseType(a.Policy), DefaultValue(a.DefaultValue) { Append(a.Data, a.Size); }
  5.1075 +
  5.1076 +
  5.1077 +    void Resize(UPInt newSize)
  5.1078 +    {
  5.1079 +        UPInt oldSize = this->Size;
  5.1080 +        BaseType::ResizeNoConstruct(newSize);
  5.1081 +        if(newSize > oldSize)
  5.1082 +            Allocator::ConstructArray(this->Data + oldSize, newSize - oldSize, DefaultValue);
  5.1083 +    }
  5.1084 +
  5.1085 +    void PushBack(const ValueType& val)
  5.1086 +    {
  5.1087 +        BaseType::ResizeNoConstruct(this->Size + 1);
  5.1088 +        Allocator::Construct(this->Data + this->Size - 1, val);
  5.1089 +    }
  5.1090 +
  5.1091 +    template<class S>
  5.1092 +    void PushBackAlt(const S& val)
  5.1093 +    {
  5.1094 +        BaseType::ResizeNoConstruct(this->Size + 1);
  5.1095 +        Allocator::ConstructAlt(this->Data + this->Size - 1, val);
  5.1096 +    }
  5.1097 +
  5.1098 +    // Append the given data to the array.
  5.1099 +    void Append(const ValueType other[], UPInt count)
  5.1100 +    {
  5.1101 +        if (count)
  5.1102 +        {
  5.1103 +            UPInt oldSize = this->Size;
  5.1104 +            BaseType::ResizeNoConstruct(this->Size + count);
  5.1105 +            Allocator::ConstructArray(this->Data + oldSize, count, other);
  5.1106 +        }
  5.1107 +    }
  5.1108 +
  5.1109 +    ValueType   DefaultValue;
  5.1110 +};
  5.1111 +
  5.1112 +
  5.1113 +
  5.1114 +
  5.1115 +
  5.1116 +//-----------------------------------------------------------------------------------
  5.1117 +// ***** ArrayBase
  5.1118 +//
  5.1119 +// Resizable array. The behavior can be POD (suffix _POD) and 
  5.1120 +// Movable (no suffix) depending on the allocator policy.
  5.1121 +// In case of _POD the constructors and destructors are not called.
  5.1122 +// 
  5.1123 +// Arrays can't handle non-movable objects! Don't put anything in here 
  5.1124 +// that can't be moved around by bitwise copy. 
  5.1125 +// 
  5.1126 +// The addresses of elements are not persistent! Don't keep the address 
  5.1127 +// of an element; the array contents will move around as it gets resized.
  5.1128 +template<class ArrayData>
  5.1129 +class ArrayBase
  5.1130 +{
  5.1131 +public:
  5.1132 +    typedef typename ArrayData::ValueType       ValueType;
  5.1133 +    typedef typename ArrayData::AllocatorType   AllocatorType;
  5.1134 +    typedef typename ArrayData::SizePolicyType  SizePolicyType;
  5.1135 +    typedef ArrayBase<ArrayData>                SelfType;
  5.1136 +
  5.1137 +
  5.1138 +#undef new
  5.1139 +    OVR_MEMORY_REDEFINE_NEW(ArrayBase)
  5.1140 +// Redefine operator 'new' if necessary.
  5.1141 +#if defined(OVR_DEFINE_NEW)
  5.1142 +#define new OVR_DEFINE_NEW
  5.1143 +#endif
  5.1144 +
  5.1145 +
  5.1146 +    ArrayBase()
  5.1147 +        : Data() {}
  5.1148 +    ArrayBase(int size)
  5.1149 +        : Data(size) {}
  5.1150 +    ArrayBase(const SelfType& a)
  5.1151 +        : Data(a.Data) {}
  5.1152 +
  5.1153 +    ArrayBase(const ValueType& defval)
  5.1154 +        : Data(defval) {}
  5.1155 +    ArrayBase(const ValueType& defval, int size)
  5.1156 +        : Data(defval, size) {}
  5.1157 +  
  5.1158 +    SizePolicyType* GetSizePolicy() const                  { return Data.Policy; }
  5.1159 +    void            SetSizePolicy(const SizePolicyType& p) { Data.Policy = p; }
  5.1160 +
  5.1161 +    bool    NeverShrinking()const       { return Data.Policy.NeverShrinking(); }
  5.1162 +    UPInt   GetSize()       const       { return Data.Size;  }
  5.1163 +    bool    IsEmpty()       const       { return Data.Size == 0; }
  5.1164 +    UPInt   GetCapacity()   const       { return Data.GetCapacity(); }
  5.1165 +    UPInt   GetNumBytes()   const       { return Data.GetCapacity() * sizeof(ValueType); }
  5.1166 +
  5.1167 +    void    ClearAndRelease()           { Data.ClearAndRelease(); }
  5.1168 +    void    Clear()                     { Data.Resize(0); }
  5.1169 +    void    Resize(UPInt newSize)       { Data.Resize(newSize); }
  5.1170 +
  5.1171 +    // Reserve can only increase the capacity
  5.1172 +    void    Reserve(UPInt newCapacity)  
  5.1173 +    { 
  5.1174 +        if (newCapacity > Data.GetCapacity())
  5.1175 +            Data.Reserve(newCapacity); 
  5.1176 +    }
  5.1177 +
  5.1178 +    // Basic access.
  5.1179 +    ValueType& At(UPInt index)
  5.1180 +    {
  5.1181 +        OVR_ASSERT(index < Data.Size);
  5.1182 +        return Data.Data[index]; 
  5.1183 +    }
  5.1184 +    const ValueType& At(UPInt index) const
  5.1185 +    {
  5.1186 +        OVR_ASSERT(index < Data.Size);
  5.1187 +        return Data.Data[index]; 
  5.1188 +    }
  5.1189 +
  5.1190 +    ValueType ValueAt(UPInt index) const
  5.1191 +    {
  5.1192 +        OVR_ASSERT(index < Data.Size);
  5.1193 +        return Data.Data[index]; 
  5.1194 +    }
  5.1195 +
  5.1196 +    // Basic access.
  5.1197 +    ValueType& operator [] (UPInt index)
  5.1198 +    {
  5.1199 +        OVR_ASSERT(index < Data.Size);
  5.1200 +        return Data.Data[index]; 
  5.1201 +    }
  5.1202 +    const ValueType& operator [] (UPInt index) const
  5.1203 +    {
  5.1204 +        OVR_ASSERT(index < Data.Size);
  5.1205 +        return Data.Data[index]; 
  5.1206 +    }
  5.1207 +
  5.1208 +    // Raw pointer to the data. Use with caution!
  5.1209 +    const ValueType* GetDataPtr() const { return Data.Data; }
  5.1210 +          ValueType* GetDataPtr()       { return Data.Data; }
  5.1211 +
  5.1212 +    // Insert the given element at the end of the array.
  5.1213 +    void    PushBack(const ValueType& val)
  5.1214 +    {
  5.1215 +        // DO NOT pass elements of your own vector into
  5.1216 +        // push_back()!  Since we're using references,
  5.1217 +        // resize() may munge the element storage!
  5.1218 +        // OVR_ASSERT(&val < &Buffer[0] || &val > &Buffer[BufferSize]);
  5.1219 +        Data.PushBack(val);
  5.1220 +    }
  5.1221 +
  5.1222 +    template<class S>
  5.1223 +    void PushBackAlt(const S& val)
  5.1224 +    {
  5.1225 +        Data.PushBackAlt(val);
  5.1226 +    }
  5.1227 +
  5.1228 +    // Remove the last element.
  5.1229 +    void    PopBack(UPInt count = 1)
  5.1230 +    {
  5.1231 +        OVR_ASSERT(Data.Size >= count);
  5.1232 +        Data.Resize(Data.Size - count);
  5.1233 +    }
  5.1234 +
  5.1235 +    ValueType& PushDefault()
  5.1236 +    {
  5.1237 +        Data.PushBack(ValueType());
  5.1238 +        return Back();
  5.1239 +    }
  5.1240 +
  5.1241 +    ValueType Pop()
  5.1242 +    {
  5.1243 +        ValueType t = Back();
  5.1244 +        PopBack();
  5.1245 +        return t;
  5.1246 +    }
  5.1247 +
  5.1248 +
  5.1249 +    // Access the first element.
  5.1250 +    ValueType&          Front()         { return At(0); }
  5.1251 +    const ValueType&    Front() const   { return At(0); }
  5.1252 +
  5.1253 +    // Access the last element.
  5.1254 +    ValueType&          Back()          { return At(Data.Size - 1); }
  5.1255 +    const ValueType&    Back() const    { return At(Data.Size - 1); }
  5.1256 +
  5.1257 +    // Array copy.  Copies the contents of a into this array.
  5.1258 +    const SelfType& operator = (const SelfType& a)   
  5.1259 +    {
  5.1260 +        Resize(a.GetSize());
  5.1261 +        for (UPInt i = 0; i < Data.Size; i++) {
  5.1262 +            *(Data.Data + i) = a[i];
  5.1263 +        }
  5.1264 +        return *this;
  5.1265 +    }
  5.1266 +
  5.1267 +    // Removing multiple elements from the array.
  5.1268 +    void    RemoveMultipleAt(UPInt index, UPInt num)
  5.1269 +    {
  5.1270 +        OVR_ASSERT(index + num <= Data.Size);
  5.1271 +        if (Data.Size == num)
  5.1272 +        {
  5.1273 +            Clear();
  5.1274 +        }
  5.1275 +        else
  5.1276 +        {
  5.1277 +            AllocatorType::DestructArray(Data.Data + index, num);
  5.1278 +            AllocatorType::CopyArrayForward(
  5.1279 +                Data.Data + index, 
  5.1280 +                Data.Data + index + num,
  5.1281 +                Data.Size - num - index);
  5.1282 +            Data.Size -= num;
  5.1283 +        }
  5.1284 +    }
  5.1285 +
  5.1286 +    // Removing an element from the array is an expensive operation!
  5.1287 +    // It compacts only after removing the last element.
  5.1288 +    void    RemoveAt(UPInt index)
  5.1289 +    {
  5.1290 +        OVR_ASSERT(index < Data.Size);
  5.1291 +        if (Data.Size == 1)
  5.1292 +        {
  5.1293 +            Clear();
  5.1294 +        }
  5.1295 +        else
  5.1296 +        {
  5.1297 +            AllocatorType::Destruct(Data.Data + index);
  5.1298 +            AllocatorType::CopyArrayForward(
  5.1299 +                Data.Data + index, 
  5.1300 +                Data.Data + index + 1,
  5.1301 +                Data.Size - 1 - index);
  5.1302 +            --Data.Size;
  5.1303 +        }
  5.1304 +    }
  5.1305 +
  5.1306 +    // Insert the given object at the given index shifting all the elements up.
  5.1307 +    void    InsertAt(UPInt index, const ValueType& val = ValueType())
  5.1308 +    {
  5.1309 +        OVR_ASSERT(index <= Data.Size);
  5.1310 +
  5.1311 +        Data.Resize(Data.Size + 1);
  5.1312 +        if (index < Data.Size - 1)
  5.1313 +        {
  5.1314 +            AllocatorType::CopyArrayBackward(
  5.1315 +                Data.Data + index + 1, 
  5.1316 +                Data.Data + index, 
  5.1317 +                Data.Size - 1 - index);
  5.1318 +        }
  5.1319 +        AllocatorType::Construct(Data.Data + index, val);
  5.1320 +    }
  5.1321 +
  5.1322 +    // Insert the given object at the given index shifting all the elements up.
  5.1323 +    void    InsertMultipleAt(UPInt index, UPInt num, const ValueType& val = ValueType())
  5.1324 +    {
  5.1325 +        OVR_ASSERT(index <= Data.Size);
  5.1326 +
  5.1327 +        Data.Resize(Data.Size + num);
  5.1328 +        if (index < Data.Size - num)
  5.1329 +        {
  5.1330 +            AllocatorType::CopyArrayBackward(
  5.1331 +                Data.Data + index + num,
  5.1332 +                Data.Data + index,
  5.1333 +                Data.Size - num - index);
  5.1334 +        }
  5.1335 +        for (UPInt i = 0; i < num; ++i)
  5.1336 +            AllocatorType::Construct(Data.Data + index + i, val);
  5.1337 +    }
  5.1338 +
  5.1339 +    // Append the given data to the array.
  5.1340 +    void    Append(const SelfType& other)
  5.1341 +    {
  5.1342 +        Append(other.Data.Data, other.GetSize());
  5.1343 +    }
  5.1344 +
  5.1345 +    // Append the given data to the array.
  5.1346 +    void    Append(const ValueType other[], UPInt count)
  5.1347 +    {
  5.1348 +        Data.Append(other, count);
  5.1349 +    }
  5.1350 +
  5.1351 +    class Iterator
  5.1352 +    {
  5.1353 +        SelfType*       pArray;
  5.1354 +        SPInt           CurIndex;
  5.1355 +
  5.1356 +    public:
  5.1357 +        Iterator() : pArray(0), CurIndex(-1) {}
  5.1358 +        Iterator(SelfType* parr, SPInt idx = 0) : pArray(parr), CurIndex(idx) {}
  5.1359 +
  5.1360 +        bool operator==(const Iterator& it) const { return pArray == it.pArray && CurIndex == it.CurIndex; }
  5.1361 +        bool operator!=(const Iterator& it) const { return pArray != it.pArray || CurIndex != it.CurIndex; }
  5.1362 +
  5.1363 +        Iterator& operator++()
  5.1364 +        {
  5.1365 +            if (pArray)
  5.1366 +            {
  5.1367 +                if (CurIndex < (SPInt)pArray->GetSize())
  5.1368 +                    ++CurIndex;
  5.1369 +            }
  5.1370 +            return *this;
  5.1371 +        }
  5.1372 +        Iterator operator++(int)
  5.1373 +        {
  5.1374 +            Iterator it(*this);
  5.1375 +            operator++();
  5.1376 +            return it;
  5.1377 +        }
  5.1378 +        Iterator& operator--()
  5.1379 +        {
  5.1380 +            if (pArray)
  5.1381 +            {
  5.1382 +                if (CurIndex >= 0)
  5.1383 +                    --CurIndex;
  5.1384 +            }
  5.1385 +            return *this;
  5.1386 +        }
  5.1387 +        Iterator operator--(int)
  5.1388 +        {
  5.1389 +            Iterator it(*this);
  5.1390 +            operator--();
  5.1391 +            return it;
  5.1392 +        }
  5.1393 +        Iterator operator+(int delta) const
  5.1394 +        {
  5.1395 +            return Iterator(pArray, CurIndex + delta);
  5.1396 +        }
  5.1397 +        Iterator operator-(int delta) const
  5.1398 +        {
  5.1399 +            return Iterator(pArray, CurIndex - delta);
  5.1400 +        }
  5.1401 +        SPInt operator-(const Iterator& right) const
  5.1402 +        {
  5.1403 +            OVR_ASSERT(pArray == right.pArray);
  5.1404 +            return CurIndex - right.CurIndex;
  5.1405 +        }
  5.1406 +        ValueType& operator*() const    { OVR_ASSERT(pArray); return  (*pArray)[CurIndex]; }
  5.1407 +        ValueType* operator->() const   { OVR_ASSERT(pArray); return &(*pArray)[CurIndex]; }
  5.1408 +        ValueType* GetPtr() const       { OVR_ASSERT(pArray); return &(*pArray)[CurIndex]; }
  5.1409 +
  5.1410 +        bool IsFinished() const { return !pArray || CurIndex < 0 || CurIndex >= (int)pArray->GetSize(); }
  5.1411 +
  5.1412 +        void Remove()
  5.1413 +        {
  5.1414 +            if (!IsFinished())
  5.1415 +                pArray->RemoveAt(CurIndex);
  5.1416 +        }
  5.1417 +
  5.1418 +        SPInt GetIndex() const { return CurIndex; }
  5.1419 +    };
  5.1420 +
  5.1421 +    Iterator Begin() { return Iterator(this); }
  5.1422 +    Iterator End()   { return Iterator(this, (SPInt)GetSize()); }
  5.1423 +    Iterator Last()  { return Iterator(this, (SPInt)GetSize() - 1); }
  5.1424 +
  5.1425 +    class ConstIterator
  5.1426 +    {
  5.1427 +        const SelfType* pArray;
  5.1428 +        SPInt           CurIndex;
  5.1429 +
  5.1430 +    public:
  5.1431 +        ConstIterator() : pArray(0), CurIndex(-1) {}
  5.1432 +        ConstIterator(const SelfType* parr, SPInt idx = 0) : pArray(parr), CurIndex(idx) {}
  5.1433 +
  5.1434 +        bool operator==(const ConstIterator& it) const { return pArray == it.pArray && CurIndex == it.CurIndex; }
  5.1435 +        bool operator!=(const ConstIterator& it) const { return pArray != it.pArray || CurIndex != it.CurIndex; }
  5.1436 +
  5.1437 +        ConstIterator& operator++()
  5.1438 +        {
  5.1439 +            if (pArray)
  5.1440 +            {
  5.1441 +                if (CurIndex < (int)pArray->GetSize())
  5.1442 +                    ++CurIndex;
  5.1443 +            }
  5.1444 +            return *this;
  5.1445 +        }
  5.1446 +        ConstIterator operator++(int)
  5.1447 +        {
  5.1448 +            ConstIterator it(*this);
  5.1449 +            operator++();
  5.1450 +            return it;
  5.1451 +        }
  5.1452 +        ConstIterator& operator--()
  5.1453 +        {
  5.1454 +            if (pArray)
  5.1455 +            {
  5.1456 +                if (CurIndex >= 0)
  5.1457 +                    --CurIndex;
  5.1458 +            }
  5.1459 +            return *this;
  5.1460 +        }
  5.1461 +        ConstIterator operator--(int)
  5.1462 +        {
  5.1463 +            ConstIterator it(*this);
  5.1464 +            operator--();
  5.1465 +            return it;
  5.1466 +        }
  5.1467 +        ConstIterator operator+(int delta) const
  5.1468 +        {
  5.1469 +            return ConstIterator(pArray, CurIndex + delta);
  5.1470 +        }
  5.1471 +        ConstIterator operator-(int delta) const
  5.1472 +        {
  5.1473 +            return ConstIterator(pArray, CurIndex - delta);
  5.1474 +        }
  5.1475 +        SPInt operator-(const ConstIterator& right) const
  5.1476 +        {
  5.1477 +            OVR_ASSERT(pArray == right.pArray);
  5.1478 +            return CurIndex - right.CurIndex;
  5.1479 +        }
  5.1480 +        const ValueType& operator*() const  { OVR_ASSERT(pArray); return  (*pArray)[CurIndex]; }
  5.1481 +        const ValueType* operator->() const { OVR_ASSERT(pArray); return &(*pArray)[CurIndex]; }
  5.1482 +        const ValueType* GetPtr() const     { OVR_ASSERT(pArray); return &(*pArray)[CurIndex]; }
  5.1483 +
  5.1484 +        bool IsFinished() const { return !pArray || CurIndex < 0 || CurIndex >= (int)pArray->GetSize(); }
  5.1485 +
  5.1486 +        SPInt GetIndex()  const { return CurIndex; }
  5.1487 +    };
  5.1488 +    ConstIterator Begin() const { return ConstIterator(this); }
  5.1489 +    ConstIterator End() const   { return ConstIterator(this, (SPInt)GetSize()); }
  5.1490 +    ConstIterator Last() const  { return ConstIterator(this, (SPInt)GetSize() - 1); }
  5.1491 +
  5.1492 +protected:
  5.1493 +    ArrayData   Data;
  5.1494 +};
  5.1495 +
  5.1496 +
  5.1497 +
  5.1498 +//-----------------------------------------------------------------------------------
  5.1499 +// ***** Array
  5.1500 +//
  5.1501 +// General purpose array for movable objects that require explicit 
  5.1502 +// construction/destruction.
  5.1503 +template<class T, class SizePolicy=ArrayDefaultPolicy>
  5.1504 +class Array : public ArrayBase<ArrayData<T, ContainerAllocator<T>, SizePolicy> >
  5.1505 +{
  5.1506 +public:
  5.1507 +    typedef T                                                           ValueType;
  5.1508 +    typedef ContainerAllocator<T>                                       AllocatorType;
  5.1509 +    typedef SizePolicy                                                  SizePolicyType;
  5.1510 +    typedef Array<T, SizePolicy>                                        SelfType;
  5.1511 +    typedef ArrayBase<ArrayData<T, ContainerAllocator<T>, SizePolicy> > BaseType;
  5.1512 +
  5.1513 +    Array() : BaseType() {}
  5.1514 +    Array(int size) : BaseType(size) {}
  5.1515 +    Array(const SizePolicyType& p) : BaseType() { SetSizePolicy(p); }
  5.1516 +    Array(const SelfType& a) : BaseType(a) {}
  5.1517 +    const SelfType& operator=(const SelfType& a) { BaseType::operator=(a); return *this; }
  5.1518 +};
  5.1519 +
  5.1520 +// ***** ArrayPOD
  5.1521 +//
  5.1522 +// General purpose array for movable objects that DOES NOT require  
  5.1523 +// construction/destruction. Constructors and destructors are not called! 
  5.1524 +// Global heap is in use.
  5.1525 +template<class T, class SizePolicy=ArrayDefaultPolicy>
  5.1526 +class ArrayPOD : public ArrayBase<ArrayData<T, ContainerAllocator_POD<T>, SizePolicy> >
  5.1527 +{
  5.1528 +public:
  5.1529 +    typedef T                                                               ValueType;
  5.1530 +    typedef ContainerAllocator_POD<T>                                       AllocatorType;
  5.1531 +    typedef SizePolicy                                                      SizePolicyType;
  5.1532 +    typedef ArrayPOD<T, SizePolicy>                                         SelfType;
  5.1533 +    typedef ArrayBase<ArrayData<T, ContainerAllocator_POD<T>, SizePolicy> > BaseType;
  5.1534 +
  5.1535 +    ArrayPOD() : BaseType() {}
  5.1536 +    ArrayPOD(int size) : BaseType(size) {}
  5.1537 +    ArrayPOD(const SizePolicyType& p) : BaseType() { SetSizePolicy(p); }
  5.1538 +    ArrayPOD(const SelfType& a) : BaseType(a) {}
  5.1539 +    const SelfType& operator=(const SelfType& a) { BaseType::operator=(a); return *this; }
  5.1540 +};
  5.1541 +
  5.1542 +
  5.1543 +// ***** ArrayCPP
  5.1544 +//
  5.1545 +// General purpose, fully C++ compliant array. Can be used with non-movable data.
  5.1546 +// Global heap is in use.
  5.1547 +template<class T, class SizePolicy=ArrayDefaultPolicy>
  5.1548 +class ArrayCPP : public ArrayBase<ArrayData<T, ContainerAllocator_CPP<T>, SizePolicy> >
  5.1549 +{
  5.1550 +public:
  5.1551 +    typedef T                                                               ValueType;
  5.1552 +    typedef ContainerAllocator_CPP<T>                                       AllocatorType;
  5.1553 +    typedef SizePolicy                                                      SizePolicyType;
  5.1554 +    typedef ArrayCPP<T, SizePolicy>                                         SelfType;
  5.1555 +    typedef ArrayBase<ArrayData<T, ContainerAllocator_CPP<T>, SizePolicy> > BaseType;
  5.1556 +
  5.1557 +    ArrayCPP() : BaseType() {}
  5.1558 +    ArrayCPP(int size) : BaseType(size) {}
  5.1559 +    ArrayCPP(const SizePolicyType& p) : BaseType() { SetSizePolicy(p); }
  5.1560 +    ArrayCPP(const SelfType& a) : BaseType(a) {}
  5.1561 +    const SelfType& operator=(const SelfType& a) { BaseType::operator=(a); return *this; }
  5.1562 +};
  5.1563 +
  5.1564 +
  5.1565 +// ***** ArrayCC
  5.1566 +//
  5.1567 +// A modification of the array that uses the given default value to
  5.1568 +// construct the elements. The constructors and destructors are 
  5.1569 +// properly called, the objects must be movable.
  5.1570 +
  5.1571 +template<class T, class SizePolicy=ArrayDefaultPolicy>
  5.1572 +class ArrayCC : public ArrayBase<ArrayDataCC<T, ContainerAllocator<T>, SizePolicy> >
  5.1573 +{
  5.1574 +public:
  5.1575 +    typedef T                                                               ValueType;
  5.1576 +    typedef ContainerAllocator<T>                                           AllocatorType;
  5.1577 +    typedef SizePolicy                                                      SizePolicyType;
  5.1578 +    typedef ArrayCC<T, SizePolicy>                                          SelfType;
  5.1579 +    typedef ArrayBase<ArrayDataCC<T, ContainerAllocator<T>, SizePolicy> >   BaseType;
  5.1580 +
  5.1581 +    ArrayCC(const ValueType& defval) : BaseType(defval) {}
  5.1582 +    ArrayCC(const ValueType& defval, int size) : BaseType(defval, size) {}
  5.1583 +    ArrayCC(const ValueType& defval, const SizePolicyType& p) : BaseType(defval) { SetSizePolicy(p); }
  5.1584 +    ArrayCC(const SelfType& a) : BaseType(a) {}
  5.1585 +    const SelfType& operator=(const SelfType& a) { BaseType::operator=(a); return *this; }
  5.1586 +};
  5.1587 +
  5.1588 +} // OVR
  5.1589 +
  5.1590 +#endif
     6.1 --- a/libovr/Src/Kernel/OVR_Atomic.cpp	Sat Sep 14 17:51:03 2013 +0300
     6.2 +++ b/libovr/Src/Kernel/OVR_Atomic.cpp	Sun Sep 15 04:10:05 2013 +0300
     6.3 @@ -1,1 +1,82 @@
     6.4 -/************************************************************************************
     6.5 
     6.6 Filename    :   OVR_Atomic.cpp
     6.7 Content     :   Contains atomic operations and inline fastest locking
     6.8                 functionality. Will contain #ifdefs for OS efficiency.
     6.9                 Have non-thread-safe implementation if not available.
    6.10 Created     :   September 19, 2012
    6.11 Notes       : 
    6.12 
    6.13 Copyright   :   Copyright 2012 Oculus VR, Inc. All Rights reserved.
    6.14 
    6.15 Use of this software is subject to the terms of the Oculus license
    6.16 agreement provided at the time of installation or download, or which
    6.17 otherwise accompanies this software in either electronic or hard copy form.
    6.18 
    6.19 ************************************************************************************/
    6.20 
    6.21 #include "OVR_Atomic.h"
    6.22 
    6.23 #ifdef OVR_ENABLE_THREADS
    6.24 
    6.25 // Include Windows 8-Metro compatible Synchronization API
    6.26 #if defined(OVR_OS_WIN32) && defined(NTDDI_WIN8) && (NTDDI_VERSION >= NTDDI_WIN8)
    6.27 #include <synchapi.h>
    6.28 #endif
    6.29 
    6.30 
    6.31 namespace OVR {
    6.32 
    6.33 // ***** Windows Lock implementation
    6.34 
    6.35 #if defined(OVR_OS_WIN32)
    6.36 
    6.37 // ***** Standard Win32 Lock implementation
    6.38 
    6.39 // Constructors
    6.40 Lock::Lock(unsigned spinCount)
    6.41 {
    6.42 #if defined(NTDDI_WIN8) && (NTDDI_VERSION >= NTDDI_WIN8)
    6.43    // On Windows 8 we use InitializeCriticalSectionEx due to Metro-Compatibility
    6.44    InitializeCriticalSectionEx(&cs, spinCount,
    6.45                                OVR_DEBUG_SELECT(NULL, CRITICAL_SECTION_NO_DEBUG_INFO));
    6.46 #else
    6.47     // Spin count init critical section function prototype for Window NT
    6.48     typedef BOOL (WINAPI *Function_InitializeCriticalSectionAndSpinCount) 
    6.49                  (LPCRITICAL_SECTION lpCriticalSection, DWORD dwSpinCount);
    6.50 
    6.51 
    6.52     // Try to load function dynamically so that we don't require NT
    6.53     // On Windows NT we will use InitializeCriticalSectionAndSpinCount
    6.54     static  bool initTried = 0;
    6.55     static  Function_InitializeCriticalSectionAndSpinCount pInitFn = 0;
    6.56 
    6.57     if (!initTried)
    6.58     {
    6.59         HMODULE hmodule = ::LoadLibrary(OVR_STR("kernel32.dll"));
    6.60         pInitFn     = (Function_InitializeCriticalSectionAndSpinCount)
    6.61                       ::GetProcAddress(hmodule, "InitializeCriticalSectionAndSpinCount");
    6.62         initTried   = true;
    6.63     }
    6.64 
    6.65     // Initialize the critical section
    6.66     if (pInitFn)
    6.67         pInitFn(&cs, spinCount);
    6.68     else
    6.69         ::InitializeCriticalSection(&cs);
    6.70 #endif
    6.71    
    6.72 }
    6.73 
    6.74 
    6.75 Lock::~Lock()
    6.76 {
    6.77     DeleteCriticalSection(&cs);
    6.78 }
    6.79 
    6.80 
    6.81 #endif
    6.82 
    6.83 } // OVR
    6.84 
    6.85 #endif // OVR_ENABLE_THREADS
    6.86 \ No newline at end of file
    6.87 +/************************************************************************************
    6.88 +
    6.89 +Filename    :   OVR_Atomic.cpp
    6.90 +Content     :   Contains atomic operations and inline fastest locking
    6.91 +                functionality. Will contain #ifdefs for OS efficiency.
    6.92 +                Have non-thread-safe implementation if not available.
    6.93 +Created     :   September 19, 2012
    6.94 +Notes       : 
    6.95 +
    6.96 +Copyright   :   Copyright 2012 Oculus VR, Inc. All Rights reserved.
    6.97 +
    6.98 +Use of this software is subject to the terms of the Oculus license
    6.99 +agreement provided at the time of installation or download, or which
   6.100 +otherwise accompanies this software in either electronic or hard copy form.
   6.101 +
   6.102 +************************************************************************************/
   6.103 +
   6.104 +#include "OVR_Atomic.h"
   6.105 +
   6.106 +#ifdef OVR_ENABLE_THREADS
   6.107 +
   6.108 +// Include Windows 8-Metro compatible Synchronization API
   6.109 +#if defined(OVR_OS_WIN32) && defined(NTDDI_WIN8) && (NTDDI_VERSION >= NTDDI_WIN8)
   6.110 +#include <synchapi.h>
   6.111 +#endif
   6.112 +
   6.113 +
   6.114 +namespace OVR {
   6.115 +
   6.116 +// ***** Windows Lock implementation
   6.117 +
   6.118 +#if defined(OVR_OS_WIN32)
   6.119 +
   6.120 +// ***** Standard Win32 Lock implementation
   6.121 +
   6.122 +// Constructors
   6.123 +Lock::Lock(unsigned spinCount)
   6.124 +{
   6.125 +#if defined(NTDDI_WIN8) && (NTDDI_VERSION >= NTDDI_WIN8)
   6.126 +   // On Windows 8 we use InitializeCriticalSectionEx due to Metro-Compatibility
   6.127 +   InitializeCriticalSectionEx(&cs, spinCount,
   6.128 +                               OVR_DEBUG_SELECT(NULL, CRITICAL_SECTION_NO_DEBUG_INFO));
   6.129 +#else
   6.130 +    // Spin count init critical section function prototype for Window NT
   6.131 +    typedef BOOL (WINAPI *Function_InitializeCriticalSectionAndSpinCount) 
   6.132 +                 (LPCRITICAL_SECTION lpCriticalSection, DWORD dwSpinCount);
   6.133 +
   6.134 +
   6.135 +    // Try to load function dynamically so that we don't require NT
   6.136 +    // On Windows NT we will use InitializeCriticalSectionAndSpinCount
   6.137 +    static  bool initTried = 0;
   6.138 +    static  Function_InitializeCriticalSectionAndSpinCount pInitFn = 0;
   6.139 +
   6.140 +    if (!initTried)
   6.141 +    {
   6.142 +        HMODULE hmodule = ::LoadLibrary(OVR_STR("kernel32.dll"));
   6.143 +        pInitFn     = (Function_InitializeCriticalSectionAndSpinCount)
   6.144 +                      ::GetProcAddress(hmodule, "InitializeCriticalSectionAndSpinCount");
   6.145 +        initTried   = true;
   6.146 +    }
   6.147 +
   6.148 +    // Initialize the critical section
   6.149 +    if (pInitFn)
   6.150 +        pInitFn(&cs, spinCount);
   6.151 +    else
   6.152 +        ::InitializeCriticalSection(&cs);
   6.153 +#endif
   6.154 +   
   6.155 +}
   6.156 +
   6.157 +
   6.158 +Lock::~Lock()
   6.159 +{
   6.160 +    DeleteCriticalSection(&cs);
   6.161 +}
   6.162 +
   6.163 +
   6.164 +#endif
   6.165 +
   6.166 +} // OVR
   6.167 +
   6.168 +#endif // OVR_ENABLE_THREADS
     7.1 --- a/libovr/Src/Kernel/OVR_Atomic.h	Sat Sep 14 17:51:03 2013 +0300
     7.2 +++ b/libovr/Src/Kernel/OVR_Atomic.h	Sun Sep 15 04:10:05 2013 +0300
     7.3 @@ -1,1 +1,859 @@
     7.4 -/************************************************************************************
     7.5 
     7.6 PublicHeader:   OVR.h
     7.7 Filename    :   OVR_Atomic.h
     7.8 Content     :   Contains atomic operations and inline fastest locking
     7.9                 functionality. Will contain #ifdefs for OS efficiency.
    7.10                 Have non-thread-safe implementaion if not available.
    7.11 Created     :   September 19, 2012
    7.12 Notes       : 
    7.13 
    7.14 Copyright   :   Copyright 2012 Oculus VR, Inc. All Rights reserved.
    7.15 
    7.16 Use of this software is subject to the terms of the Oculus license
    7.17 agreement provided at the time of installation or download, or which
    7.18 otherwise accompanies this software in either electronic or hard copy form.
    7.19 
    7.20 ************************************************************************************/
    7.21 #ifndef OVR_Atomic_h
    7.22 #define OVR_Atomic_h
    7.23 
    7.24 #include "OVR_Types.h"
    7.25 
    7.26 // Include System thread functionality.
    7.27 #if defined(OVR_OS_WIN32)
    7.28 #include <windows.h>
    7.29 #else
    7.30 #include <pthread.h>
    7.31 #endif
    7.32 
    7.33 
    7.34 namespace OVR {
    7.35 
    7.36 
    7.37 // ****** Declared classes
    7.38 
    7.39 // If there is NO thread support we implement AtomicOps and
    7.40 // Lock objects as no-ops. The other classes are not defined.
    7.41 template<class C> class AtomicOps;
    7.42 template<class T> class AtomicInt;
    7.43 template<class T> class AtomicPtr;
    7.44 
    7.45 class   Lock;
    7.46 
    7.47 
    7.48 //-----------------------------------------------------------------------------------
    7.49 // ***** AtomicOps
    7.50 
    7.51 // Atomic operations are provided by the AtomicOps templates class,
    7.52 // implemented through system-specific AtomicOpsRaw specializations.
    7.53 // It provides several fundamental operations such as Exchange, ExchangeAdd
    7.54 // CompareAndSet, and Store_Release. Each function includes several memory
    7.55 // synchronization versions, important for multiprocessing CPUs with weak
    7.56 // memory consistency. The following memory fencing strategies are supported:
    7.57 //
    7.58 //  - NoSync.  No memory synchronization is done for atomic op.
    7.59 //  - Release. All other memory writes are completed before atomic op
    7.60 //             writes its results.
    7.61 //  - Acquire. Further memory reads are forced to wait until atomic op
    7.62 //             executes, guaranteeing that the right values will be seen.
    7.63 //  - Sync.    A combination of Release and Acquire.
    7.64 
    7.65 
    7.66 // *** AtomicOpsRaw
    7.67 
    7.68 // AtomicOpsRaw is a specialized template that provides atomic operations 
    7.69 // used by AtomicOps. This class has two fundamental qualities: (1) it
    7.70 // defines a type T of correct size, and (2) provides operations that work
    7.71 // atomically, such as Exchange_Sync and CompareAndSet_Release.
    7.72 
    7.73 // AtomicOpsRawBase class contains shared constants/classes for AtomicOpsRaw.
    7.74 // The primary thing is does is define sync class objects, whose destructor and
    7.75 // constructor provide places to insert appropriate synchronization calls, on 
    7.76 // systems where such calls are necessary. So far, the breakdown is as follows:
    7.77 // 
    7.78 //  - X86 systems don't need custom syncs, since their exchange/atomic
    7.79 //    instructions are implicitly synchronized.
    7.80 //  - PowerPC requires lwsync/isync instructions that can use this mechanism.
    7.81 //  - If some other systems require a mechanism where syncing type is associated
    7.82 //    with a particular instruction, the default implementation (which implements
    7.83 //    all Sync, Acquire, and Release modes in terms of NoSync and fence) may not
    7.84 //    work. Ii that case it will need to be #ifdef-ed conditionally.
    7.85 
    7.86 struct AtomicOpsRawBase
    7.87 {
    7.88 #if !defined(OVR_ENABLE_THREADS) || defined(OVR_CPU_X86) || defined(OVR_OS_WIN32) || defined(OVR_OS_IPHONE)
    7.89     // Need to have empty constructor to avoid class 'unused' variable warning.
    7.90     struct FullSync { inline FullSync() { } };
    7.91     struct AcquireSync { inline AcquireSync() { } };
    7.92     struct ReleaseSync { inline ReleaseSync() { } };
    7.93 
    7.94 #elif defined(OVR_CPU_PPC64) || defined(OVR_CPU_PPC)
    7.95     struct FullSync { inline FullSync() { asm volatile("sync\n"); } ~FullSync() { asm volatile("isync\n"); } };
    7.96     struct AcquireSync { inline AcquireSync() { } ~AcquireSync() { asm volatile("isync\n"); } };
    7.97     struct ReleaseSync { inline ReleaseSync() { asm volatile("sync\n"); } };
    7.98 
    7.99 #elif defined(OVR_CPU_MIPS)
   7.100     struct FullSync { inline FullSync() { asm volatile("sync\n"); } ~FullSync() { asm volatile("sync\n"); } };
   7.101     struct AcquireSync { inline AcquireSync() { } ~AcquireSync() { asm volatile("sync\n"); } };
   7.102     struct ReleaseSync { inline ReleaseSync() { asm volatile("sync\n"); } };
   7.103 
   7.104 #elif defined(OVR_CPU_ARM)
   7.105     struct FullSync { inline FullSync() { asm volatile("dmb\n"); } ~FullSync() { asm volatile("dmb\n"); } };
   7.106     struct AcquireSync { inline AcquireSync() { } ~AcquireSync() { asm volatile("dmb\n"); } };
   7.107     struct ReleaseSync { inline ReleaseSync() { asm volatile("dmb\n"); } };
   7.108 
   7.109 
   7.110 #elif defined(OVR_CC_GNU) && (__GNUC__ >= 4)
   7.111     // __sync functions are already full sync
   7.112     struct FullSync { inline FullSync() { } };
   7.113     struct AcquireSync { inline AcquireSync() { } };
   7.114     struct ReleaseSync { inline ReleaseSync() { } };
   7.115 #endif
   7.116 };
   7.117 
   7.118 
   7.119 // 4-Byte raw data atomic op implementation class.
   7.120 struct AtomicOpsRaw_4ByteImpl : public AtomicOpsRawBase
   7.121 {
   7.122 #if !defined(OVR_ENABLE_THREADS)
   7.123 
   7.124     // Provide a type for no-thread-support cases. Used by AtomicOpsRaw_DefImpl.
   7.125     typedef UInt32 T;   
   7.126 
   7.127     // *** Thread - Safe Atomic Versions.
   7.128 
   7.129 #elif defined(OVR_OS_WIN32)
   7.130 
   7.131     // Use special defined for VC6, where volatile is not used and
   7.132     // InterlockedCompareExchange is declared incorrectly.
   7.133     typedef LONG T;      
   7.134 #if defined(OVR_CC_MSVC) && (OVR_CC_MSVC < 1300)
   7.135     typedef T* InterlockTPtr;
   7.136     typedef LPVOID ET;
   7.137     typedef ET* InterlockETPtr;
   7.138 #else
   7.139     typedef volatile T* InterlockTPtr;
   7.140     typedef T ET;
   7.141     typedef InterlockTPtr InterlockETPtr;
   7.142 #endif
   7.143     inline static T     Exchange_NoSync(volatile T* p, T val)            { return InterlockedExchange((InterlockTPtr)p, val); }
   7.144     inline static T     ExchangeAdd_NoSync(volatile T* p, T val)         { return InterlockedExchangeAdd((InterlockTPtr)p, val); }
   7.145     inline static bool  CompareAndSet_NoSync(volatile T* p, T c, T val)  { return InterlockedCompareExchange((InterlockETPtr)p, (ET)val, (ET)c) == (ET)c; }
   7.146 
   7.147 #elif defined(OVR_CPU_PPC64) || defined(OVR_CPU_PPC)
   7.148     typedef UInt32 T;
   7.149     static inline UInt32   Exchange_NoSync(volatile UInt32 *i, UInt32 j)
   7.150     {
   7.151         UInt32 ret;
   7.152 
   7.153         asm volatile("1:\n\t"
   7.154                      "lwarx  %[r],0,%[i]\n\t"
   7.155                      "stwcx. %[j],0,%[i]\n\t"
   7.156                      "bne-   1b\n"
   7.157                      : "+m" (*i), [r] "=&b" (ret) : [i] "b" (i), [j] "b" (j) : "cc", "memory");
   7.158 
   7.159         return ret;
   7.160     }
   7.161 
   7.162     static inline UInt32   ExchangeAdd_NoSync(volatile UInt32 *i, UInt32 j)
   7.163     {
   7.164         UInt32 dummy, ret;
   7.165 
   7.166         asm volatile("1:\n\t"
   7.167                      "lwarx  %[r],0,%[i]\n\t"
   7.168                      "add    %[o],%[r],%[j]\n\t"
   7.169                      "stwcx. %[o],0,%[i]\n\t"
   7.170                      "bne-   1b\n"
   7.171                      : "+m" (*i), [r] "=&b" (ret), [o] "=&r" (dummy) : [i] "b" (i), [j] "b" (j) : "cc", "memory");
   7.172 
   7.173         return ret;
   7.174     }
   7.175 
   7.176     static inline bool     CompareAndSet_NoSync(volatile UInt32 *i, UInt32 c, UInt32 value)
   7.177     {
   7.178         UInt32 ret;
   7.179 
   7.180         asm volatile("1:\n\t"
   7.181                      "lwarx  %[r],0,%[i]\n\t"
   7.182                      "cmpw   0,%[r],%[cmp]\n\t"
   7.183                      "mfcr   %[r]\n\t"
   7.184                      "bne-   2f\n\t"
   7.185                      "stwcx. %[val],0,%[i]\n\t"
   7.186                      "bne-   1b\n\t"
   7.187                      "2:\n"
   7.188                      : "+m" (*i), [r] "=&b" (ret) : [i] "b" (i), [cmp] "b" (c), [val] "b" (value) : "cc", "memory");
   7.189 
   7.190         return (ret & 0x20000000) ? 1 : 0;
   7.191     }
   7.192 
   7.193 #elif defined(OVR_CPU_MIPS)
   7.194     typedef UInt32 T;
   7.195 
   7.196     static inline UInt32   Exchange_NoSync(volatile UInt32 *i, UInt32 j)
   7.197     {
   7.198         UInt32 ret;
   7.199 
   7.200         asm volatile("1:\n\t"
   7.201                      "ll     %[r],0(%[i])\n\t"
   7.202                      "sc     %[j],0(%[i])\n\t"
   7.203                      "beq    %[j],$0,1b\n\t"
   7.204                      "nop    \n"
   7.205                      : "+m" (*i), [r] "=&d" (ret) : [i] "d" (i), [j] "d" (j) : "cc", "memory");
   7.206 
   7.207         return ret;
   7.208     }
   7.209 
   7.210     static inline UInt32   ExchangeAdd_NoSync(volatile UInt32 *i, UInt32 j)
   7.211     {
   7.212         UInt32 ret;
   7.213 
   7.214         asm volatile("1:\n\t"
   7.215                      "ll     %[r],0(%[i])\n\t"
   7.216                      "addu   %[j],%[r],%[j]\n\t"
   7.217                      "sc     %[j],0(%[i])\n\t"
   7.218                      "beq    %[j],$0,1b\n\t"
   7.219                      "nop    \n"
   7.220                      : "+m" (*i), [r] "=&d" (ret) : [i] "d" (i), [j] "d" (j) : "cc", "memory");
   7.221 
   7.222         return ret;
   7.223     }
   7.224 
   7.225     static inline bool     CompareAndSet_NoSync(volatile UInt32 *i, UInt32 c, UInt32 value)
   7.226     {
   7.227         UInt32 ret, dummy;
   7.228 
   7.229         asm volatile("1:\n\t"
   7.230                      "move   %[r],$0\n\t"
   7.231                      "ll     %[o],0(%[i])\n\t"
   7.232                      "bne    %[o],%[c],2f\n\t"
   7.233                      "move   %[r],%[v]\n\t"
   7.234                      "sc     %[r],0(%[i])\n\t"
   7.235                      "beq    %[r],$0,1b\n\t"
   7.236                      "nop    \n\t"
   7.237                      "2:\n"
   7.238                      : "+m" (*i),[r] "=&d" (ret), [o] "=&d" (dummy) : [i] "d" (i), [c] "d" (c), [v] "d" (value)
   7.239                      : "cc", "memory");
   7.240 
   7.241         return ret;
   7.242     }
   7.243 
   7.244 #elif defined(OVR_CPU_ARM) && defined(OVR_CC_ARM)
   7.245     typedef UInt32 T;
   7.246 
   7.247     static inline UInt32   Exchange_NoSync(volatile UInt32 *i, UInt32 j)
   7.248     {
   7.249         for(;;)
   7.250         {
   7.251             T r = __ldrex(i);
   7.252             if (__strex(j, i) == 0)
   7.253                 return r;
   7.254         }
   7.255     }
   7.256     static inline UInt32   ExchangeAdd_NoSync(volatile UInt32 *i, UInt32 j)
   7.257     {
   7.258         for(;;)
   7.259         {
   7.260             T r = __ldrex(i);
   7.261             if (__strex(r + j, i) == 0)
   7.262                 return r;
   7.263         }
   7.264     }
   7.265 
   7.266     static inline bool     CompareAndSet_NoSync(volatile UInt32 *i, UInt32 c, UInt32 value)
   7.267     {
   7.268         for(;;)
   7.269         {
   7.270             T r = __ldrex(i);
   7.271             if (r != c)
   7.272                 return 0;
   7.273             if (__strex(value, i) == 0)
   7.274                 return 1;
   7.275         }
   7.276     }
   7.277 
   7.278 #elif defined(OVR_CPU_ARM)
   7.279     typedef UInt32 T;
   7.280 
   7.281     static inline UInt32   Exchange_NoSync(volatile UInt32 *i, UInt32 j)
   7.282     {
   7.283         UInt32 ret, dummy;
   7.284 
   7.285         asm volatile("1:\n\t"
   7.286             "ldrex  %[r],[%[i]]\n\t"
   7.287             "strex  %[t],%[j],[%[i]]\n\t"
   7.288             "cmp    %[t],#0\n\t"
   7.289             "bne    1b\n\t"
   7.290             : "+m" (*i), [r] "=&r" (ret), [t] "=&r" (dummy) : [i] "r" (i), [j] "r" (j) : "cc", "memory");
   7.291 
   7.292         return ret;
   7.293     }
   7.294 
   7.295     static inline UInt32   ExchangeAdd_NoSync(volatile UInt32 *i, UInt32 j)
   7.296     {
   7.297         UInt32 ret, dummy, test;
   7.298 
   7.299         asm volatile("1:\n\t"
   7.300             "ldrex  %[r],[%[i]]\n\t"
   7.301             "add    %[o],%[r],%[j]\n\t"
   7.302             "strex  %[t],%[o],[%[i]]\n\t"
   7.303             "cmp    %[t],#0\n\t"
   7.304             "bne    1b\n\t"
   7.305             : "+m" (*i), [r] "=&r" (ret), [o] "=&r" (dummy), [t] "=&r" (test)  : [i] "r" (i), [j] "r" (j) : "cc", "memory");
   7.306 
   7.307         return ret;
   7.308     }
   7.309 
   7.310     static inline bool     CompareAndSet_NoSync(volatile UInt32 *i, UInt32 c, UInt32 value)
   7.311     {
   7.312         UInt32 ret = 1, dummy, test;
   7.313 
   7.314         asm volatile("1:\n\t"
   7.315             "ldrex  %[o],[%[i]]\n\t"
   7.316             "cmp    %[o],%[c]\n\t"
   7.317             "bne    2f\n\t"
   7.318             "strex  %[r],%[v],[%[i]]\n\t"
   7.319             "cmp    %[r],#0\n\t"
   7.320             "bne    1b\n\t"
   7.321             "2:\n"
   7.322             : "+m" (*i),[r] "=&r" (ret), [o] "=&r" (dummy), [t] "=&r" (test) : [i] "r" (i), [c] "r" (c), [v] "r" (value)
   7.323             : "cc", "memory");
   7.324 
   7.325         return !ret;
   7.326     }
   7.327 
   7.328 #elif defined(OVR_CPU_X86)
   7.329     typedef UInt32 T;
   7.330 
   7.331     static inline UInt32   Exchange_NoSync(volatile UInt32 *i, UInt32 j)
   7.332     {
   7.333         asm volatile("xchgl %1,%[i]\n"
   7.334                      : "+m" (*i), "=q" (j) : [i] "m" (*i), "1" (j) : "cc", "memory");
   7.335 
   7.336         return j;
   7.337     }
   7.338 
   7.339     static inline UInt32   ExchangeAdd_NoSync(volatile UInt32 *i, UInt32 j)
   7.340     {
   7.341         asm volatile("lock; xaddl %1,%[i]\n"
   7.342                      : "+m" (*i), "+q" (j) : [i] "m" (*i) : "cc", "memory");
   7.343 
   7.344         return j;
   7.345     }
   7.346 
   7.347     static inline bool     CompareAndSet_NoSync(volatile UInt32 *i, UInt32 c, UInt32 value)
   7.348     {
   7.349         UInt32 ret;
   7.350 
   7.351         asm volatile("lock; cmpxchgl %[v],%[i]\n"
   7.352                      : "+m" (*i), "=a" (ret) : [i] "m" (*i), "1" (c), [v] "q" (value) : "cc", "memory");
   7.353 
   7.354         return (ret == c);
   7.355     }
   7.356 
   7.357 #elif defined(OVR_CC_GNU) && (__GNUC__ >= 4 && __GNUC_MINOR__ >= 1)
   7.358 
   7.359     typedef UInt32 T;
   7.360 
   7.361     static inline T   Exchange_NoSync(volatile T *i, T j)
   7.362     {
   7.363         T v;
   7.364         do {
   7.365             v = *i;
   7.366         } while (!__sync_bool_compare_and_swap(i, v, j));
   7.367         return v;
   7.368     }
   7.369 
   7.370     static inline T   ExchangeAdd_NoSync(volatile T *i, T j)
   7.371     {
   7.372         return __sync_fetch_and_add(i, j);
   7.373     }
   7.374 
   7.375     static inline bool     CompareAndSet_NoSync(volatile T *i, T c, T value)
   7.376     {
   7.377         return __sync_bool_compare_and_swap(i, c, value);
   7.378     }
   7.379 
   7.380 #endif // OS
   7.381 };
   7.382 
   7.383 
   7.384 // 8-Byte raw data data atomic op implementation class.
   7.385 // Currently implementation is provided only on systems with 64-bit pointers.
   7.386 struct AtomicOpsRaw_8ByteImpl : public AtomicOpsRawBase
   7.387 {    
   7.388 #if !defined(OVR_64BIT_POINTERS) || !defined(OVR_ENABLE_THREADS)
   7.389 
   7.390     // Provide a type for no-thread-support cases. Used by AtomicOpsRaw_DefImpl.
   7.391     typedef UInt64 T;
   7.392 
   7.393     // *** Thread - Safe OS specific versions.
   7.394 #elif defined(OVR_OS_WIN32)
   7.395 
   7.396     // This is only for 64-bit systems.
   7.397     typedef LONG64      T;
   7.398     typedef volatile T* InterlockTPtr;    
   7.399     inline static T     Exchange_NoSync(volatile T* p, T val)            { return InterlockedExchange64((InterlockTPtr)p, val); }
   7.400     inline static T     ExchangeAdd_NoSync(volatile T* p, T val)         { return InterlockedExchangeAdd64((InterlockTPtr)p, val); }
   7.401     inline static bool  CompareAndSet_NoSync(volatile T* p, T c, T val)  { return InterlockedCompareExchange64((InterlockTPtr)p, val, c) == c; }
   7.402 
   7.403 #elif defined(OVR_CPU_PPC64)
   7.404  
   7.405     typedef UInt64 T;
   7.406 
   7.407     static inline UInt64   Exchange_NoSync(volatile UInt64 *i, UInt64 j)
   7.408     {
   7.409         UInt64 dummy, ret;
   7.410 
   7.411         asm volatile("1:\n\t"
   7.412                      "ldarx  %[r],0,%[i]\n\t"
   7.413                      "mr     %[o],%[j]\n\t"
   7.414                      "stdcx. %[o],0,%[i]\n\t"
   7.415                      "bne-   1b\n"
   7.416                      : "+m" (*i), [r] "=&b" (ret), [o] "=&r" (dummy) : [i] "b" (i), [j] "b" (j) : "cc");
   7.417 
   7.418         return ret;
   7.419     }
   7.420 
   7.421     static inline UInt64   ExchangeAdd_NoSync(volatile UInt64 *i, UInt64 j)
   7.422     {
   7.423         UInt64 dummy, ret;
   7.424 
   7.425         asm volatile("1:\n\t"
   7.426                      "ldarx  %[r],0,%[i]\n\t"
   7.427                      "add    %[o],%[r],%[j]\n\t"
   7.428                      "stdcx. %[o],0,%[i]\n\t"
   7.429                      "bne-   1b\n"
   7.430                      : "+m" (*i), [r] "=&b" (ret), [o] "=&r" (dummy) : [i] "b" (i), [j] "b" (j) : "cc");
   7.431 
   7.432         return ret;
   7.433     }
   7.434 
   7.435     static inline bool     CompareAndSet_NoSync(volatile UInt64 *i, UInt64 c, UInt64 value)
   7.436     {
   7.437         UInt64 ret, dummy;
   7.438 
   7.439         asm volatile("1:\n\t"
   7.440                      "ldarx  %[r],0,%[i]\n\t"
   7.441                      "cmpw   0,%[r],%[cmp]\n\t"
   7.442                      "mfcr   %[r]\n\t"
   7.443                      "bne-   2f\n\t"
   7.444                      "stdcx. %[val],0,%[i]\n\t"
   7.445                      "bne-   1b\n\t"
   7.446                      "2:\n"
   7.447                      : "+m" (*i), [r] "=&b" (ret), [o] "=&r" (dummy) : [i] "b" (i), [cmp] "b" (c), [val] "b" (value) : "cc");
   7.448 
   7.449         return (ret & 0x20000000) ? 1 : 0;
   7.450     }
   7.451 
   7.452 #elif defined(OVR_CC_GNU) && (__GNUC__ >= 4 && __GNUC_MINOR__ >= 1)
   7.453 
   7.454     typedef UInt64 T;
   7.455 
   7.456     static inline T   Exchange_NoSync(volatile T *i, T j)
   7.457     {
   7.458         T v;
   7.459         do {
   7.460             v = *i;
   7.461         } while (!__sync_bool_compare_and_swap(i, v, j));
   7.462         return v;
   7.463     }
   7.464 
   7.465     static inline T   ExchangeAdd_NoSync(volatile T *i, T j)
   7.466     {
   7.467         return __sync_fetch_and_add(i, j);
   7.468     }
   7.469 
   7.470     static inline bool     CompareAndSet_NoSync(volatile T *i, T c, T value)
   7.471     {
   7.472         return __sync_bool_compare_and_swap(i, c, value);
   7.473     }
   7.474 
   7.475 #endif // OS
   7.476 };
   7.477 
   7.478 
   7.479 // Default implementation for AtomicOpsRaw; provides implementation of mem-fenced
   7.480 // atomic operations where fencing is done with a sync object wrapped around a NoSync
   7.481 // operation implemented in the base class. If such implementation is not possible
   7.482 // on a given platform, #ifdefs can be used to disable it and then op functions can be
   7.483 // implemented individually in the appropriate AtomicOpsRaw<size> class.
   7.484 
   7.485 template<class O>
   7.486 struct AtomicOpsRaw_DefImpl : public O
   7.487 {
   7.488     typedef typename O::T O_T;
   7.489     typedef typename O::FullSync    O_FullSync;
   7.490     typedef typename O::AcquireSync O_AcquireSync;
   7.491     typedef typename O::ReleaseSync O_ReleaseSync;
   7.492 
   7.493     // If there is no thread support, provide the default implementation. In this case,
   7.494     // the base class (0) must still provide the T declaration.
   7.495 #ifndef OVR_ENABLE_THREADS
   7.496 
   7.497     // Atomic exchange of val with argument. Returns old val.
   7.498     inline static O_T   Exchange_NoSync(volatile O_T* p, O_T val)           { O_T old = *p; *p = val; return old; }
   7.499     // Adds a new val to argument; returns its old val.
   7.500     inline static O_T   ExchangeAdd_NoSync(volatile O_T* p, O_T val)        { O_T old = *p; *p += val; return old; }
   7.501     // Compares the argument data with 'c' val.
   7.502     // If succeeded, stores val int '*p' and returns true; otherwise returns false.
   7.503     inline static bool  CompareAndSet_NoSync(volatile O_T* p, O_T c, O_T val) { if (*p==c) { *p = val; return 1; } return 0; }
   7.504 
   7.505 #endif
   7.506 
   7.507     // If NoSync wrapped implementation may not be possible, it this block should be
   7.508     //  replaced with per-function implementation in O.
   7.509     // "AtomicOpsRaw_DefImpl<O>::" prefix in calls below.
   7.510     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); }
   7.511     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); }
   7.512     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); }  
   7.513     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); }
   7.514     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); }
   7.515     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); }
   7.516     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); }
   7.517     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); }
   7.518     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); }
   7.519 
   7.520     // Loads and stores with memory fence. These have only the relevant versions.
   7.521 #ifdef OVR_CPU_X86
   7.522     // On X86, Store_Release is implemented as exchange. Note that we can also
   7.523     // consider 'sfence' in the future, although it is not as compatible with older CPUs.
   7.524     inline static void  Store_Release(volatile O_T* p, O_T val)  { Exchange_Release(p, val); }
   7.525 #else
   7.526     inline static void  Store_Release(volatile O_T* p, O_T val)  { O_ReleaseSync sync; OVR_UNUSED(sync); *p = val; }
   7.527 #endif
   7.528     inline static O_T   Load_Acquire(const volatile O_T* p)      { O_AcquireSync sync; OVR_UNUSED(sync); return *p; }
   7.529 };
   7.530 
   7.531 
   7.532 template<int size>
   7.533 struct AtomicOpsRaw : public AtomicOpsRawBase { };
   7.534 
   7.535 template<>
   7.536 struct AtomicOpsRaw<4> : public AtomicOpsRaw_DefImpl<AtomicOpsRaw_4ByteImpl>
   7.537 {   
   7.538     // Ensure that assigned type size is correct.
   7.539     AtomicOpsRaw()
   7.540     { OVR_COMPILER_ASSERT(sizeof(AtomicOpsRaw_DefImpl<AtomicOpsRaw_4ByteImpl>::T) == 4); }
   7.541 };
   7.542 template<>
   7.543 struct AtomicOpsRaw<8> : public AtomicOpsRaw_DefImpl<AtomicOpsRaw_8ByteImpl>
   7.544 {
   7.545     AtomicOpsRaw()
   7.546     { OVR_COMPILER_ASSERT(sizeof(AtomicOpsRaw_DefImpl<AtomicOpsRaw_8ByteImpl>::T) == 8); }
   7.547 };
   7.548 
   7.549 
   7.550 // *** AtomicOps - implementation of atomic Ops for specified class
   7.551 
   7.552 // Implements atomic ops on a class, provided that the object is either
   7.553 // 4 or 8 bytes in size (depending on the AtomicOpsRaw specializations
   7.554 // available). Relies on AtomicOpsRaw for much of implementation.
   7.555 
   7.556 template<class C>
   7.557 class AtomicOps
   7.558 {
   7.559     typedef AtomicOpsRaw<sizeof(C)>       Ops;
   7.560     typedef typename Ops::T               T;
   7.561     typedef volatile typename Ops::T*     PT;
   7.562     // We cast through unions to (1) avoid pointer size compiler warnings
   7.563     // and (2) ensure that there are no problems with strict pointer aliasing.
   7.564     union C2T_union { C c; T t; };
   7.565 
   7.566 public:
   7.567     // General purpose implementation for standard syncs.    
   7.568     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; }
   7.569     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; }
   7.570     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; }
   7.571     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; }
   7.572     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; }
   7.573     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; }
   7.574     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; }
   7.575     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; }
   7.576     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); }
   7.577     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); }
   7.578     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); }
   7.579     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); }
   7.580     // Loads and stores with memory fence. These have only the relevant versions.    
   7.581     inline static void  Store_Release(volatile C* p, C val)             { C2T_union u; u.c = val; Ops::Store_Release((PT)p, u.t); }    
   7.582     inline static C     Load_Acquire(const volatile C* p)               { C2T_union u; u.t = Ops::Load_Acquire((PT)p); return u.c; }
   7.583 };
   7.584 
   7.585 
   7.586 
   7.587 // Atomic value base class - implements operations shared for integers and pointers.
   7.588 template<class T>
   7.589 class AtomicValueBase
   7.590 {
   7.591 protected:
   7.592     typedef AtomicOps<T> Ops;
   7.593 public:
   7.594 
   7.595     volatile T  Value;
   7.596 
   7.597     inline AtomicValueBase()                  { }
   7.598     explicit inline AtomicValueBase(T val)    { Ops::Store_Release(&Value, val); }
   7.599 
   7.600     // Most libraries (TBB and Joshua Scholar's) library do not do Load_Acquire
   7.601     // here, since most algorithms do not require atomic loads. Needs some research.    
   7.602     inline operator T() const { return Value; }
   7.603 
   7.604     // *** Standard Atomic inlines
   7.605     inline T     Exchange_Sync(T val)               { return Ops::Exchange_Sync(&Value,  val); }
   7.606     inline T     Exchange_Release(T val)            { return Ops::Exchange_Release(&Value, val); }
   7.607     inline T     Exchange_Acquire(T val)            { return Ops::Exchange_Acquire(&Value, val); }
   7.608     inline T     Exchange_NoSync(T val)             { return Ops::Exchange_NoSync(&Value, val); }
   7.609     inline bool  CompareAndSet_Sync(T c, T val)     { return Ops::CompareAndSet_Sync(&Value, c, val); }
   7.610     inline bool  CompareAndSet_Release(T c, T val)  { return Ops::CompareAndSet_Release(&Value, c, val); }
   7.611     inline bool  CompareAndSet_Acquire(T c, T val)  { return Ops::CompareAndSet_Relse(&Value, c, val); }
   7.612     inline bool  CompareAndSet_NoSync(T c, T val)   { return Ops::CompareAndSet_NoSync(&Value, c, val); }
   7.613     // Load & Store.
   7.614     inline void  Store_Release(T val)               { Ops::Store_Release(&Value, val); }
   7.615     inline T     Load_Acquire() const               { return Ops::Load_Acquire(&Value);  }
   7.616 };
   7.617 
   7.618 
   7.619 // ***** AtomicPtr - Atomic pointer template
   7.620 
   7.621 // This pointer class supports atomic assignments with release,
   7.622 // increment / decrement operations, and conditional compare + set.
   7.623 
   7.624 template<class T>
   7.625 class AtomicPtr : public AtomicValueBase<T*>
   7.626 {
   7.627     typedef typename AtomicValueBase<T*>::Ops Ops;
   7.628 
   7.629 public:
   7.630     // Initialize pointer value to 0 by default; use Store_Release only with explicit constructor.
   7.631     inline AtomicPtr() : AtomicValueBase<T*>()                     { this->Value = 0; }
   7.632     explicit inline AtomicPtr(T* val) : AtomicValueBase<T*>(val)   { }
   7.633         
   7.634     // Pointer access.
   7.635     inline T* operator -> () const     { return this->Load_Acquire(); }
   7.636 
   7.637     // It looks like it is convenient to have Load_Acquire characteristics
   7.638     // for this, since that is convenient for algorithms such as linked
   7.639     // list traversals that can be added to bu another thread.
   7.640     inline operator T* () const        { return this->Load_Acquire(); }
   7.641 
   7.642 
   7.643     // *** Standard Atomic inlines (applicable to pointers)
   7.644 
   7.645     // ExhangeAdd considers pointer size for pointers.
   7.646     template<class I>
   7.647     inline T*     ExchangeAdd_Sync(I incr)      { return Ops::ExchangeAdd_Sync(&this->Value, ((T*)0) + incr); }
   7.648     template<class I>
   7.649     inline T*     ExchangeAdd_Release(I incr)   { return Ops::ExchangeAdd_Release(&this->Value, ((T*)0) + incr); }
   7.650     template<class I>
   7.651     inline T*     ExchangeAdd_Acquire(I incr)   { return Ops::ExchangeAdd_Acquire(&this->Value, ((T*)0) + incr); }
   7.652     template<class I>
   7.653     inline T*     ExchangeAdd_NoSync(I incr)    { return Ops::ExchangeAdd_NoSync(&this->Value, ((T*)0) + incr); }
   7.654 
   7.655     // *** Atomic Operators
   7.656 
   7.657     inline T* operator = (T* val)  { this->Store_Release(val); return val; }
   7.658 
   7.659     template<class I>
   7.660     inline T* operator += (I val) { return ExchangeAdd_Sync(val) + val; }
   7.661     template<class I>
   7.662     inline T* operator -= (I val) { return operator += (-val); }
   7.663 
   7.664     inline T* operator ++ ()      { return ExchangeAdd_Sync(1) + 1; }
   7.665     inline T* operator -- ()      { return ExchangeAdd_Sync(-1) - 1; }
   7.666     inline T* operator ++ (int)   { return ExchangeAdd_Sync(1); }
   7.667     inline T* operator -- (int)   { return ExchangeAdd_Sync(-1); }
   7.668 };
   7.669 
   7.670 
   7.671 // ***** AtomicInt - Atomic integer template
   7.672 
   7.673 // Implements an atomic integer type; the exact type to use is provided 
   7.674 // as an argument. Supports atomic Acquire / Release semantics, atomic
   7.675 // arithmetic operations, and atomic conditional compare + set.
   7.676 
   7.677 template<class T>
   7.678 class AtomicInt : public AtomicValueBase<T>
   7.679 {
   7.680     typedef typename AtomicValueBase<T>::Ops Ops;
   7.681 
   7.682 public:
   7.683     inline AtomicInt() : AtomicValueBase<T>()                     { }
   7.684     explicit inline AtomicInt(T val) : AtomicValueBase<T>(val)    { }
   7.685 
   7.686 
   7.687     // *** Standard Atomic inlines (applicable to int)   
   7.688     inline T     ExchangeAdd_Sync(T val)            { return Ops::ExchangeAdd_Sync(&this->Value, val); }
   7.689     inline T     ExchangeAdd_Release(T val)         { return Ops::ExchangeAdd_Release(&this->Value, val); }
   7.690     inline T     ExchangeAdd_Acquire(T val)         { return Ops::ExchangeAdd_Acquire(&this->Value, val); }
   7.691     inline T     ExchangeAdd_NoSync(T val)          { return Ops::ExchangeAdd_NoSync(&this->Value, val); }
   7.692     // These increments could be more efficient because they don't return a value.
   7.693     inline void  Increment_Sync()                   { ExchangeAdd_Sync((T)1); }
   7.694     inline void  Increment_Release()                { ExchangeAdd_Release((T)1); }
   7.695     inline void  Increment_Acquire()                { ExchangeAdd_Acquire((T)1); }    
   7.696     inline void  Increment_NoSync()                 { ExchangeAdd_NoSync((T)1); }
   7.697 
   7.698     // *** Atomic Operators
   7.699 
   7.700     inline T operator = (T val)  { this->Store_Release(val); return val; }
   7.701     inline T operator += (T val) { return ExchangeAdd_Sync(val) + val; }
   7.702     inline T operator -= (T val) { return ExchangeAdd_Sync(0 - val) - val; }
   7.703 
   7.704     inline T operator ++ ()      { return ExchangeAdd_Sync((T)1) + 1; }
   7.705     inline T operator -- ()      { return ExchangeAdd_Sync(((T)0)-1) - 1; }
   7.706     inline T operator ++ (int)   { return ExchangeAdd_Sync((T)1); }
   7.707     inline T operator -- (int)   { return ExchangeAdd_Sync(((T)0)-1); }
   7.708 
   7.709     // More complex atomic operations. Leave it to compiler whether to optimize them or not.
   7.710     T operator &= (T arg)
   7.711     {
   7.712         T comp, newVal;
   7.713         do {
   7.714             comp   = this->Value;
   7.715             newVal = comp & arg;
   7.716         } while(!this->CompareAndSet_Sync(comp, newVal));
   7.717         return newVal;
   7.718     }
   7.719 
   7.720     T operator |= (T arg)
   7.721     {
   7.722         T comp, newVal;
   7.723         do {
   7.724             comp   = this->Value;
   7.725             newVal = comp | arg;
   7.726         } while(!this->CompareAndSet_Sync(comp, newVal));
   7.727         return newVal;
   7.728     }
   7.729 
   7.730     T operator ^= (T arg)
   7.731     {
   7.732         T comp, newVal;
   7.733         do {
   7.734             comp   = this->Value;
   7.735             newVal = comp ^ arg;
   7.736         } while(!this->CompareAndSet_Sync(comp, newVal));
   7.737         return newVal;
   7.738     }
   7.739 
   7.740     T operator *= (T arg)
   7.741     {
   7.742         T comp, newVal;
   7.743         do {
   7.744             comp   = this->Value;
   7.745             newVal = comp * arg;
   7.746         } while(!this->CompareAndSet_Sync(comp, newVal));
   7.747         return newVal;
   7.748     }
   7.749 
   7.750     T operator /= (T arg)
   7.751     {
   7.752         T comp, newVal;
   7.753         do {
   7.754             comp   = this->Value;
   7.755             newVal = comp / arg;
   7.756         } while(!CompareAndSet_Sync(comp, newVal));
   7.757         return newVal;
   7.758     }
   7.759 
   7.760     T operator >>= (unsigned bits)
   7.761     {
   7.762         T comp, newVal;
   7.763         do {
   7.764             comp   = this->Value;
   7.765             newVal = comp >> bits;
   7.766         } while(!CompareAndSet_Sync(comp, newVal));
   7.767         return newVal;
   7.768     }
   7.769 
   7.770     T operator <<= (unsigned bits)
   7.771     {
   7.772         T comp, newVal;
   7.773         do {
   7.774             comp   = this->Value;
   7.775             newVal = comp << bits;
   7.776         } while(!this->CompareAndSet_Sync(comp, newVal));
   7.777         return newVal;
   7.778     }
   7.779 };
   7.780 
   7.781 
   7.782 
   7.783 //-----------------------------------------------------------------------------------
   7.784 // ***** Lock
   7.785 
   7.786 // Lock is a simplest and most efficient mutual-exclusion lock class.
   7.787 // Unlike Mutex, it cannot be waited on.
   7.788 
   7.789 class Lock
   7.790 {
   7.791     // NOTE: Locks are not allocatable and they themselves should not allocate 
   7.792     // memory by standard means. This is the case because StandardAllocator
   7.793     // relies on this class.
   7.794     // Make 'delete' private. Don't do this for 'new' since it can be redefined.  
   7.795     void    operator delete(void*) {}
   7.796 
   7.797 
   7.798     // *** Lock implementation for various platforms.
   7.799     
   7.800 #if !defined(OVR_ENABLE_THREADS)
   7.801 
   7.802 public:
   7.803     // With no thread support, lock does nothing.
   7.804     inline Lock() { }
   7.805     inline Lock(unsigned) { }
   7.806     inline ~Lock() { }    
   7.807     inline void DoLock() { }
   7.808     inline void Unlock() { }
   7.809 
   7.810    // Windows.   
   7.811 #elif defined(OVR_OS_WIN32)
   7.812 
   7.813     CRITICAL_SECTION cs;
   7.814 public:   
   7.815     Lock(unsigned spinCount = 0);      
   7.816     ~Lock();
   7.817     // Locking functions.
   7.818     inline void DoLock()    { ::EnterCriticalSection(&cs); }
   7.819     inline void Unlock()    { ::LeaveCriticalSection(&cs); }
   7.820 
   7.821 #else
   7.822     pthread_mutex_t mutex;
   7.823 
   7.824 public:
   7.825     static pthread_mutexattr_t RecursiveAttr;
   7.826     static bool                RecursiveAttrInit;
   7.827 
   7.828     Lock (unsigned dummy = 0)
   7.829     {
   7.830         if (!RecursiveAttrInit)
   7.831         {
   7.832             pthread_mutexattr_init(&RecursiveAttr);
   7.833             pthread_mutexattr_settype(&RecursiveAttr, PTHREAD_MUTEX_RECURSIVE);
   7.834             RecursiveAttrInit = 1;
   7.835         }
   7.836         pthread_mutex_init(&mutex,&RecursiveAttr);
   7.837     }
   7.838     ~Lock ()                { pthread_mutex_destroy(&mutex); }
   7.839     inline void DoLock()    { pthread_mutex_lock(&mutex); }
   7.840     inline void Unlock()    { pthread_mutex_unlock(&mutex); }
   7.841 
   7.842 #endif // OVR_ENABLE_THREDS
   7.843 
   7.844 
   7.845 public:
   7.846     // Locker class, used for automatic locking
   7.847     class Locker
   7.848     {
   7.849     public:     
   7.850         Lock *pLock;
   7.851         inline Locker(Lock *plock)
   7.852         { pLock = plock; pLock->DoLock(); }
   7.853         inline ~Locker()
   7.854         { pLock->Unlock();  }
   7.855     };
   7.856 };
   7.857 
   7.858 
   7.859 
   7.860 } // OVR
   7.861 
   7.862 #endif
   7.863 \ No newline at end of file
   7.864 +/************************************************************************************
   7.865 +
   7.866 +PublicHeader:   OVR.h
   7.867 +Filename    :   OVR_Atomic.h
   7.868 +Content     :   Contains atomic operations and inline fastest locking
   7.869 +                functionality. Will contain #ifdefs for OS efficiency.
   7.870 +                Have non-thread-safe implementaion if not available.
   7.871 +Created     :   September 19, 2012
   7.872 +Notes       : 
   7.873 +
   7.874 +Copyright   :   Copyright 2012 Oculus VR, Inc. All Rights reserved.
   7.875 +
   7.876 +Use of this software is subject to the terms of the Oculus license
   7.877 +agreement provided at the time of installation or download, or which
   7.878 +otherwise accompanies this software in either electronic or hard copy form.
   7.879 +
   7.880 +************************************************************************************/
   7.881 +#ifndef OVR_Atomic_h
   7.882 +#define OVR_Atomic_h
   7.883 +
   7.884 +#include "OVR_Types.h"
   7.885 +
   7.886 +// Include System thread functionality.
   7.887 +#if defined(OVR_OS_WIN32)
   7.888 +#include <windows.h>
   7.889 +#else
   7.890 +#include <pthread.h>
   7.891 +#endif
   7.892 +
   7.893 +
   7.894 +namespace OVR {
   7.895 +
   7.896 +
   7.897 +// ****** Declared classes
   7.898 +
   7.899 +// If there is NO thread support we implement AtomicOps and
   7.900 +// Lock objects as no-ops. The other classes are not defined.
   7.901 +template<class C> class AtomicOps;
   7.902 +template<class T> class AtomicInt;
   7.903 +template<class T> class AtomicPtr;
   7.904 +
   7.905 +class   Lock;
   7.906 +
   7.907 +
   7.908 +//-----------------------------------------------------------------------------------
   7.909 +// ***** AtomicOps
   7.910 +
   7.911 +// Atomic operations are provided by the AtomicOps templates class,
   7.912 +// implemented through system-specific AtomicOpsRaw specializations.
   7.913 +// It provides several fundamental operations such as Exchange, ExchangeAdd
   7.914 +// CompareAndSet, and Store_Release. Each function includes several memory
   7.915 +// synchronization versions, important for multiprocessing CPUs with weak
   7.916 +// memory consistency. The following memory fencing strategies are supported:
   7.917 +//
   7.918 +//  - NoSync.  No memory synchronization is done for atomic op.
   7.919 +//  - Release. All other memory writes are completed before atomic op
   7.920 +//             writes its results.
   7.921 +//  - Acquire. Further memory reads are forced to wait until atomic op
   7.922 +//             executes, guaranteeing that the right values will be seen.
   7.923 +//  - Sync.    A combination of Release and Acquire.
   7.924 +
   7.925 +
   7.926 +// *** AtomicOpsRaw
   7.927 +
   7.928 +// AtomicOpsRaw is a specialized template that provides atomic operations 
   7.929 +// used by AtomicOps. This class has two fundamental qualities: (1) it
   7.930 +// defines a type T of correct size, and (2) provides operations that work
   7.931 +// atomically, such as Exchange_Sync and CompareAndSet_Release.
   7.932 +
   7.933 +// AtomicOpsRawBase class contains shared constants/classes for AtomicOpsRaw.
   7.934 +// The primary thing is does is define sync class objects, whose destructor and
   7.935 +// constructor provide places to insert appropriate synchronization calls, on 
   7.936 +// systems where such calls are necessary. So far, the breakdown is as follows:
   7.937 +// 
   7.938 +//  - X86 systems don't need custom syncs, since their exchange/atomic
   7.939 +//    instructions are implicitly synchronized.
   7.940 +//  - PowerPC requires lwsync/isync instructions that can use this mechanism.
   7.941 +//  - If some other systems require a mechanism where syncing type is associated
   7.942 +//    with a particular instruction, the default implementation (which implements
   7.943 +//    all Sync, Acquire, and Release modes in terms of NoSync and fence) may not
   7.944 +//    work. Ii that case it will need to be #ifdef-ed conditionally.
   7.945 +
   7.946 +struct AtomicOpsRawBase
   7.947 +{
   7.948 +#if !defined(OVR_ENABLE_THREADS) || defined(OVR_CPU_X86) || defined(OVR_OS_WIN32) || defined(OVR_OS_IPHONE)
   7.949 +    // Need to have empty constructor to avoid class 'unused' variable warning.
   7.950 +    struct FullSync { inline FullSync() { } };
   7.951 +    struct AcquireSync { inline AcquireSync() { } };
   7.952 +    struct ReleaseSync { inline ReleaseSync() { } };
   7.953 +
   7.954 +#elif defined(OVR_CPU_PPC64) || defined(OVR_CPU_PPC)
   7.955 +    struct FullSync { inline FullSync() { asm volatile("sync\n"); } ~FullSync() { asm volatile("isync\n"); } };
   7.956 +    struct AcquireSync { inline AcquireSync() { } ~AcquireSync() { asm volatile("isync\n"); } };
   7.957 +    struct ReleaseSync { inline ReleaseSync() { asm volatile("sync\n"); } };
   7.958 +
   7.959 +#elif defined(OVR_CPU_MIPS)
   7.960 +    struct FullSync { inline FullSync() { asm volatile("sync\n"); } ~FullSync() { asm volatile("sync\n"); } };
   7.961 +    struct AcquireSync { inline AcquireSync() { } ~AcquireSync() { asm volatile("sync\n"); } };
   7.962 +    struct ReleaseSync { inline ReleaseSync() { asm volatile("sync\n"); } };
   7.963 +
   7.964 +#elif defined(OVR_CPU_ARM)
   7.965 +    struct FullSync { inline FullSync() { asm volatile("dmb\n"); } ~FullSync() { asm volatile("dmb\n"); } };
   7.966 +    struct AcquireSync { inline AcquireSync() { } ~AcquireSync() { asm volatile("dmb\n"); } };
   7.967 +    struct ReleaseSync { inline ReleaseSync() { asm volatile("dmb\n"); } };
   7.968 +
   7.969 +
   7.970 +#elif defined(OVR_CC_GNU) && (__GNUC__ >= 4)
   7.971 +    // __sync functions are already full sync
   7.972 +    struct FullSync { inline FullSync() { } };
   7.973 +    struct AcquireSync { inline AcquireSync() { } };
   7.974 +    struct ReleaseSync { inline ReleaseSync() { } };
   7.975 +#endif
   7.976 +};
   7.977 +
   7.978 +
   7.979 +// 4-Byte raw data atomic op implementation class.
   7.980 +struct AtomicOpsRaw_4ByteImpl : public AtomicOpsRawBase
   7.981 +{
   7.982 +#if !defined(OVR_ENABLE_THREADS)
   7.983 +
   7.984 +    // Provide a type for no-thread-support cases. Used by AtomicOpsRaw_DefImpl.
   7.985 +    typedef UInt32 T;   
   7.986 +
   7.987 +    // *** Thread - Safe Atomic Versions.
   7.988 +
   7.989 +#elif defined(OVR_OS_WIN32)
   7.990 +
   7.991 +    // Use special defined for VC6, where volatile is not used and
   7.992 +    // InterlockedCompareExchange is declared incorrectly.
   7.993 +    typedef LONG T;      
   7.994 +#if defined(OVR_CC_MSVC) && (OVR_CC_MSVC < 1300)
   7.995 +    typedef T* InterlockTPtr;
   7.996 +    typedef LPVOID ET;
   7.997 +    typedef ET* InterlockETPtr;
   7.998 +#else
   7.999 +    typedef volatile T* InterlockTPtr;
  7.1000 +    typedef T ET;
  7.1001 +    typedef InterlockTPtr InterlockETPtr;
  7.1002 +#endif
  7.1003 +    inline static T     Exchange_NoSync(volatile T* p, T val)            { return InterlockedExchange((InterlockTPtr)p, val); }
  7.1004 +    inline static T     ExchangeAdd_NoSync(volatile T* p, T val)         { return InterlockedExchangeAdd((InterlockTPtr)p, val); }
  7.1005 +    inline static bool  CompareAndSet_NoSync(volatile T* p, T c, T val)  { return InterlockedCompareExchange((InterlockETPtr)p, (ET)val, (ET)c) == (ET)c; }
  7.1006 +
  7.1007 +#elif defined(OVR_CPU_PPC64) || defined(OVR_CPU_PPC)
  7.1008 +    typedef UInt32 T;
  7.1009 +    static inline UInt32   Exchange_NoSync(volatile UInt32 *i, UInt32 j)
  7.1010 +    {
  7.1011 +        UInt32 ret;
  7.1012 +
  7.1013 +        asm volatile("1:\n\t"
  7.1014 +                     "lwarx  %[r],0,%[i]\n\t"
  7.1015 +                     "stwcx. %[j],0,%[i]\n\t"
  7.1016 +                     "bne-   1b\n"
  7.1017 +                     : "+m" (*i), [r] "=&b" (ret) : [i] "b" (i), [j] "b" (j) : "cc", "memory");
  7.1018 +
  7.1019 +        return ret;
  7.1020 +    }
  7.1021 +
  7.1022 +    static inline UInt32   ExchangeAdd_NoSync(volatile UInt32 *i, UInt32 j)
  7.1023 +    {
  7.1024 +        UInt32 dummy, ret;
  7.1025 +
  7.1026 +        asm volatile("1:\n\t"
  7.1027 +                     "lwarx  %[r],0,%[i]\n\t"
  7.1028 +                     "add    %[o],%[r],%[j]\n\t"
  7.1029 +                     "stwcx. %[o],0,%[i]\n\t"
  7.1030 +                     "bne-   1b\n"
  7.1031 +                     : "+m" (*i), [r] "=&b" (ret), [o] "=&r" (dummy) : [i] "b" (i), [j] "b" (j) : "cc", "memory");
  7.1032 +
  7.1033 +        return ret;
  7.1034 +    }
  7.1035 +
  7.1036 +    static inline bool     CompareAndSet_NoSync(volatile UInt32 *i, UInt32 c, UInt32 value)
  7.1037 +    {
  7.1038 +        UInt32 ret;
  7.1039 +
  7.1040 +        asm volatile("1:\n\t"
  7.1041 +                     "lwarx  %[r],0,%[i]\n\t"
  7.1042 +                     "cmpw   0,%[r],%[cmp]\n\t"
  7.1043 +                     "mfcr   %[r]\n\t"
  7.1044 +                     "bne-   2f\n\t"
  7.1045 +                     "stwcx. %[val],0,%[i]\n\t"
  7.1046 +                     "bne-   1b\n\t"
  7.1047 +                     "2:\n"
  7.1048 +                     : "+m" (*i), [r] "=&b" (ret) : [i] "b" (i), [cmp] "b" (c), [val] "b" (value) : "cc", "memory");
  7.1049 +
  7.1050 +        return (ret & 0x20000000) ? 1 : 0;
  7.1051 +    }
  7.1052 +
  7.1053 +#elif defined(OVR_CPU_MIPS)
  7.1054 +    typedef UInt32 T;
  7.1055 +
  7.1056 +    static inline UInt32   Exchange_NoSync(volatile UInt32 *i, UInt32 j)
  7.1057 +    {
  7.1058 +        UInt32 ret;
  7.1059 +
  7.1060 +        asm volatile("1:\n\t"
  7.1061 +                     "ll     %[r],0(%[i])\n\t"
  7.1062 +                     "sc     %[j],0(%[i])\n\t"
  7.1063 +                     "beq    %[j],$0,1b\n\t"
  7.1064 +                     "nop    \n"
  7.1065 +                     : "+m" (*i), [r] "=&d" (ret) : [i] "d" (i), [j] "d" (j) : "cc", "memory");
  7.1066 +
  7.1067 +        return ret;
  7.1068 +    }
  7.1069 +
  7.1070 +    static inline UInt32   ExchangeAdd_NoSync(volatile UInt32 *i, UInt32 j)
  7.1071 +    {
  7.1072 +        UInt32 ret;
  7.1073 +
  7.1074 +        asm volatile("1:\n\t"
  7.1075 +                     "ll     %[r],0(%[i])\n\t"
  7.1076 +                     "addu   %[j],%[r],%[j]\n\t"
  7.1077 +                     "sc     %[j],0(%[i])\n\t"
  7.1078 +                     "beq    %[j],$0,1b\n\t"
  7.1079 +                     "nop    \n"
  7.1080 +                     : "+m" (*i), [r] "=&d" (ret) : [i] "d" (i), [j] "d" (j) : "cc", "memory");
  7.1081 +
  7.1082 +        return ret;
  7.1083 +    }
  7.1084 +
  7.1085 +    static inline bool     CompareAndSet_NoSync(volatile UInt32 *i, UInt32 c, UInt32 value)
  7.1086 +    {
  7.1087 +        UInt32 ret, dummy;
  7.1088 +
  7.1089 +        asm volatile("1:\n\t"
  7.1090 +                     "move   %[r],$0\n\t"
  7.1091 +                     "ll     %[o],0(%[i])\n\t"
  7.1092 +                     "bne    %[o],%[c],2f\n\t"
  7.1093 +                     "move   %[r],%[v]\n\t"
  7.1094 +                     "sc     %[r],0(%[i])\n\t"
  7.1095 +                     "beq    %[r],$0,1b\n\t"
  7.1096 +                     "nop    \n\t"
  7.1097 +                     "2:\n"
  7.1098 +                     : "+m" (*i),[r] "=&d" (ret), [o] "=&d" (dummy) : [i] "d" (i), [c] "d" (c), [v] "d" (value)
  7.1099 +                     : "cc", "memory");
  7.1100 +
  7.1101 +        return ret;
  7.1102 +    }
  7.1103 +
  7.1104 +#elif defined(OVR_CPU_ARM) && defined(OVR_CC_ARM)
  7.1105 +    typedef UInt32 T;
  7.1106 +
  7.1107 +    static inline UInt32   Exchange_NoSync(volatile UInt32 *i, UInt32 j)
  7.1108 +    {
  7.1109 +        for(;;)
  7.1110 +        {
  7.1111 +            T r = __ldrex(i);
  7.1112 +            if (__strex(j, i) == 0)
  7.1113 +                return r;
  7.1114 +        }
  7.1115 +    }
  7.1116 +    static inline UInt32   ExchangeAdd_NoSync(volatile UInt32 *i, UInt32 j)
  7.1117 +    {
  7.1118 +        for(;;)
  7.1119 +        {
  7.1120 +            T r = __ldrex(i);
  7.1121 +            if (__strex(r + j, i) == 0)
  7.1122 +                return r;
  7.1123 +        }
  7.1124 +    }
  7.1125 +
  7.1126 +    static inline bool     CompareAndSet_NoSync(volatile UInt32 *i, UInt32 c, UInt32 value)
  7.1127 +    {
  7.1128 +        for(;;)
  7.1129 +        {
  7.1130 +            T r = __ldrex(i);
  7.1131 +            if (r != c)
  7.1132 +                return 0;
  7.1133 +            if (__strex(value, i) == 0)
  7.1134 +                return 1;
  7.1135 +        }
  7.1136 +    }
  7.1137 +
  7.1138 +#elif defined(OVR_CPU_ARM)
  7.1139 +    typedef UInt32 T;
  7.1140 +
  7.1141 +    static inline UInt32   Exchange_NoSync(volatile UInt32 *i, UInt32 j)
  7.1142 +    {
  7.1143 +        UInt32 ret, dummy;
  7.1144 +
  7.1145 +        asm volatile("1:\n\t"
  7.1146 +            "ldrex  %[r],[%[i]]\n\t"
  7.1147 +            "strex  %[t],%[j],[%[i]]\n\t"
  7.1148 +            "cmp    %[t],#0\n\t"
  7.1149 +            "bne    1b\n\t"
  7.1150 +            : "+m" (*i), [r] "=&r" (ret), [t] "=&r" (dummy) : [i] "r" (i), [j] "r" (j) : "cc", "memory");
  7.1151 +
  7.1152 +        return ret;
  7.1153 +    }
  7.1154 +
  7.1155 +    static inline UInt32   ExchangeAdd_NoSync(volatile UInt32 *i, UInt32 j)
  7.1156 +    {
  7.1157 +        UInt32 ret, dummy, test;
  7.1158 +
  7.1159 +        asm volatile("1:\n\t"
  7.1160 +            "ldrex  %[r],[%[i]]\n\t"
  7.1161 +            "add    %[o],%[r],%[j]\n\t"
  7.1162 +            "strex  %[t],%[o],[%[i]]\n\t"
  7.1163 +            "cmp    %[t],#0\n\t"
  7.1164 +            "bne    1b\n\t"
  7.1165 +            : "+m" (*i), [r] "=&r" (ret), [o] "=&r" (dummy), [t] "=&r" (test)  : [i] "r" (i), [j] "r" (j) : "cc", "memory");
  7.1166 +
  7.1167 +        return ret;
  7.1168 +    }
  7.1169 +
  7.1170 +    static inline bool     CompareAndSet_NoSync(volatile UInt32 *i, UInt32 c, UInt32 value)
  7.1171 +    {
  7.1172 +        UInt32 ret = 1, dummy, test;
  7.1173 +
  7.1174 +        asm volatile("1:\n\t"
  7.1175 +            "ldrex  %[o],[%[i]]\n\t"
  7.1176 +            "cmp    %[o],%[c]\n\t"
  7.1177 +            "bne    2f\n\t"
  7.1178 +            "strex  %[r],%[v],[%[i]]\n\t"
  7.1179 +            "cmp    %[r],#0\n\t"
  7.1180 +            "bne    1b\n\t"
  7.1181 +            "2:\n"
  7.1182 +            : "+m" (*i),[r] "=&r" (ret), [o] "=&r" (dummy), [t] "=&r" (test) : [i] "r" (i), [c] "r" (c), [v] "r" (value)
  7.1183 +            : "cc", "memory");
  7.1184 +
  7.1185 +        return !ret;
  7.1186 +    }
  7.1187 +
  7.1188 +#elif defined(OVR_CPU_X86)
  7.1189 +    typedef UInt32 T;
  7.1190 +
  7.1191 +    static inline UInt32   Exchange_NoSync(volatile UInt32 *i, UInt32 j)
  7.1192 +    {
  7.1193 +        asm volatile("xchgl %1,%[i]\n"
  7.1194 +                     : "+m" (*i), "=q" (j) : [i] "m" (*i), "1" (j) : "cc", "memory");
  7.1195 +
  7.1196 +        return j;
  7.1197 +    }
  7.1198 +
  7.1199 +    static inline UInt32   ExchangeAdd_NoSync(volatile UInt32 *i, UInt32 j)
  7.1200 +    {
  7.1201 +        asm volatile("lock; xaddl %1,%[i]\n"
  7.1202 +                     : "+m" (*i), "+q" (j) : [i] "m" (*i) : "cc", "memory");
  7.1203 +
  7.1204 +        return j;
  7.1205 +    }
  7.1206 +
  7.1207 +    static inline bool     CompareAndSet_NoSync(volatile UInt32 *i, UInt32 c, UInt32 value)
  7.1208 +    {
  7.1209 +        UInt32 ret;
  7.1210 +
  7.1211 +        asm volatile("lock; cmpxchgl %[v],%[i]\n"
  7.1212 +                     : "+m" (*i), "=a" (ret) : [i] "m" (*i), "1" (c), [v] "q" (value) : "cc", "memory");
  7.1213 +
  7.1214 +        return (ret == c);
  7.1215 +    }
  7.1216 +
  7.1217 +#elif defined(OVR_CC_GNU) && (__GNUC__ >= 4 && __GNUC_MINOR__ >= 1)
  7.1218 +
  7.1219 +    typedef UInt32 T;
  7.1220 +
  7.1221 +    static inline T   Exchange_NoSync(volatile T *i, T j)
  7.1222 +    {
  7.1223 +        T v;
  7.1224 +        do {
  7.1225 +            v = *i;
  7.1226 +        } while (!__sync_bool_compare_and_swap(i, v, j));
  7.1227 +        return v;
  7.1228 +    }
  7.1229 +
  7.1230 +    static inline T   ExchangeAdd_NoSync(volatile T *i, T j)
  7.1231 +    {
  7.1232 +        return __sync_fetch_and_add(i, j);
  7.1233 +    }
  7.1234 +
  7.1235 +    static inline bool     CompareAndSet_NoSync(volatile T *i, T c, T value)
  7.1236 +    {
  7.1237 +        return __sync_bool_compare_and_swap(i, c, value);
  7.1238 +    }
  7.1239 +
  7.1240 +#endif // OS
  7.1241 +};
  7.1242 +
  7.1243 +
  7.1244 +// 8-Byte raw data data atomic op implementation class.
  7.1245 +// Currently implementation is provided only on systems with 64-bit pointers.
  7.1246 +struct AtomicOpsRaw_8ByteImpl : public AtomicOpsRawBase
  7.1247 +{    
  7.1248 +#if !defined(OVR_64BIT_POINTERS) || !defined(OVR_ENABLE_THREADS)
  7.1249 +
  7.1250 +    // Provide a type for no-thread-support cases. Used by AtomicOpsRaw_DefImpl.
  7.1251 +    typedef UInt64 T;
  7.1252 +
  7.1253 +    // *** Thread - Safe OS specific versions.
  7.1254 +#elif defined(OVR_OS_WIN32)
  7.1255 +
  7.1256 +    // This is only for 64-bit systems.
  7.1257 +    typedef LONG64      T;
  7.1258 +    typedef volatile T* InterlockTPtr;    
  7.1259 +    inline static T     Exchange_NoSync(volatile T* p, T val)            { return InterlockedExchange64((InterlockTPtr)p, val); }
  7.1260 +    inline static T     ExchangeAdd_NoSync(volatile T* p, T val)         { return InterlockedExchangeAdd64((InterlockTPtr)p, val); }
  7.1261 +    inline static bool  CompareAndSet_NoSync(volatile T* p, T c, T val)  { return InterlockedCompareExchange64((InterlockTPtr)p, val, c) == c; }
  7.1262 +
  7.1263 +#elif defined(OVR_CPU_PPC64)
  7.1264 + 
  7.1265 +    typedef UInt64 T;
  7.1266 +
  7.1267 +    static inline UInt64   Exchange_NoSync(volatile UInt64 *i, UInt64 j)
  7.1268 +    {
  7.1269 +        UInt64 dummy, ret;
  7.1270 +
  7.1271 +        asm volatile("1:\n\t"
  7.1272 +                     "ldarx  %[r],0,%[i]\n\t"
  7.1273 +                     "mr     %[o],%[j]\n\t"
  7.1274 +                     "stdcx. %[o],0,%[i]\n\t"
  7.1275 +                     "bne-   1b\n"
  7.1276 +                     : "+m" (*i), [r] "=&b" (ret), [o] "=&r" (dummy) : [i] "b" (i), [j] "b" (j) : "cc");
  7.1277 +
  7.1278 +        return ret;
  7.1279 +    }
  7.1280 +
  7.1281 +    static inline UInt64   ExchangeAdd_NoSync(volatile UInt64 *i, UInt64 j)
  7.1282 +    {
  7.1283 +        UInt64 dummy, ret;
  7.1284 +
  7.1285 +        asm volatile("1:\n\t"
  7.1286 +                     "ldarx  %[r],0,%[i]\n\t"
  7.1287 +                     "add    %[o],%[r],%[j]\n\t"
  7.1288 +                     "stdcx. %[o],0,%[i]\n\t"
  7.1289 +                     "bne-   1b\n"
  7.1290 +                     : "+m" (*i), [r] "=&b" (ret), [o] "=&r" (dummy) : [i] "b" (i), [j] "b" (j) : "cc");
  7.1291 +
  7.1292 +        return ret;
  7.1293 +    }
  7.1294 +
  7.1295 +    static inline bool     CompareAndSet_NoSync(volatile UInt64 *i, UInt64 c, UInt64 value)
  7.1296 +    {
  7.1297 +        UInt64 ret, dummy;
  7.1298 +
  7.1299 +        asm volatile("1:\n\t"
  7.1300 +                     "ldarx  %[r],0,%[i]\n\t"
  7.1301 +                     "cmpw   0,%[r],%[cmp]\n\t"
  7.1302 +                     "mfcr   %[r]\n\t"
  7.1303 +                     "bne-   2f\n\t"
  7.1304 +                     "stdcx. %[val],0,%[i]\n\t"
  7.1305 +                     "bne-   1b\n\t"
  7.1306 +                     "2:\n"
  7.1307 +                     : "+m" (*i), [r] "=&b" (ret), [o] "=&r" (dummy) : [i] "b" (i), [cmp] "b" (c), [val] "b" (value) : "cc");
  7.1308 +
  7.1309 +        return (ret & 0x20000000) ? 1 : 0;
  7.1310 +    }
  7.1311 +
  7.1312 +#elif defined(OVR_CC_GNU) && (__GNUC__ >= 4 && __GNUC_MINOR__ >= 1)
  7.1313 +
  7.1314 +    typedef UInt64 T;
  7.1315 +
  7.1316 +    static inline T   Exchange_NoSync(volatile T *i, T j)
  7.1317 +    {
  7.1318 +        T v;
  7.1319 +        do {
  7.1320 +            v = *i;
  7.1321 +        } while (!__sync_bool_compare_and_swap(i, v, j));
  7.1322 +        return v;
  7.1323 +    }
  7.1324 +
  7.1325 +    static inline T   ExchangeAdd_NoSync(volatile T *i, T j)
  7.1326 +    {
  7.1327 +        return __sync_fetch_and_add(i, j);
  7.1328 +    }
  7.1329 +
  7.1330 +    static inline bool     CompareAndSet_NoSync(volatile T *i, T c, T value)
  7.1331 +    {
  7.1332 +        return __sync_bool_compare_and_swap(i, c, value);
  7.1333 +    }
  7.1334 +
  7.1335 +#endif // OS
  7.1336 +};
  7.1337 +
  7.1338 +
  7.1339 +// Default implementation for AtomicOpsRaw; provides implementation of mem-fenced
  7.1340 +// atomic operations where fencing is done with a sync object wrapped around a NoSync
  7.1341 +// operation implemented in the base class. If such implementation is not possible
  7.1342 +// on a given platform, #ifdefs can be used to disable it and then op functions can be
  7.1343 +// implemented individually in the appropriate AtomicOpsRaw<size> class.
  7.1344 +
  7.1345 +template<class O>
  7.1346 +struct AtomicOpsRaw_DefImpl : public O
  7.1347 +{
  7.1348 +    typedef typename O::T O_T;
  7.1349 +    typedef typename O::FullSync    O_FullSync;
  7.1350 +    typedef typename O::AcquireSync O_AcquireSync;
  7.1351 +    typedef typename O::ReleaseSync O_ReleaseSync;
  7.1352 +
  7.1353 +    // If there is no thread support, provide the default implementation. In this case,
  7.1354 +    // the base class (0) must still provide the T declaration.
  7.1355 +#ifndef OVR_ENABLE_THREADS
  7.1356 +
  7.1357 +    // Atomic exchange of val with argument. Returns old val.
  7.1358 +    inline static O_T   Exchange_NoSync(volatile O_T* p, O_T val)           { O_T old = *p; *p = val; return old; }
  7.1359 +    // Adds a new val to argument; returns its old val.
  7.1360 +    inline static O_T   ExchangeAdd_NoSync(volatile O_T* p, O_T val)        { O_T old = *p; *p += val; return old; }
  7.1361 +    // Compares the argument data with 'c' val.
  7.1362 +    // If succeeded, stores val int '*p' and returns true; otherwise returns false.
  7.1363 +    inline static bool  CompareAndSet_NoSync(volatile O_T* p, O_T c, O_T val) { if (*p==c) { *p = val; return 1; } return 0; }
  7.1364 +
  7.1365 +#endif
  7.1366 +
  7.1367 +    // If NoSync wrapped implementation may not be possible, it this block should be
  7.1368 +    //  replaced with per-function implementation in O.
  7.1369 +    // "AtomicOpsRaw_DefImpl<O>::" prefix in calls below.
  7.1370 +    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); }
  7.1371 +    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); }
  7.1372 +    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); }  
  7.1373 +    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); }
  7.1374 +    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); }
  7.1375 +    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); }
  7.1376 +    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); }
  7.1377 +    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); }
  7.1378 +    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); }
  7.1379 +
  7.1380 +    // Loads and stores with memory fence. These have only the relevant versions.
  7.1381 +#ifdef OVR_CPU_X86
  7.1382 +    // On X86, Store_Release is implemented as exchange. Note that we can also
  7.1383 +    // consider 'sfence' in the future, although it is not as compatible with older CPUs.
  7.1384 +    inline static void  Store_Release(volatile O_T* p, O_T val)  { Exchange_Release(p, val); }
  7.1385 +#else
  7.1386 +    inline static void  Store_Release(volatile O_T* p, O_T val)  { O_ReleaseSync sync; OVR_UNUSED(sync); *p = val; }
  7.1387 +#endif
  7.1388 +    inline static O_T   Load_Acquire(const volatile O_T* p)      { O_AcquireSync sync; OVR_UNUSED(sync); return *p; }
  7.1389 +};
  7.1390 +
  7.1391 +
  7.1392 +template<int size>
  7.1393 +struct AtomicOpsRaw : public AtomicOpsRawBase { };
  7.1394 +
  7.1395 +template<>
  7.1396 +struct AtomicOpsRaw<4> : public AtomicOpsRaw_DefImpl<AtomicOpsRaw_4ByteImpl>
  7.1397 +{   
  7.1398 +    // Ensure that assigned type size is correct.
  7.1399 +    AtomicOpsRaw()
  7.1400 +    { OVR_COMPILER_ASSERT(sizeof(AtomicOpsRaw_DefImpl<AtomicOpsRaw_4ByteImpl>::T) == 4); }
  7.1401 +};
  7.1402 +template<>
  7.1403 +struct AtomicOpsRaw<8> : public AtomicOpsRaw_DefImpl<AtomicOpsRaw_8ByteImpl>
  7.1404 +{
  7.1405 +    AtomicOpsRaw()
  7.1406 +    { OVR_COMPILER_ASSERT(sizeof(AtomicOpsRaw_DefImpl<AtomicOpsRaw_8ByteImpl>::T) == 8); }
  7.1407 +};
  7.1408 +
  7.1409 +
  7.1410 +// *** AtomicOps - implementation of atomic Ops for specified class
  7.1411 +
  7.1412 +// Implements atomic ops on a class, provided that the object is either
  7.1413 +// 4 or 8 bytes in size (depending on the AtomicOpsRaw specializations
  7.1414 +// available). Relies on AtomicOpsRaw for much of implementation.
  7.1415 +
  7.1416 +template<class C>
  7.1417 +class AtomicOps
  7.1418 +{
  7.1419 +    typedef AtomicOpsRaw<sizeof(C)>       Ops;
  7.1420 +    typedef typename Ops::T               T;
  7.1421 +    typedef volatile typename Ops::T*     PT;
  7.1422 +    // We cast through unions to (1) avoid pointer size compiler warnings
  7.1423 +    // and (2) ensure that there are no problems with strict pointer aliasing.
  7.1424 +    union C2T_union { C c; T t; };
  7.1425 +
  7.1426 +public:
  7.1427 +    // General purpose implementation for standard syncs.    
  7.1428 +    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; }
  7.1429 +    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; }
  7.1430 +    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; }
  7.1431 +    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; }
  7.1432 +    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; }
  7.1433 +    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; }
  7.1434 +    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; }
  7.1435 +    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; }
  7.1436 +    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); }
  7.1437 +    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); }
  7.1438 +    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); }
  7.1439 +    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); }
  7.1440 +    // Loads and stores with memory fence. These have only the relevant versions.    
  7.1441 +    inline static void  Store_Release(volatile C* p, C val)             { C2T_union u; u.c = val; Ops::Store_Release((PT)p, u.t); }    
  7.1442 +    inline static C     Load_Acquire(const volatile C* p)               { C2T_union u; u.t = Ops::Load_Acquire((PT)p); return u.c; }
  7.1443 +};
  7.1444 +
  7.1445 +
  7.1446 +
  7.1447 +// Atomic value base class - implements operations shared for integers and pointers.
  7.1448 +template<class T>
  7.1449 +class AtomicValueBase
  7.1450 +{
  7.1451 +protected:
  7.1452 +    typedef AtomicOps<T> Ops;
  7.1453 +public:
  7.1454 +
  7.1455 +    volatile T  Value;
  7.1456 +
  7.1457 +    inline AtomicValueBase()                  { }
  7.1458 +    explicit inline AtomicValueBase(T val)    { Ops::Store_Release(&Value, val); }
  7.1459 +
  7.1460 +    // Most libraries (TBB and Joshua Scholar's) library do not do Load_Acquire
  7.1461 +    // here, since most algorithms do not require atomic loads. Needs some research.    
  7.1462 +    inline operator T() const { return Value; }
  7.1463 +
  7.1464 +    // *** Standard Atomic inlines
  7.1465 +    inline T     Exchange_Sync(T val)               { return Ops::Exchange_Sync(&Value,  val); }
  7.1466 +    inline T     Exchange_Release(T val)            { return Ops::Exchange_Release(&Value, val); }
  7.1467 +    inline T     Exchange_Acquire(T val)            { return Ops::Exchange_Acquire(&Value, val); }
  7.1468 +    inline T     Exchange_NoSync(T val)             { return Ops::Exchange_NoSync(&Value, val); }
  7.1469 +    inline bool  CompareAndSet_Sync(T c, T val)     { return Ops::CompareAndSet_Sync(&Value, c, val); }
  7.1470 +    inline bool  CompareAndSet_Release(T c, T val)  { return Ops::CompareAndSet_Release(&Value, c, val); }
  7.1471 +    inline bool  CompareAndSet_Acquire(T c, T val)  { return Ops::CompareAndSet_Relse(&Value, c, val); }
  7.1472 +    inline bool  CompareAndSet_NoSync(T c, T val)   { return Ops::CompareAndSet_NoSync(&Value, c, val); }
  7.1473 +    // Load & Store.
  7.1474 +    inline void  Store_Release(T val)               { Ops::Store_Release(&Value, val); }
  7.1475 +    inline T     Load_Acquire() const               { return Ops::Load_Acquire(&Value);  }
  7.1476 +};
  7.1477 +
  7.1478 +
  7.1479 +// ***** AtomicPtr - Atomic pointer template
  7.1480 +
  7.1481 +// This pointer class supports atomic assignments with release,
  7.1482 +// increment / decrement operations, and conditional compare + set.
  7.1483 +
  7.1484 +template<class T>
  7.1485 +class AtomicPtr : public AtomicValueBase<T*>
  7.1486 +{
  7.1487 +    typedef typename AtomicValueBase<T*>::Ops Ops;
  7.1488 +
  7.1489 +public:
  7.1490 +    // Initialize pointer value to 0 by default; use Store_Release only with explicit constructor.
  7.1491 +    inline AtomicPtr() : AtomicValueBase<T*>()                     { this->Value = 0; }
  7.1492 +    explicit inline AtomicPtr(T* val) : AtomicValueBase<T*>(val)   { }
  7.1493 +        
  7.1494 +    // Pointer access.
  7.1495 +    inline T* operator -> () const     { return this->Load_Acquire(); }
  7.1496 +
  7.1497 +    // It looks like it is convenient to have Load_Acquire characteristics
  7.1498 +    // for this, since that is convenient for algorithms such as linked
  7.1499 +    // list traversals that can be added to bu another thread.
  7.1500 +    inline operator T* () const        { return this->Load_Acquire(); }
  7.1501 +
  7.1502 +
  7.1503 +    // *** Standard Atomic inlines (applicable to pointers)
  7.1504 +
  7.1505 +    // ExhangeAdd considers pointer size for pointers.
  7.1506 +    template<class I>
  7.1507 +    inline T*     ExchangeAdd_Sync(I incr)      { return Ops::ExchangeAdd_Sync(&this->Value, ((T*)0) + incr); }
  7.1508 +    template<class I>
  7.1509 +    inline T*     ExchangeAdd_Release(I incr)   { return Ops::ExchangeAdd_Release(&this->Value, ((T*)0) + incr); }
  7.1510 +    template<class I>
  7.1511 +    inline T*     ExchangeAdd_Acquire(I incr)   { return Ops::ExchangeAdd_Acquire(&this->Value, ((T*)0) + incr); }
  7.1512 +    template<class I>
  7.1513 +    inline T*     ExchangeAdd_NoSync(I incr)    { return Ops::ExchangeAdd_NoSync(&this->Value, ((T*)0) + incr); }
  7.1514 +
  7.1515 +    // *** Atomic Operators
  7.1516 +
  7.1517 +    inline T* operator = (T* val)  { this->Store_Release(val); return val; }
  7.1518 +
  7.1519 +    template<class I>
  7.1520 +    inline T* operator += (I val) { return ExchangeAdd_Sync(val) + val; }
  7.1521 +    template<class I>
  7.1522 +    inline T* operator -= (I val) { return operator += (-val); }
  7.1523 +
  7.1524 +    inline T* operator ++ ()      { return ExchangeAdd_Sync(1) + 1; }
  7.1525 +    inline T* operator -- ()      { return ExchangeAdd_Sync(-1) - 1; }
  7.1526 +    inline T* operator ++ (int)   { return ExchangeAdd_Sync(1); }
  7.1527 +    inline T* operator -- (int)   { return ExchangeAdd_Sync(-1); }
  7.1528 +};
  7.1529 +
  7.1530 +
  7.1531 +// ***** AtomicInt - Atomic integer template
  7.1532 +
  7.1533 +// Implements an atomic integer type; the exact type to use is provided 
  7.1534 +// as an argument. Supports atomic Acquire / Release semantics, atomic
  7.1535 +// arithmetic operations, and atomic conditional compare + set.
  7.1536 +
  7.1537 +template<class T>
  7.1538 +class AtomicInt : public AtomicValueBase<T>
  7.1539 +{
  7.1540 +    typedef typename AtomicValueBase<T>::Ops Ops;
  7.1541 +
  7.1542 +public:
  7.1543 +    inline AtomicInt() : AtomicValueBase<T>()                     { }
  7.1544 +    explicit inline AtomicInt(T val) : AtomicValueBase<T>(val)    { }
  7.1545 +
  7.1546 +
  7.1547 +    // *** Standard Atomic inlines (applicable to int)   
  7.1548 +    inline T     ExchangeAdd_Sync(T val)            { return Ops::ExchangeAdd_Sync(&this->Value, val); }
  7.1549 +    inline T     ExchangeAdd_Release(T val)         { return Ops::ExchangeAdd_Release(&this->Value, val); }
  7.1550 +    inline T     ExchangeAdd_Acquire(T val)         { return Ops::ExchangeAdd_Acquire(&this->Value, val); }
  7.1551 +    inline T     ExchangeAdd_NoSync(T val)          { return Ops::ExchangeAdd_NoSync(&this->Value, val); }
  7.1552 +    // These increments could be more efficient because they don't return a value.
  7.1553 +    inline void  Increment_Sync()                   { ExchangeAdd_Sync((T)1); }
  7.1554 +    inline void  Increment_Release()                { ExchangeAdd_Release((T)1); }
  7.1555 +    inline void  Increment_Acquire()                { ExchangeAdd_Acquire((T)1); }    
  7.1556 +    inline void  Increment_NoSync()                 { ExchangeAdd_NoSync((T)1); }
  7.1557 +
  7.1558 +    // *** Atomic Operators
  7.1559 +
  7.1560 +    inline T operator = (T val)  { this->Store_Release(val); return val; }
  7.1561 +    inline T operator += (T val) { return ExchangeAdd_Sync(val) + val; }
  7.1562 +    inline T operator -= (T val) { return ExchangeAdd_Sync(0 - val) - val; }
  7.1563 +
  7.1564 +    inline T operator ++ ()      { return ExchangeAdd_Sync((T)1) + 1; }
  7.1565 +    inline T operator -- ()      { return ExchangeAdd_Sync(((T)0)-1) - 1; }
  7.1566 +    inline T operator ++ (int)   { return ExchangeAdd_Sync((T)1); }
  7.1567 +    inline T operator -- (int)   { return ExchangeAdd_Sync(((T)0)-1); }
  7.1568 +
  7.1569 +    // More complex atomic operations. Leave it to compiler whether to optimize them or not.
  7.1570 +    T operator &= (T arg)
  7.1571 +    {
  7.1572 +        T comp, newVal;
  7.1573 +        do {
  7.1574 +            comp   = this->Value;
  7.1575 +            newVal = comp & arg;
  7.1576 +        } while(!this->CompareAndSet_Sync(comp, newVal));
  7.1577 +        return newVal;
  7.1578 +    }
  7.1579 +
  7.1580 +    T operator |= (T arg)
  7.1581 +    {
  7.1582 +        T comp, newVal;
  7.1583 +        do {
  7.1584 +            comp   = this->Value;
  7.1585 +            newVal = comp | arg;
  7.1586 +        } while(!this->CompareAndSet_Sync(comp, newVal));
  7.1587 +        return newVal;
  7.1588 +    }
  7.1589 +
  7.1590 +    T operator ^= (T arg)
  7.1591 +    {
  7.1592 +        T comp, newVal;
  7.1593 +        do {
  7.1594 +            comp   = this->Value;
  7.1595 +            newVal = comp ^ arg;
  7.1596 +        } while(!this->CompareAndSet_Sync(comp, newVal));
  7.1597 +        return newVal;
  7.1598 +    }
  7.1599 +
  7.1600 +    T operator *= (T arg)
  7.1601 +    {
  7.1602 +        T comp, newVal;
  7.1603 +        do {
  7.1604 +            comp   = this->Value;
  7.1605 +            newVal = comp * arg;
  7.1606 +        } while(!this->CompareAndSet_Sync(comp, newVal));
  7.1607 +        return newVal;
  7.1608 +    }
  7.1609 +
  7.1610 +    T operator /= (T arg)
  7.1611 +    {
  7.1612 +        T comp, newVal;
  7.1613 +        do {
  7.1614 +            comp   = this->Value;
  7.1615 +            newVal = comp / arg;
  7.1616 +        } while(!CompareAndSet_Sync(comp, newVal));
  7.1617 +        return newVal;
  7.1618 +    }
  7.1619 +
  7.1620 +    T operator >>= (unsigned bits)
  7.1621 +    {
  7.1622 +        T comp, newVal;
  7.1623 +        do {
  7.1624 +            comp   = this->Value;
  7.1625 +            newVal = comp >> bits;
  7.1626 +        } while(!CompareAndSet_Sync(comp, newVal));
  7.1627 +        return newVal;
  7.1628 +    }
  7.1629 +
  7.1630 +    T operator <<= (unsigned bits)
  7.1631 +    {
  7.1632 +        T comp, newVal;
  7.1633 +        do {
  7.1634 +            comp   = this->Value;
  7.1635 +            newVal = comp << bits;
  7.1636 +        } while(!this->CompareAndSet_Sync(comp, newVal));
  7.1637 +        return newVal;
  7.1638 +    }
  7.1639 +};
  7.1640 +
  7.1641 +
  7.1642 +
  7.1643 +//-----------------------------------------------------------------------------------
  7.1644 +// ***** Lock
  7.1645 +
  7.1646 +// Lock is a simplest and most efficient mutual-exclusion lock class.
  7.1647 +// Unlike Mutex, it cannot be waited on.
  7.1648 +
  7.1649 +class Lock
  7.1650 +{
  7.1651 +    // NOTE: Locks are not allocatable and they themselves should not allocate 
  7.1652 +    // memory by standard means. This is the case because StandardAllocator
  7.1653 +    // relies on this class.
  7.1654 +    // Make 'delete' private. Don't do this for 'new' since it can be redefined.  
  7.1655 +    void    operator delete(void*) {}
  7.1656 +
  7.1657 +
  7.1658 +    // *** Lock implementation for various platforms.
  7.1659 +    
  7.1660 +#if !defined(OVR_ENABLE_THREADS)
  7.1661 +
  7.1662 +public:
  7.1663 +    // With no thread support, lock does nothing.
  7.1664 +    inline Lock() { }
  7.1665 +    inline Lock(unsigned) { }
  7.1666 +    inline ~Lock() { }    
  7.1667 +    inline void DoLock() { }
  7.1668 +    inline void Unlock() { }
  7.1669 +
  7.1670 +   // Windows.   
  7.1671 +#elif defined(OVR_OS_WIN32)
  7.1672 +
  7.1673 +    CRITICAL_SECTION cs;
  7.1674 +public:   
  7.1675 +    Lock(unsigned spinCount = 0);      
  7.1676 +    ~Lock();
  7.1677 +    // Locking functions.
  7.1678 +    inline void DoLock()    { ::EnterCriticalSection(&cs); }
  7.1679 +    inline void Unlock()    { ::LeaveCriticalSection(&cs); }
  7.1680 +
  7.1681 +#else
  7.1682 +    pthread_mutex_t mutex;
  7.1683 +
  7.1684 +public:
  7.1685 +    static pthread_mutexattr_t RecursiveAttr;
  7.1686 +    static bool                RecursiveAttrInit;
  7.1687 +
  7.1688 +    Lock (unsigned dummy = 0)
  7.1689 +    {
  7.1690 +        if (!RecursiveAttrInit)
  7.1691 +        {
  7.1692 +            pthread_mutexattr_init(&RecursiveAttr);
  7.1693 +            pthread_mutexattr_settype(&RecursiveAttr, PTHREAD_MUTEX_RECURSIVE);
  7.1694 +            RecursiveAttrInit = 1;
  7.1695 +        }
  7.1696 +        pthread_mutex_init(&mutex,&RecursiveAttr);
  7.1697 +    }
  7.1698 +    ~Lock ()                { pthread_mutex_destroy(&mutex); }
  7.1699 +    inline void DoLock()    { pthread_mutex_lock(&mutex); }
  7.1700 +    inline void Unlock()    { pthread_mutex_unlock(&mutex); }
  7.1701 +
  7.1702 +#endif // OVR_ENABLE_THREDS
  7.1703 +
  7.1704 +
  7.1705 +public:
  7.1706 +    // Locker class, used for automatic locking
  7.1707 +    class Locker
  7.1708 +    {
  7.1709 +    public:     
  7.1710 +        Lock *pLock;
  7.1711 +        inline Locker(Lock *plock)
  7.1712 +        { pLock = plock; pLock->DoLock(); }
  7.1713 +        inline ~Locker()
  7.1714 +        { pLock->Unlock();  }
  7.1715 +    };
  7.1716 +};
  7.1717 +
  7.1718 +
  7.1719 +
  7.1720 +} // OVR
  7.1721 +
  7.1722 +#endif
     8.1 --- a/libovr/Src/Kernel/OVR_Color.h	Sat Sep 14 17:51:03 2013 +0300
     8.2 +++ b/libovr/Src/Kernel/OVR_Color.h	Sun Sep 15 04:10:05 2013 +0300
     8.3 @@ -1,1 +1,55 @@
     8.4 -/************************************************************************************
     8.5 
     8.6 PublicHeader:   OVR.h
     8.7 Filename    :   OVR_Color.h
     8.8 Content     :   Contains color struct.
     8.9 Created     :   February 7, 2013
    8.10 Notes       : 
    8.11 
    8.12 Copyright   :   Copyright 2013 Oculus VR, Inc. All Rights reserved.
    8.13 
    8.14 Use of this software is subject to the terms of the Oculus license
    8.15 agreement provided at the time of installation or download, or which
    8.16 otherwise accompanies this software in either electronic or hard copy form.
    8.17 
    8.18 ************************************************************************************/
    8.19 #ifndef OVR_Color_h
    8.20 #define OVR_Color_h
    8.21 
    8.22 #include "OVR_Types.h"
    8.23 
    8.24 namespace OVR {
    8.25 
    8.26 struct Color
    8.27 {
    8.28     UByte R,G,B,A;
    8.29 
    8.30     Color() {}
    8.31 
    8.32     // Constructs color by channel. Alpha is set to 0xFF (fully visible)
    8.33     // if not specified.
    8.34     Color(unsigned char r,unsigned char g,unsigned char b, unsigned char a = 0xFF)
    8.35         : R(r), G(g), B(b), A(a) { }
    8.36 
    8.37     // 0xAARRGGBB - Common HTML color Hex layout
    8.38     Color(unsigned c)
    8.39         : R((unsigned char)(c>>16)), G((unsigned char)(c>>8)),
    8.40         B((unsigned char)c), A((unsigned char)(c>>24)) { }
    8.41 
    8.42     bool operator==(const Color& b) const
    8.43     {
    8.44         return R == b.R && G == b.G && B == b.B && A == b.A;
    8.45     }
    8.46 
    8.47     void  GetRGBA(float *r, float *g, float *b, float* a) const
    8.48     {
    8.49         *r = R / 255.0f;
    8.50         *g = G / 255.0f;
    8.51         *b = B / 255.0f;
    8.52         *a = A / 255.0f;
    8.53     }
    8.54 };
    8.55 
    8.56 }
    8.57 
    8.58 #endif
    8.59 \ No newline at end of file
    8.60 +/************************************************************************************
    8.61 +
    8.62 +PublicHeader:   OVR.h
    8.63 +Filename    :   OVR_Color.h
    8.64 +Content     :   Contains color struct.
    8.65 +Created     :   February 7, 2013
    8.66 +Notes       : 
    8.67 +
    8.68 +Copyright   :   Copyright 2013 Oculus VR, Inc. All Rights reserved.
    8.69 +
    8.70 +Use of this software is subject to the terms of the Oculus license
    8.71 +agreement provided at the time of installation or download, or which
    8.72 +otherwise accompanies this software in either electronic or hard copy form.
    8.73 +
    8.74 +************************************************************************************/
    8.75 +#ifndef OVR_Color_h
    8.76 +#define OVR_Color_h
    8.77 +
    8.78 +#include "OVR_Types.h"
    8.79 +
    8.80 +namespace OVR {
    8.81 +
    8.82 +struct Color
    8.83 +{
    8.84 +    UByte R,G,B,A;
    8.85 +
    8.86 +    Color() {}
    8.87 +
    8.88 +    // Constructs color by channel. Alpha is set to 0xFF (fully visible)
    8.89 +    // if not specified.
    8.90 +    Color(unsigned char r,unsigned char g,unsigned char b, unsigned char a = 0xFF)
    8.91 +        : R(r), G(g), B(b), A(a) { }
    8.92 +
    8.93 +    // 0xAARRGGBB - Common HTML color Hex layout
    8.94 +    Color(unsigned c)
    8.95 +        : R((unsigned char)(c>>16)), G((unsigned char)(c>>8)),
    8.96 +        B((unsigned char)c), A((unsigned char)(c>>24)) { }
    8.97 +
    8.98 +    bool operator==(const Color& b) const
    8.99 +    {
   8.100 +        return R == b.R && G == b.G && B == b.B && A == b.A;
   8.101 +    }
   8.102 +
   8.103 +    void  GetRGBA(float *r, float *g, float *b, float* a) const
   8.104 +    {
   8.105 +        *r = R / 255.0f;
   8.106 +        *g = G / 255.0f;
   8.107 +        *b = B / 255.0f;
   8.108 +        *a = A / 255.0f;
   8.109 +    }
   8.110 +};
   8.111 +
   8.112 +}
   8.113 +
   8.114 +#endif
     9.1 --- a/libovr/Src/Kernel/OVR_ContainerAllocator.h	Sat Sep 14 17:51:03 2013 +0300
     9.2 +++ b/libovr/Src/Kernel/OVR_ContainerAllocator.h	Sun Sep 15 04:10:05 2013 +0300
     9.3 @@ -1,1 +1,256 @@
     9.4 -/************************************************************************************
     9.5 
     9.6 PublicHeader:   OVR.h
     9.7 Filename    :   OVR_ContainerAllocator.h
     9.8 Content     :   Template allocators and constructors for containers.
     9.9 Created     :   September 19, 2012
    9.10 Notes       : 
    9.11 
    9.12 Copyright   :   Copyright 2012 Oculus VR, Inc. All Rights reserved.
    9.13 
    9.14 Use of this software is subject to the terms of the Oculus license
    9.15 agreement provided at the time of installation or download, or which
    9.16 otherwise accompanies this software in either electronic or hard copy form.
    9.17 
    9.18 ************************************************************************************/
    9.19 
    9.20 #ifndef OVR_ContainerAllocator_h
    9.21 #define OVR_ContainerAllocator_h
    9.22 
    9.23 #include "OVR_Allocator.h"
    9.24 #include <string.h>
    9.25 
    9.26 
    9.27 namespace OVR {
    9.28 
    9.29 
    9.30 //-----------------------------------------------------------------------------------
    9.31 // ***** Container Allocator
    9.32 
    9.33 // ContainerAllocator serves as a template argument for allocations done by
    9.34 // containers, such as Array and Hash; replacing it could allow allocator
    9.35 // substitution in containers.
    9.36 
    9.37 class ContainerAllocatorBase
    9.38 {
    9.39 public:
    9.40     static void* Alloc(UPInt size)                { return OVR_ALLOC(size); }
    9.41     static void* Realloc(void* p, UPInt newSize)  { return OVR_REALLOC(p, newSize); }
    9.42     static void  Free(void *p)                    { OVR_FREE(p); }
    9.43 };
    9.44 
    9.45 
    9.46 
    9.47 //-----------------------------------------------------------------------------------
    9.48 // ***** Constructors, Destructors, Copiers
    9.49 
    9.50 // Plain Old Data - movable, no special constructors/destructor.
    9.51 template<class T> 
    9.52 class ConstructorPOD
    9.53 {
    9.54 public:
    9.55     static void Construct(void *) {}
    9.56     static void Construct(void *p, const T& source) 
    9.57     { 
    9.58         *(T*)p = source;
    9.59     }
    9.60 
    9.61     // Same as above, but allows for a different type of constructor.
    9.62     template <class S> 
    9.63     static void ConstructAlt(void *p, const S& source)
    9.64     {
    9.65         *(T*)p = source;
    9.66     }
    9.67 
    9.68     static void ConstructArray(void*, UPInt) {}
    9.69 
    9.70     static void ConstructArray(void* p, UPInt count, const T& source)
    9.71     {
    9.72         UByte *pdata = (UByte*)p;
    9.73         for (UPInt i=0; i< count; ++i, pdata += sizeof(T))
    9.74             *(T*)pdata = source;
    9.75     }
    9.76 
    9.77     static void ConstructArray(void* p, UPInt count, const T* psource)
    9.78     {
    9.79         memcpy(p, psource, sizeof(T) * count);
    9.80     }
    9.81 
    9.82     static void Destruct(T*) {}
    9.83     static void DestructArray(T*, UPInt) {}
    9.84 
    9.85     static void CopyArrayForward(T* dst, const T* src, UPInt count)
    9.86     {
    9.87         memmove(dst, src, count * sizeof(T));
    9.88     }
    9.89 
    9.90     static void CopyArrayBackward(T* dst, const T* src, UPInt count)
    9.91     {
    9.92         memmove(dst, src, count * sizeof(T));
    9.93     }
    9.94 
    9.95     static bool IsMovable() { return true; }
    9.96 };
    9.97 
    9.98 
    9.99 //-----------------------------------------------------------------------------------
   9.100 // ***** ConstructorMov
   9.101 //
   9.102 // Correct C++ construction and destruction for movable objects
   9.103 template<class T> 
   9.104 class ConstructorMov
   9.105 {
   9.106 public:
   9.107     static void Construct(void* p) 
   9.108     { 
   9.109         OVR::Construct<T>(p);
   9.110     }
   9.111 
   9.112     static void Construct(void* p, const T& source) 
   9.113     { 
   9.114         OVR::Construct<T>(p, source);
   9.115     }
   9.116 
   9.117     // Same as above, but allows for a different type of constructor.
   9.118     template <class S> 
   9.119     static void ConstructAlt(void* p, const S& source)
   9.120     {
   9.121         OVR::ConstructAlt<T,S>(p, source);
   9.122     }
   9.123 
   9.124     static void ConstructArray(void* p, UPInt count)
   9.125     {
   9.126         UByte* pdata = (UByte*)p;
   9.127         for (UPInt i=0; i< count; ++i, pdata += sizeof(T))
   9.128             Construct(pdata);
   9.129     }
   9.130 
   9.131     static void ConstructArray(void* p, UPInt count, const T& source)
   9.132     {
   9.133         UByte* pdata = (UByte*)p;
   9.134         for (UPInt i=0; i< count; ++i, pdata += sizeof(T))
   9.135             Construct(pdata, source);
   9.136     }
   9.137 
   9.138     static void ConstructArray(void* p, UPInt count, const T* psource)
   9.139     {
   9.140         UByte* pdata = (UByte*)p;
   9.141         for (UPInt i=0; i< count; ++i, pdata += sizeof(T))
   9.142             Construct(pdata, *psource++);
   9.143     }
   9.144 
   9.145     static void Destruct(T* p)
   9.146     {
   9.147         p->~T();
   9.148         OVR_UNUSED(p); // Suppress silly MSVC warning
   9.149     }
   9.150 
   9.151     static void DestructArray(T* p, UPInt count)
   9.152     {   
   9.153         p += count - 1;
   9.154         for (UPInt i=0; i<count; ++i, --p)
   9.155             p->~T();
   9.156     }
   9.157 
   9.158     static void CopyArrayForward(T* dst, const T* src, UPInt count)
   9.159     {
   9.160         memmove(dst, src, count * sizeof(T));
   9.161     }
   9.162 
   9.163     static void CopyArrayBackward(T* dst, const T* src, UPInt count)
   9.164     {
   9.165         memmove(dst, src, count * sizeof(T));
   9.166     }
   9.167 
   9.168     static bool IsMovable() { return true; }
   9.169 };
   9.170 
   9.171 
   9.172 //-----------------------------------------------------------------------------------
   9.173 // ***** ConstructorCPP
   9.174 //
   9.175 // Correct C++ construction and destruction for movable objects
   9.176 template<class T> 
   9.177 class ConstructorCPP
   9.178 {
   9.179 public:
   9.180     static void Construct(void* p) 
   9.181     { 
   9.182         OVR::Construct<T>(p);        
   9.183     }
   9.184 
   9.185     static void Construct(void* p, const T& source) 
   9.186     { 
   9.187         OVR::Construct<T>(p, source);        
   9.188     }
   9.189 
   9.190     // Same as above, but allows for a different type of constructor.
   9.191     template <class S> 
   9.192     static void ConstructAlt(void* p, const S& source)
   9.193     {
   9.194         OVR::ConstructAlt<T,S>(p, source);        
   9.195     }
   9.196 
   9.197     static void ConstructArray(void* p, UPInt count)
   9.198     {
   9.199         UByte* pdata = (UByte*)p;
   9.200         for (UPInt i=0; i< count; ++i, pdata += sizeof(T))
   9.201             Construct(pdata);
   9.202     }
   9.203 
   9.204     static void ConstructArray(void* p, UPInt count, const T& source)
   9.205     {
   9.206         UByte* pdata = (UByte*)p;
   9.207         for (UPInt i=0; i< count; ++i, pdata += sizeof(T))
   9.208             Construct(pdata, source);
   9.209     }
   9.210 
   9.211     static void ConstructArray(void* p, UPInt count, const T* psource)
   9.212     {
   9.213         UByte* pdata = (UByte*)p;
   9.214         for (UPInt i=0; i< count; ++i, pdata += sizeof(T))
   9.215             Construct(pdata, *psource++);
   9.216     }
   9.217 
   9.218     static void Destruct(T* p)
   9.219     {
   9.220         p->~T();
   9.221         OVR_UNUSED(p); // Suppress silly MSVC warning
   9.222     }
   9.223 
   9.224     static void DestructArray(T* p, UPInt count)
   9.225     {   
   9.226         p += count - 1;
   9.227         for (UPInt i=0; i<count; ++i, --p)
   9.228             p->~T();
   9.229     }
   9.230 
   9.231     static void CopyArrayForward(T* dst, const T* src, UPInt count)
   9.232     {
   9.233         for(UPInt i = 0; i < count; ++i)
   9.234             dst[i] = src[i];
   9.235     }
   9.236 
   9.237     static void CopyArrayBackward(T* dst, const T* src, UPInt count)
   9.238     {
   9.239         for(UPInt i = count; i; --i)
   9.240             dst[i-1] = src[i-1];
   9.241     }
   9.242 
   9.243     static bool IsMovable() { return false; }
   9.244 };
   9.245 
   9.246 
   9.247 //-----------------------------------------------------------------------------------
   9.248 // ***** Container Allocator with movement policy
   9.249 //
   9.250 // Simple wraps as specialized allocators
   9.251 template<class T> struct ContainerAllocator_POD : ContainerAllocatorBase, ConstructorPOD<T> {};
   9.252 template<class T> struct ContainerAllocator     : ContainerAllocatorBase, ConstructorMov<T> {};
   9.253 template<class T> struct ContainerAllocator_CPP : ContainerAllocatorBase, ConstructorCPP<T> {};
   9.254 
   9.255 
   9.256 } // OVR
   9.257 
   9.258 
   9.259 #endif
   9.260 \ No newline at end of file
   9.261 +/************************************************************************************
   9.262 +
   9.263 +PublicHeader:   OVR.h
   9.264 +Filename    :   OVR_ContainerAllocator.h
   9.265 +Content     :   Template allocators and constructors for containers.
   9.266 +Created     :   September 19, 2012
   9.267 +Notes       : 
   9.268 +
   9.269 +Copyright   :   Copyright 2012 Oculus VR, Inc. All Rights reserved.
   9.270 +
   9.271 +Use of this software is subject to the terms of the Oculus license
   9.272 +agreement provided at the time of installation or download, or which
   9.273 +otherwise accompanies this software in either electronic or hard copy form.
   9.274 +
   9.275 +************************************************************************************/
   9.276 +
   9.277 +#ifndef OVR_ContainerAllocator_h
   9.278 +#define OVR_ContainerAllocator_h
   9.279 +
   9.280 +#include "OVR_Allocator.h"
   9.281 +#include <string.h>
   9.282 +
   9.283 +
   9.284 +namespace OVR {
   9.285 +
   9.286 +
   9.287 +//-----------------------------------------------------------------------------------
   9.288 +// ***** Container Allocator
   9.289 +
   9.290 +// ContainerAllocator serves as a template argument for allocations done by
   9.291 +// containers, such as Array and Hash; replacing it could allow allocator
   9.292 +// substitution in containers.
   9.293 +
   9.294 +class ContainerAllocatorBase
   9.295 +{
   9.296 +public:
   9.297 +    static void* Alloc(UPInt size)                { return OVR_ALLOC(size); }
   9.298 +    static void* Realloc(void* p, UPInt newSize)  { return OVR_REALLOC(p, newSize); }
   9.299 +    static void  Free(void *p)                    { OVR_FREE(p); }
   9.300 +};
   9.301 +
   9.302 +
   9.303 +
   9.304 +//-----------------------------------------------------------------------------------
   9.305 +// ***** Constructors, Destructors, Copiers
   9.306 +
   9.307 +// Plain Old Data - movable, no special constructors/destructor.
   9.308 +template<class T> 
   9.309 +class ConstructorPOD
   9.310 +{
   9.311 +public:
   9.312 +    static void Construct(void *) {}
   9.313 +    static void Construct(void *p, const T& source) 
   9.314 +    { 
   9.315 +        *(T*)p = source;
   9.316 +    }
   9.317 +
   9.318 +    // Same as above, but allows for a different type of constructor.
   9.319 +    template <class S> 
   9.320 +    static void ConstructAlt(void *p, const S& source)
   9.321 +    {
   9.322 +        *(T*)p = source;
   9.323 +    }
   9.324 +
   9.325 +    static void ConstructArray(void*, UPInt) {}
   9.326 +
   9.327 +    static void ConstructArray(void* p, UPInt count, const T& source)
   9.328 +    {
   9.329 +        UByte *pdata = (UByte*)p;
   9.330 +        for (UPInt i=0; i< count; ++i, pdata += sizeof(T))
   9.331 +            *(T*)pdata = source;
   9.332 +    }
   9.333 +
   9.334 +    static void ConstructArray(void* p, UPInt count, const T* psource)
   9.335 +    {
   9.336 +        memcpy(p, psource, sizeof(T) * count);
   9.337 +    }
   9.338 +
   9.339 +    static void Destruct(T*) {}
   9.340 +    static void DestructArray(T*, UPInt) {}
   9.341 +
   9.342 +    static void CopyArrayForward(T* dst, const T* src, UPInt count)
   9.343 +    {
   9.344 +        memmove(dst, src, count * sizeof(T));
   9.345 +    }
   9.346 +
   9.347 +    static void CopyArrayBackward(T* dst, const T* src, UPInt count)
   9.348 +    {
   9.349 +        memmove(dst, src, count * sizeof(T));
   9.350 +    }
   9.351 +
   9.352 +    static bool IsMovable() { return true; }
   9.353 +};
   9.354 +
   9.355 +
   9.356 +//-----------------------------------------------------------------------------------
   9.357 +// ***** ConstructorMov
   9.358 +//
   9.359 +// Correct C++ construction and destruction for movable objects
   9.360 +template<class T> 
   9.361 +class ConstructorMov
   9.362 +{
   9.363 +public:
   9.364 +    static void Construct(void* p) 
   9.365 +    { 
   9.366 +        OVR::Construct<T>(p);
   9.367 +    }
   9.368 +
   9.369 +    static void Construct(void* p, const T& source) 
   9.370 +    { 
   9.371 +        OVR::Construct<T>(p, source);
   9.372 +    }
   9.373 +
   9.374 +    // Same as above, but allows for a different type of constructor.
   9.375 +    template <class S> 
   9.376 +    static void ConstructAlt(void* p, const S& source)
   9.377 +    {
   9.378 +        OVR::ConstructAlt<T,S>(p, source);
   9.379 +    }
   9.380 +
   9.381 +    static void ConstructArray(void* p, UPInt count)
   9.382 +    {
   9.383 +        UByte* pdata = (UByte*)p;
   9.384 +        for (UPInt i=0; i< count; ++i, pdata += sizeof(T))
   9.385 +            Construct(pdata);
   9.386 +    }
   9.387 +
   9.388 +    static void ConstructArray(void* p, UPInt count, const T& source)
   9.389 +    {
   9.390 +        UByte* pdata = (UByte*)p;
   9.391 +        for (UPInt i=0; i< count; ++i, pdata += sizeof(T))
   9.392 +            Construct(pdata, source);
   9.393 +    }
   9.394 +
   9.395 +    static void ConstructArray(void* p, UPInt count, const T* psource)
   9.396 +    {
   9.397 +        UByte* pdata = (UByte*)p;
   9.398 +        for (UPInt i=0; i< count; ++i, pdata += sizeof(T))
   9.399 +            Construct(pdata, *psource++);
   9.400 +    }
   9.401 +
   9.402 +    static void Destruct(T* p)
   9.403 +    {
   9.404 +        p->~T();
   9.405 +        OVR_UNUSED(p); // Suppress silly MSVC warning
   9.406 +    }
   9.407 +
   9.408 +    static void DestructArray(T* p, UPInt count)
   9.409 +    {   
   9.410 +        p += count - 1;
   9.411 +        for (UPInt i=0; i<count; ++i, --p)
   9.412 +            p->~T();
   9.413 +    }
   9.414 +
   9.415 +    static void CopyArrayForward(T* dst, const T* src, UPInt count)
   9.416 +    {
   9.417 +        memmove(dst, src, count * sizeof(T));
   9.418 +    }
   9.419 +
   9.420 +    static void CopyArrayBackward(T* dst, const T* src, UPInt count)
   9.421 +    {
   9.422 +        memmove(dst, src, count * sizeof(T));
   9.423 +    }
   9.424 +
   9.425 +    static bool IsMovable() { return true; }
   9.426 +};
   9.427 +
   9.428 +
   9.429 +//-----------------------------------------------------------------------------------
   9.430 +// ***** ConstructorCPP
   9.431 +//
   9.432 +// Correct C++ construction and destruction for movable objects
   9.433 +template<class T> 
   9.434 +class ConstructorCPP
   9.435 +{
   9.436 +public:
   9.437 +    static void Construct(void* p) 
   9.438 +    { 
   9.439 +        OVR::Construct<T>(p);        
   9.440 +    }
   9.441 +
   9.442 +    static void Construct(void* p, const T& source) 
   9.443 +    { 
   9.444 +        OVR::Construct<T>(p, source);        
   9.445 +    }
   9.446 +
   9.447 +    // Same as above, but allows for a different type of constructor.
   9.448 +    template <class S> 
   9.449 +    static void ConstructAlt(void* p, const S& source)
   9.450 +    {
   9.451 +        OVR::ConstructAlt<T,S>(p, source);        
   9.452 +    }
   9.453 +
   9.454 +    static void ConstructArray(void* p, UPInt count)
   9.455 +    {
   9.456 +        UByte* pdata = (UByte*)p;
   9.457 +        for (UPInt i=0; i< count; ++i, pdata += sizeof(T))
   9.458 +            Construct(pdata);
   9.459 +    }
   9.460 +
   9.461 +    static void ConstructArray(void* p, UPInt count, const T& source)
   9.462 +    {
   9.463 +        UByte* pdata = (UByte*)p;
   9.464 +        for (UPInt i=0; i< count; ++i, pdata += sizeof(T))
   9.465 +            Construct(pdata, source);
   9.466 +    }
   9.467 +
   9.468 +    static void ConstructArray(void* p, UPInt count, const T* psource)
   9.469 +    {
   9.470 +        UByte* pdata = (UByte*)p;
   9.471 +        for (UPInt i=0; i< count; ++i, pdata += sizeof(T))
   9.472 +            Construct(pdata, *psource++);
   9.473 +    }
   9.474 +
   9.475 +    static void Destruct(T* p)
   9.476 +    {
   9.477 +        p->~T();
   9.478 +        OVR_UNUSED(p); // Suppress silly MSVC warning
   9.479 +    }
   9.480 +
   9.481 +    static void DestructArray(T* p, UPInt count)
   9.482 +    {   
   9.483 +        p += count - 1;
   9.484 +        for (UPInt i=0; i<count; ++i, --p)
   9.485 +            p->~T();
   9.486 +    }
   9.487 +
   9.488 +    static void CopyArrayForward(T* dst, const T* src, UPInt count)
   9.489 +    {
   9.490 +        for(UPInt i = 0; i < count; ++i)
   9.491 +            dst[i] = src[i];
   9.492 +    }
   9.493 +
   9.494 +    static void CopyArrayBackward(T* dst, const T* src, UPInt count)
   9.495 +    {
   9.496 +        for(UPInt i = count; i; --i)
   9.497 +            dst[i-1] = src[i-1];
   9.498 +    }
   9.499 +
   9.500 +    static bool IsMovable() { return false; }
   9.501 +};
   9.502 +
   9.503 +
   9.504 +//-----------------------------------------------------------------------------------
   9.505 +// ***** Container Allocator with movement policy
   9.506 +//
   9.507 +// Simple wraps as specialized allocators
   9.508 +template<class T> struct ContainerAllocator_POD : ContainerAllocatorBase, ConstructorPOD<T> {};
   9.509 +template<class T> struct ContainerAllocator     : ContainerAllocatorBase, ConstructorMov<T> {};
   9.510 +template<class T> struct ContainerAllocator_CPP : ContainerAllocatorBase, ConstructorCPP<T> {};
   9.511 +
   9.512 +
   9.513 +} // OVR
   9.514 +
   9.515 +
   9.516 +#endif
    10.1 --- a/libovr/Src/Kernel/OVR_File.cpp	Sat Sep 14 17:51:03 2013 +0300
    10.2 +++ b/libovr/Src/Kernel/OVR_File.cpp	Sun Sep 15 04:10:05 2013 +0300
    10.3 @@ -1,1 +1,571 @@
    10.4 -/**************************************************************************
    10.5 
    10.6 Filename    :   OVR_File.cpp
    10.7 Content     :   File wrapper class implementation (Win32)
    10.8 
    10.9 Created     :   April 5, 1999
   10.10 Authors     :   Michael Antonov
   10.11 
   10.12 Copyright   :   Copyright 2012 Oculus VR, Inc. All Rights reserved.
   10.13 
   10.14 Use of this software is subject to the terms of the Oculus license
   10.15 agreement provided at the time of installation or download, or which
   10.16 otherwise accompanies this software in either electronic or hard copy form.
   10.17 
   10.18 **************************************************************************/
   10.19 
   10.20 #define  GFILE_CXX
   10.21 
   10.22 // Standard C library (Captain Obvious guarantees!)
   10.23 #include <stdio.h>
   10.24 
   10.25 #include "OVR_File.h"
   10.26 
   10.27 namespace OVR {
   10.28 
   10.29 // Buffered file adds buffering to an existing file
   10.30 // FILEBUFFER_SIZE defines the size of internal buffer, while
   10.31 // FILEBUFFER_TOLERANCE controls the amount of data we'll effectively try to buffer
   10.32 #define FILEBUFFER_SIZE         (8192-8)
   10.33 #define FILEBUFFER_TOLERANCE    4096
   10.34 
   10.35 // ** Constructor/Destructor
   10.36 
   10.37 // Hidden constructor
   10.38 // Not supposed to be used
   10.39 BufferedFile::BufferedFile() : DelegatedFile(0)
   10.40 {
   10.41     pBuffer     = (UByte*)OVR_ALLOC(FILEBUFFER_SIZE);
   10.42     BufferMode  = NoBuffer;
   10.43     FilePos     = 0;
   10.44     Pos         = 0;
   10.45     DataSize    = 0;
   10.46 }
   10.47 
   10.48 // Takes another file as source
   10.49 BufferedFile::BufferedFile(File *pfile) : DelegatedFile(pfile)
   10.50 {
   10.51     pBuffer     = (UByte*)OVR_ALLOC(FILEBUFFER_SIZE);
   10.52     BufferMode  = NoBuffer;
   10.53     FilePos     = pfile->LTell();
   10.54     Pos         = 0;
   10.55     DataSize    = 0;
   10.56 }
   10.57 
   10.58 
   10.59 // Destructor
   10.60 BufferedFile::~BufferedFile()
   10.61 {
   10.62     // Flush in case there's data
   10.63     if (pFile)
   10.64         FlushBuffer();
   10.65     // Get rid of buffer
   10.66     if (pBuffer)
   10.67         OVR_FREE(pBuffer);
   10.68 }
   10.69 
   10.70 /*
   10.71 bool    BufferedFile::VCopy(const Object &source)
   10.72 {
   10.73     if (!DelegatedFile::VCopy(source))
   10.74         return 0;
   10.75 
   10.76     // Data members
   10.77     BufferedFile *psource = (BufferedFile*)&source;
   10.78 
   10.79     // Buffer & the mode it's in
   10.80     pBuffer         = psource->pBuffer;
   10.81     BufferMode      = psource->BufferMode;
   10.82     Pos             = psource->Pos;
   10.83     DataSize        = psource->DataSize;
   10.84     return 1;
   10.85 }
   10.86 */
   10.87 
   10.88 // Initializes buffering to a certain mode
   10.89 bool    BufferedFile::SetBufferMode(BufferModeType mode)
   10.90 {
   10.91     if (!pBuffer)
   10.92         return false;
   10.93     if (mode == BufferMode)
   10.94         return true;
   10.95      
   10.96     FlushBuffer();
   10.97 
   10.98     // Can't set write mode if we can't write
   10.99     if ((mode==WriteBuffer) && (!pFile || !pFile->IsWritable()) )
  10.100         return 0;
  10.101 
  10.102     // And SetMode
  10.103     BufferMode = mode;
  10.104     Pos        = 0;
  10.105     DataSize   = 0;
  10.106     return 1;
  10.107 }
  10.108 
  10.109 // Flushes buffer
  10.110 void    BufferedFile::FlushBuffer()
  10.111 {
  10.112     switch(BufferMode)
  10.113     {
  10.114         case WriteBuffer:
  10.115             // Write data in buffer
  10.116             FilePos += pFile->Write(pBuffer,Pos);
  10.117             Pos = 0;
  10.118             break;
  10.119 
  10.120         case ReadBuffer:
  10.121             // Seek back & reset buffer data
  10.122             if ((DataSize-Pos)>0)
  10.123                 FilePos = pFile->LSeek(-(int)(DataSize-Pos), Seek_Cur);
  10.124             DataSize = 0;
  10.125             Pos      = 0;
  10.126             break;
  10.127         default:
  10.128             // not handled!
  10.129             break;
  10.130     }
  10.131 }
  10.132 
  10.133 // Reloads data for ReadBuffer
  10.134 void    BufferedFile::LoadBuffer()
  10.135 {
  10.136     if (BufferMode == ReadBuffer)
  10.137     {
  10.138         // We should only reload once all of pre-loaded buffer is consumed.
  10.139         OVR_ASSERT(Pos == DataSize);
  10.140 
  10.141         // WARNING: Right now LoadBuffer() assumes the buffer's empty
  10.142         int sz   = pFile->Read(pBuffer,FILEBUFFER_SIZE);
  10.143         DataSize = sz<0 ? 0 : (unsigned)sz;
  10.144         Pos      = 0;
  10.145         FilePos  += DataSize;
  10.146     }
  10.147 }
  10.148 
  10.149 
  10.150 // ** Overridden functions
  10.151 
  10.152 // We override all the functions that can possibly
  10.153 // require buffer mode switch, flush, or extra calculations
  10.154 
  10.155 // Tell() requires buffer adjustment
  10.156 int     BufferedFile::Tell()
  10.157 {
  10.158     if (BufferMode == ReadBuffer)
  10.159         return int (FilePos - DataSize + Pos);
  10.160 
  10.161     int pos = pFile->Tell();
  10.162     // Adjust position based on buffer mode & data
  10.163     if (pos!=-1)
  10.164     {
  10.165         OVR_ASSERT(BufferMode != ReadBuffer);
  10.166         if (BufferMode == WriteBuffer)
  10.167             pos += Pos;
  10.168     }
  10.169     return pos;
  10.170 }
  10.171 
  10.172 SInt64  BufferedFile::LTell()
  10.173 {
  10.174     if (BufferMode == ReadBuffer)
  10.175         return FilePos - DataSize + Pos;
  10.176 
  10.177     SInt64 pos = pFile->LTell();
  10.178     if (pos!=-1)
  10.179     {
  10.180         OVR_ASSERT(BufferMode != ReadBuffer);
  10.181         if (BufferMode == WriteBuffer)
  10.182             pos += Pos;
  10.183     }
  10.184     return pos;
  10.185 }
  10.186 
  10.187 int     BufferedFile::GetLength()
  10.188 {
  10.189     int len = pFile->GetLength();
  10.190     // If writing through buffer, file length may actually be bigger
  10.191     if ((len!=-1) && (BufferMode==WriteBuffer))
  10.192     {
  10.193         int currPos = pFile->Tell() + Pos;
  10.194         if (currPos>len)
  10.195             len = currPos;
  10.196     }
  10.197     return len;
  10.198 }
  10.199 SInt64  BufferedFile::LGetLength()
  10.200 {
  10.201     SInt64 len = pFile->LGetLength();
  10.202     // If writing through buffer, file length may actually be bigger
  10.203     if ((len!=-1) && (BufferMode==WriteBuffer))
  10.204     {
  10.205         SInt64 currPos = pFile->LTell() + Pos;
  10.206         if (currPos>len)
  10.207             len = currPos;
  10.208     }
  10.209     return len;
  10.210 }
  10.211 
  10.212 /*
  10.213 bool    BufferedFile::Stat(FileStats *pfs)
  10.214 {
  10.215     // Have to fix up length is stat
  10.216     if (pFile->Stat(pfs))
  10.217     {
  10.218         if (BufferMode==WriteBuffer)
  10.219         {
  10.220             SInt64 currPos = pFile->LTell() + Pos;
  10.221             if (currPos > pfs->Size)
  10.222             {
  10.223                 pfs->Size   = currPos;
  10.224                 // ??
  10.225                 pfs->Blocks = (pfs->Size+511) >> 9;
  10.226             }
  10.227         }
  10.228         return 1;
  10.229     }
  10.230     return 0;
  10.231 }
  10.232 */
  10.233 
  10.234 int     BufferedFile::Write(const UByte *psourceBuffer, int numBytes)
  10.235 {
  10.236     if ( (BufferMode==WriteBuffer) || SetBufferMode(WriteBuffer))
  10.237     {
  10.238         // If not data space in buffer, flush
  10.239         if ((FILEBUFFER_SIZE-(int)Pos)<numBytes)
  10.240         {
  10.241             FlushBuffer();
  10.242             // If bigger then tolerance, just write directly
  10.243             if (numBytes>FILEBUFFER_TOLERANCE)
  10.244             {
  10.245                 int sz = pFile->Write(psourceBuffer,numBytes);
  10.246                 if (sz > 0)
  10.247                     FilePos += sz;
  10.248                 return sz;
  10.249             }
  10.250         }
  10.251 
  10.252         // Enough space in buffer.. so copy to it
  10.253         memcpy(pBuffer+Pos, psourceBuffer, numBytes);
  10.254         Pos += numBytes;
  10.255         return numBytes;
  10.256     }
  10.257     int sz = pFile->Write(psourceBuffer,numBytes);
  10.258     if (sz > 0)
  10.259         FilePos += sz;
  10.260     return sz;
  10.261 }
  10.262 
  10.263 int     BufferedFile::Read(UByte *pdestBuffer, int numBytes)
  10.264 {
  10.265     if ( (BufferMode==ReadBuffer) || SetBufferMode(ReadBuffer))
  10.266     {
  10.267         // Data in buffer... copy it
  10.268         if ((int)(DataSize-Pos) >= numBytes)
  10.269         {
  10.270             memcpy(pdestBuffer, pBuffer+Pos, numBytes);
  10.271             Pos += numBytes;
  10.272             return numBytes;
  10.273         }
  10.274 
  10.275         // Not enough data in buffer, copy buffer
  10.276         int     readBytes = DataSize-Pos;
  10.277         memcpy(pdestBuffer, pBuffer+Pos, readBytes);
  10.278         numBytes    -= readBytes;
  10.279         pdestBuffer += readBytes;
  10.280         Pos = DataSize;
  10.281 
  10.282         // Don't reload buffer if more then tolerance
  10.283         // (No major advantage, and we don't want to write a loop)
  10.284         if (numBytes>FILEBUFFER_TOLERANCE)
  10.285         {
  10.286             numBytes = pFile->Read(pdestBuffer,numBytes);
  10.287             if (numBytes > 0)
  10.288             {
  10.289                 FilePos += numBytes;
  10.290                 Pos = DataSize = 0;
  10.291             }
  10.292             return readBytes + ((numBytes==-1) ? 0 : numBytes);
  10.293         }
  10.294 
  10.295         // Reload the buffer
  10.296         // WARNING: Right now LoadBuffer() assumes the buffer's empty
  10.297         LoadBuffer();
  10.298         if ((int)(DataSize-Pos) < numBytes)
  10.299             numBytes = (int)DataSize-Pos;
  10.300 
  10.301         memcpy(pdestBuffer, pBuffer+Pos, numBytes);
  10.302         Pos += numBytes;
  10.303         return numBytes + readBytes;
  10.304         
  10.305         /*
  10.306         // Alternative Read implementation. The one above is probably better
  10.307         // due to FILEBUFFER_TOLERANCE.
  10.308         int     total = 0;
  10.309 
  10.310         do {
  10.311             int     bufferBytes = (int)(DataSize-Pos);
  10.312             int     copyBytes = (bufferBytes > numBytes) ? numBytes : bufferBytes;
  10.313 
  10.314             memcpy(pdestBuffer, pBuffer+Pos, copyBytes);
  10.315             numBytes    -= copyBytes;
  10.316             pdestBuffer += copyBytes;
  10.317             Pos         += copyBytes;
  10.318             total       += copyBytes;
  10.319 
  10.320             if (numBytes == 0)
  10.321                 break;
  10.322             LoadBuffer();
  10.323 
  10.324         } while (DataSize > 0);
  10.325 
  10.326         return total;
  10.327         */     
  10.328     }
  10.329     int sz = pFile->Read(pdestBuffer,numBytes);
  10.330     if (sz > 0)
  10.331         FilePos += sz;
  10.332     return sz;
  10.333 }
  10.334 
  10.335 
  10.336 int     BufferedFile::SkipBytes(int numBytes)
  10.337 {
  10.338     int skippedBytes = 0;
  10.339 
  10.340     // Special case for skipping a little data in read buffer
  10.341     if (BufferMode==ReadBuffer)
  10.342     {
  10.343         skippedBytes = (((int)DataSize-(int)Pos) >= numBytes) ? numBytes : (DataSize-Pos);
  10.344         Pos          += skippedBytes;
  10.345         numBytes     -= skippedBytes;
  10.346     }
  10.347 
  10.348     if (numBytes)
  10.349     {
  10.350         numBytes = pFile->SkipBytes(numBytes);
  10.351         // Make sure we return the actual number skipped, or error
  10.352         if (numBytes!=-1)
  10.353         {
  10.354             skippedBytes += numBytes;
  10.355             FilePos += numBytes;
  10.356             Pos = DataSize = 0;
  10.357         }
  10.358         else if (skippedBytes <= 0)
  10.359             skippedBytes = -1;
  10.360     }
  10.361     return skippedBytes;
  10.362 }
  10.363 
  10.364 int     BufferedFile::BytesAvailable()
  10.365 {
  10.366     int available = pFile->BytesAvailable();
  10.367     // Adjust available size based on buffers
  10.368     switch(BufferMode)
  10.369     {
  10.370         case ReadBuffer:
  10.371             available += DataSize-Pos;
  10.372             break;
  10.373         case WriteBuffer:
  10.374             available -= Pos;
  10.375             if (available<0)
  10.376                 available= 0;
  10.377             break;
  10.378         default:
  10.379             break;
  10.380     }
  10.381     return available;
  10.382 }
  10.383 
  10.384 bool    BufferedFile::Flush()
  10.385 {
  10.386     FlushBuffer();
  10.387     return pFile->Flush();
  10.388 }
  10.389 
  10.390 // Seeking could be optimized better..
  10.391 int     BufferedFile::Seek(int offset, int origin)
  10.392 {    
  10.393     if (BufferMode == ReadBuffer)
  10.394     {
  10.395         if (origin == Seek_Cur)
  10.396         {
  10.397             // Seek can fall either before or after Pos in the buffer,
  10.398             // but it must be within bounds.
  10.399             if (((unsigned(offset) + Pos)) <= DataSize)
  10.400             {
  10.401                 Pos += offset;
  10.402                 return int (FilePos - DataSize + Pos);
  10.403             }
  10.404 
  10.405             // Lightweight buffer "Flush". We do this to avoid an extra seek
  10.406             // back operation which would take place if we called FlushBuffer directly.
  10.407             origin = Seek_Set;
  10.408             OVR_ASSERT(((FilePos - DataSize + Pos) + (UInt64)offset) < ~(UInt64)0);
  10.409             offset = (int)(FilePos - DataSize + Pos) + offset;
  10.410             Pos = DataSize = 0;
  10.411         }
  10.412         else if (origin == Seek_Set)
  10.413         {
  10.414             if (((unsigned)offset - (FilePos-DataSize)) <= DataSize)
  10.415             {
  10.416                 OVR_ASSERT((FilePos-DataSize) < ~(UInt64)0);
  10.417                 Pos = (unsigned)offset - (unsigned)(FilePos-DataSize);
  10.418                 return offset;
  10.419             }
  10.420             Pos = DataSize = 0;
  10.421         }
  10.422         else
  10.423         {
  10.424             FlushBuffer();
  10.425         }
  10.426     }
  10.427     else
  10.428     {
  10.429         FlushBuffer();
  10.430     }    
  10.431 
  10.432     /*
  10.433     // Old Seek Logic
  10.434     if (origin == Seek_Cur && offset + Pos < DataSize)
  10.435     {
  10.436         //OVR_ASSERT((FilePos - DataSize) >= (FilePos - DataSize + Pos + offset));
  10.437         Pos += offset;
  10.438         OVR_ASSERT(int (Pos) >= 0);
  10.439         return int (FilePos - DataSize + Pos);
  10.440     }
  10.441     else if (origin == Seek_Set && unsigned(offset) >= FilePos - DataSize && unsigned(offset) < FilePos)
  10.442     {
  10.443         Pos = unsigned(offset - FilePos + DataSize);
  10.444         OVR_ASSERT(int (Pos) >= 0);
  10.445         return int (FilePos - DataSize + Pos);
  10.446     }   
  10.447     
  10.448     FlushBuffer();
  10.449     */
  10.450 
  10.451 
  10.452     FilePos = pFile->Seek(offset,origin);
  10.453     return int (FilePos);
  10.454 }
  10.455 
  10.456 SInt64  BufferedFile::LSeek(SInt64 offset, int origin)
  10.457 {
  10.458     if (BufferMode == ReadBuffer)
  10.459     {
  10.460         if (origin == Seek_Cur)
  10.461         {
  10.462             // Seek can fall either before or after Pos in the buffer,
  10.463             // but it must be within bounds.
  10.464             if (((unsigned(offset) + Pos)) <= DataSize)
  10.465             {
  10.466                 Pos += (unsigned)offset;
  10.467                 return SInt64(FilePos - DataSize + Pos);
  10.468             }
  10.469 
  10.470             // Lightweight buffer "Flush". We do this to avoid an extra seek
  10.471             // back operation which would take place if we called FlushBuffer directly.
  10.472             origin = Seek_Set;            
  10.473             offset = (SInt64)(FilePos - DataSize + Pos) + offset;
  10.474             Pos = DataSize = 0;
  10.475         }
  10.476         else if (origin == Seek_Set)
  10.477         {
  10.478             if (((UInt64)offset - (FilePos-DataSize)) <= DataSize)
  10.479             {                
  10.480                 Pos = (unsigned)((UInt64)offset - (FilePos-DataSize));
  10.481                 return offset;
  10.482             }
  10.483             Pos = DataSize = 0;
  10.484         }
  10.485         else
  10.486         {
  10.487             FlushBuffer();
  10.488         }
  10.489     }
  10.490     else
  10.491     {
  10.492         FlushBuffer();
  10.493     }
  10.494 
  10.495 /*
  10.496     OVR_ASSERT(BufferMode != NoBuffer);
  10.497 
  10.498     if (origin == Seek_Cur && offset + Pos < DataSize)
  10.499     {
  10.500         Pos += int (offset);
  10.501         return FilePos - DataSize + Pos;
  10.502     }
  10.503     else if (origin == Seek_Set && offset >= SInt64(FilePos - DataSize) && offset < SInt64(FilePos))
  10.504     {
  10.505         Pos = unsigned(offset - FilePos + DataSize);
  10.506         return FilePos - DataSize + Pos;
  10.507     }
  10.508 
  10.509     FlushBuffer();
  10.510     */
  10.511 
  10.512     FilePos = pFile->LSeek(offset,origin);
  10.513     return FilePos;
  10.514 }
  10.515 
  10.516 int     BufferedFile::CopyFromStream(File *pstream, int byteSize)
  10.517 {
  10.518     // We can't rely on overridden Write()
  10.519     // because delegation doesn't override virtual pointers
  10.520     // So, just re-implement
  10.521     UByte   buff[0x4000];
  10.522     int     count = 0;
  10.523     int     szRequest, szRead, szWritten;
  10.524 
  10.525     while(byteSize)
  10.526     {
  10.527         szRequest = (byteSize > int(sizeof(buff))) ? int(sizeof(buff)) : byteSize;
  10.528 
  10.529         szRead    = pstream->Read(buff,szRequest);
  10.530         szWritten = 0;
  10.531         if (szRead > 0)
  10.532             szWritten = Write(buff,szRead);
  10.533 
  10.534         count   +=szWritten;
  10.535         byteSize-=szWritten;
  10.536         if (szWritten < szRequest)
  10.537             break;
  10.538     }
  10.539     return count;
  10.540 }
  10.541 
  10.542 // Closing files
  10.543 bool    BufferedFile::Close()
  10.544 {
  10.545     switch(BufferMode)
  10.546     {
  10.547         case WriteBuffer:
  10.548             FlushBuffer();
  10.549             break;
  10.550         case ReadBuffer:
  10.551             // No need to seek back on close
  10.552             BufferMode = NoBuffer;
  10.553             break;
  10.554         default:
  10.555             break;
  10.556     }
  10.557     return pFile->Close();
  10.558 }
  10.559 
  10.560 
  10.561 // ***** Global path helpers
  10.562 
  10.563 // Find trailing short filename in a path.
  10.564 const char* OVR_CDECL GetShortFilename(const char* purl)
  10.565 {    
  10.566     UPInt len = OVR_strlen(purl);
  10.567     for (UPInt i=len; i>0; i--) 
  10.568         if (purl[i]=='\\' || purl[i]=='/')
  10.569             return purl+i+1;
  10.570     return purl;
  10.571 }
  10.572 
  10.573 } // OVR
  10.574 
  10.575 \ No newline at end of file
  10.576 +/**************************************************************************
  10.577 +
  10.578 +Filename    :   OVR_File.cpp
  10.579 +Content     :   File wrapper class implementation (Win32)
  10.580 +
  10.581 +Created     :   April 5, 1999
  10.582 +Authors     :   Michael Antonov
  10.583 +
  10.584 +Copyright   :   Copyright 2012 Oculus VR, Inc. All Rights reserved.
  10.585 +
  10.586 +Use of this software is subject to the terms of the Oculus license
  10.587 +agreement provided at the time of installation or download, or which
  10.588 +otherwise accompanies this software in either electronic or hard copy form.
  10.589 +
  10.590 +**************************************************************************/
  10.591 +
  10.592 +#define  GFILE_CXX
  10.593 +
  10.594 +// Standard C library (Captain Obvious guarantees!)
  10.595 +#include <stdio.h>
  10.596 +
  10.597 +#include "OVR_File.h"
  10.598 +
  10.599 +namespace OVR {
  10.600 +
  10.601 +// Buffered file adds buffering to an existing file
  10.602 +// FILEBUFFER_SIZE defines the size of internal buffer, while
  10.603 +// FILEBUFFER_TOLERANCE controls the amount of data we'll effectively try to buffer
  10.604 +#define FILEBUFFER_SIZE         (8192-8)
  10.605 +#define FILEBUFFER_TOLERANCE    4096
  10.606 +
  10.607 +// ** Constructor/Destructor
  10.608 +
  10.609 +// Hidden constructor
  10.610 +// Not supposed to be used
  10.611 +BufferedFile::BufferedFile() : DelegatedFile(0)
  10.612 +{
  10.613 +    pBuffer     = (UByte*)OVR_ALLOC(FILEBUFFER_SIZE);
  10.614 +    BufferMode  = NoBuffer;
  10.615 +    FilePos     = 0;
  10.616 +    Pos         = 0;
  10.617 +    DataSize    = 0;
  10.618 +}
  10.619 +
  10.620 +// Takes another file as source
  10.621 +BufferedFile::BufferedFile(File *pfile) : DelegatedFile(pfile)
  10.622 +{
  10.623 +    pBuffer     = (UByte*)OVR_ALLOC(FILEBUFFER_SIZE);
  10.624 +    BufferMode  = NoBuffer;
  10.625 +    FilePos     = pfile->LTell();
  10.626 +    Pos         = 0;
  10.627 +    DataSize    = 0;
  10.628 +}
  10.629 +
  10.630 +
  10.631 +// Destructor
  10.632 +BufferedFile::~BufferedFile()
  10.633 +{
  10.634 +    // Flush in case there's data
  10.635 +    if (pFile)
  10.636 +        FlushBuffer();
  10.637 +    // Get rid of buffer
  10.638 +    if (pBuffer)
  10.639 +        OVR_FREE(pBuffer);
  10.640 +}
  10.641 +
  10.642 +/*
  10.643 +bool    BufferedFile::VCopy(const Object &source)
  10.644 +{
  10.645 +    if (!DelegatedFile::VCopy(source))
  10.646 +        return 0;
  10.647 +
  10.648 +    // Data members
  10.649 +    BufferedFile *psource = (BufferedFile*)&source;
  10.650 +
  10.651 +    // Buffer & the mode it's in
  10.652 +    pBuffer         = psource->pBuffer;
  10.653 +    BufferMode      = psource->BufferMode;
  10.654 +    Pos             = psource->Pos;
  10.655 +    DataSize        = psource->DataSize;
  10.656 +    return 1;
  10.657 +}
  10.658 +*/
  10.659 +
  10.660 +// Initializes buffering to a certain mode
  10.661 +bool    BufferedFile::SetBufferMode(BufferModeType mode)
  10.662 +{
  10.663 +    if (!pBuffer)
  10.664 +        return false;
  10.665 +    if (mode == BufferMode)
  10.666 +        return true;
  10.667 +     
  10.668 +    FlushBuffer();
  10.669 +
  10.670 +    // Can't set write mode if we can't write
  10.671 +    if ((mode==WriteBuffer) && (!pFile || !pFile->IsWritable()) )
  10.672 +        return 0;
  10.673 +
  10.674 +    // And SetMode
  10.675 +    BufferMode = mode;
  10.676 +    Pos        = 0;
  10.677 +    DataSize   = 0;
  10.678 +    return 1;
  10.679 +}
  10.680 +
  10.681 +// Flushes buffer
  10.682 +void    BufferedFile::FlushBuffer()
  10.683 +{
  10.684 +    switch(BufferMode)
  10.685 +    {
  10.686 +        case WriteBuffer:
  10.687 +            // Write data in buffer
  10.688 +            FilePos += pFile->Write(pBuffer,Pos);
  10.689 +            Pos = 0;
  10.690 +            break;
  10.691 +
  10.692 +        case ReadBuffer:
  10.693 +            // Seek back & reset buffer data
  10.694 +            if ((DataSize-Pos)>0)
  10.695 +                FilePos = pFile->LSeek(-(int)(DataSize-Pos), Seek_Cur);
  10.696 +            DataSize = 0;
  10.697 +            Pos      = 0;
  10.698 +            break;
  10.699 +        default:
  10.700 +            // not handled!
  10.701 +            break;
  10.702 +    }
  10.703 +}
  10.704 +
  10.705 +// Reloads data for ReadBuffer
  10.706 +void    BufferedFile::LoadBuffer()
  10.707 +{
  10.708 +    if (BufferMode == ReadBuffer)
  10.709 +    {
  10.710 +        // We should only reload once all of pre-loaded buffer is consumed.
  10.711 +        OVR_ASSERT(Pos == DataSize);
  10.712 +
  10.713 +        // WARNING: Right now LoadBuffer() assumes the buffer's empty
  10.714 +        int sz   = pFile->Read(pBuffer,FILEBUFFER_SIZE);
  10.715 +        DataSize = sz<0 ? 0 : (unsigned)sz;
  10.716 +        Pos      = 0;
  10.717 +        FilePos  += DataSize;
  10.718 +    }
  10.719 +}
  10.720 +
  10.721 +
  10.722 +// ** Overridden functions
  10.723 +
  10.724 +// We override all the functions that can possibly
  10.725 +// require buffer mode switch, flush, or extra calculations
  10.726 +
  10.727 +// Tell() requires buffer adjustment
  10.728 +int     BufferedFile::Tell()
  10.729 +{
  10.730 +    if (BufferMode == ReadBuffer)
  10.731 +        return int (FilePos - DataSize + Pos);
  10.732 +
  10.733 +    int pos = pFile->Tell();
  10.734 +    // Adjust position based on buffer mode & data
  10.735 +    if (pos!=-1)
  10.736 +    {
  10.737 +        OVR_ASSERT(BufferMode != ReadBuffer);
  10.738 +        if (BufferMode == WriteBuffer)
  10.739 +            pos += Pos;
  10.740 +    }
  10.741 +    return pos;
  10.742 +}
  10.743 +
  10.744 +SInt64  BufferedFile::LTell()
  10.745 +{
  10.746 +    if (BufferMode == ReadBuffer)
  10.747 +        return FilePos - DataSize + Pos;
  10.748 +
  10.749 +    SInt64 pos = pFile->LTell();
  10.750 +    if (pos!=-1)
  10.751 +    {
  10.752 +        OVR_ASSERT(BufferMode != ReadBuffer);
  10.753 +        if (BufferMode == WriteBuffer)
  10.754 +            pos += Pos;
  10.755 +    }
  10.756 +    return pos;
  10.757 +}
  10.758 +
  10.759 +int     BufferedFile::GetLength()
  10.760 +{
  10.761 +    int len = pFile->GetLength();
  10.762 +    // If writing through buffer, file length may actually be bigger
  10.763 +    if ((len!=-1) && (BufferMode==WriteBuffer))
  10.764 +    {
  10.765 +        int currPos = pFile->Tell() + Pos;
  10.766 +        if (currPos>len)
  10.767 +            len = currPos;
  10.768 +    }
  10.769 +    return len;
  10.770 +}
  10.771 +SInt64  BufferedFile::LGetLength()
  10.772 +{
  10.773 +    SInt64 len = pFile->LGetLength();
  10.774 +    // If writing through buffer, file length may actually be bigger
  10.775 +    if ((len!=-1) && (BufferMode==WriteBuffer))
  10.776 +    {
  10.777 +        SInt64 currPos = pFile->LTell() + Pos;
  10.778 +        if (currPos>len)
  10.779 +            len = currPos;
  10.780 +    }
  10.781 +    return len;
  10.782 +}
  10.783 +
  10.784 +/*
  10.785 +bool    BufferedFile::Stat(FileStats *pfs)
  10.786 +{
  10.787 +    // Have to fix up length is stat
  10.788 +    if (pFile->Stat(pfs))
  10.789 +    {
  10.790 +        if (BufferMode==WriteBuffer)
  10.791 +        {
  10.792 +            SInt64 currPos = pFile->LTell() + Pos;
  10.793 +            if (currPos > pfs->Size)
  10.794 +            {
  10.795 +                pfs->Size   = currPos;
  10.796 +                // ??
  10.797 +                pfs->Blocks = (pfs->Size+511) >> 9;
  10.798 +            }
  10.799 +        }
  10.800 +        return 1;
  10.801 +    }
  10.802 +    return 0;
  10.803 +}
  10.804 +*/
  10.805 +
  10.806 +int     BufferedFile::Write(const UByte *psourceBuffer, int numBytes)
  10.807 +{
  10.808 +    if ( (BufferMode==WriteBuffer) || SetBufferMode(WriteBuffer))
  10.809 +    {
  10.810 +        // If not data space in buffer, flush
  10.811 +        if ((FILEBUFFER_SIZE-(int)Pos)<numBytes)
  10.812 +        {
  10.813 +            FlushBuffer();
  10.814 +            // If bigger then tolerance, just write directly
  10.815 +            if (numBytes>FILEBUFFER_TOLERANCE)
  10.816 +            {
  10.817 +                int sz = pFile->Write(psourceBuffer,numBytes);
  10.818 +                if (sz > 0)
  10.819 +                    FilePos += sz;
  10.820 +                return sz;
  10.821 +            }
  10.822 +        }
  10.823 +
  10.824 +        // Enough space in buffer.. so copy to it
  10.825 +        memcpy(pBuffer+Pos, psourceBuffer, numBytes);
  10.826 +        Pos += numBytes;
  10.827 +        return numBytes;
  10.828 +    }
  10.829 +    int sz = pFile->Write(psourceBuffer,numBytes);
  10.830 +    if (sz > 0)
  10.831 +        FilePos += sz;
  10.832 +    return sz;
  10.833 +}
  10.834 +
  10.835 +int     BufferedFile::Read(UByte *pdestBuffer, int numBytes)
  10.836 +{
  10.837 +    if ( (BufferMode==ReadBuffer) || SetBufferMode(ReadBuffer))
  10.838 +    {
  10.839 +        // Data in buffer... copy it
  10.840 +        if ((int)(DataSize-Pos) >= numBytes)
  10.841 +        {
  10.842 +            memcpy(pdestBuffer, pBuffer+Pos, numBytes);
  10.843 +            Pos += numBytes;
  10.844 +            return numBytes;
  10.845 +        }
  10.846 +
  10.847 +        // Not enough data in buffer, copy buffer
  10.848 +        int     readBytes = DataSize-Pos;
  10.849 +        memcpy(pdestBuffer, pBuffer+Pos, readBytes);
  10.850 +        numBytes    -= readBytes;
  10.851 +        pdestBuffer += readBytes;
  10.852 +        Pos = DataSize;
  10.853 +
  10.854 +        // Don't reload buffer if more then tolerance
  10.855 +        // (No major advantage, and we don't want to write a loop)
  10.856 +        if (numBytes>FILEBUFFER_TOLERANCE)
  10.857 +        {
  10.858 +            numBytes = pFile->Read(pdestBuffer,numBytes);
  10.859 +            if (numBytes > 0)
  10.860 +            {
  10.861 +                FilePos += numBytes;
  10.862 +                Pos = DataSize = 0;
  10.863 +            }
  10.864 +            return readBytes + ((numBytes==-1) ? 0 : numBytes);
  10.865 +        }
  10.866 +
  10.867 +        // Reload the buffer
  10.868 +        // WARNING: Right now LoadBuffer() assumes the buffer's empty
  10.869 +        LoadBuffer();
  10.870 +        if ((int)(DataSize-Pos) < numBytes)
  10.871 +            numBytes = (int)DataSize-Pos;
  10.872 +
  10.873 +        memcpy(pdestBuffer, pBuffer+Pos, numBytes);
  10.874 +        Pos += numBytes;
  10.875 +        return numBytes + readBytes;
  10.876 +        
  10.877 +        /*
  10.878 +        // Alternative Read implementation. The one above is probably better
  10.879 +        // due to FILEBUFFER_TOLERANCE.
  10.880 +        int     total = 0;
  10.881 +
  10.882 +        do {
  10.883 +            int     bufferBytes = (int)(DataSize-Pos);
  10.884 +            int     copyBytes = (bufferBytes > numBytes) ? numBytes : bufferBytes;
  10.885 +
  10.886 +            memcpy(pdestBuffer, pBuffer+Pos, copyBytes);
  10.887 +            numBytes    -= copyBytes;
  10.888 +            pdestBuffer += copyBytes;
  10.889 +            Pos         += copyBytes;
  10.890 +            total       += copyBytes;
  10.891 +
  10.892 +            if (numBytes == 0)
  10.893 +                break;
  10.894 +            LoadBuffer();
  10.895 +
  10.896 +        } while (DataSize > 0);
  10.897 +
  10.898 +        return total;
  10.899 +        */     
  10.900 +    }
  10.901 +    int sz = pFile->Read(pdestBuffer,numBytes);
  10.902 +    if (sz > 0)
  10.903 +        FilePos += sz;
  10.904 +    return sz;
  10.905 +}
  10.906 +
  10.907 +
  10.908 +int     BufferedFile::SkipBytes(int numBytes)
  10.909 +{
  10.910 +    int skippedBytes = 0;
  10.911 +
  10.912 +    // Special case for skipping a little data in read buffer
  10.913 +    if (BufferMode==ReadBuffer)
  10.914 +    {
  10.915 +        skippedBytes = (((int)DataSize-(int)Pos) >= numBytes) ? numBytes : (DataSize-Pos);
  10.916 +        Pos          += skippedBytes;
  10.917 +        numBytes     -= skippedBytes;
  10.918 +    }
  10.919 +
  10.920 +    if (numBytes)
  10.921 +    {
  10.922 +        numBytes = pFile->SkipBytes(numBytes);
  10.923 +        // Make sure we return the actual number skipped, or error
  10.924 +        if (numBytes!=-1)
  10.925 +        {
  10.926 +            skippedBytes += numBytes;
  10.927 +            FilePos += numBytes;
  10.928 +            Pos = DataSize = 0;
  10.929 +        }
  10.930 +        else if (skippedBytes <= 0)
  10.931 +            skippedBytes = -1;
  10.932 +    }
  10.933 +    return skippedBytes;
  10.934 +}
  10.935 +
  10.936 +int     BufferedFile::BytesAvailable()
  10.937 +{
  10.938 +    int available = pFile->BytesAvailable();
  10.939 +    // Adjust available size based on buffers
  10.940 +    switch(BufferMode)
  10.941 +    {
  10.942 +        case ReadBuffer:
  10.943 +            available += DataSize-Pos;
  10.944 +            break;
  10.945 +        case WriteBuffer:
  10.946 +            available -= Pos;
  10.947 +            if (available<0)
  10.948 +                available= 0;
  10.949 +            break;
  10.950 +        default:
  10.951 +            break;
  10.952 +    }
  10.953 +    return available;
  10.954 +}
  10.955 +
  10.956 +bool    BufferedFile::Flush()
  10.957 +{
  10.958 +    FlushBuffer();
  10.959 +    return pFile->Flush();
  10.960 +}
  10.961 +
  10.962 +// Seeking could be optimized better..
  10.963 +int     BufferedFile::Seek(int offset, int origin)
  10.964 +{    
  10.965 +    if (BufferMode == ReadBuffer)
  10.966 +    {
  10.967 +        if (origin == Seek_Cur)
  10.968 +        {
  10.969 +            // Seek can fall either before or after Pos in the buffer,
  10.970 +            // but it must be within bounds.
  10.971 +            if (((unsigned(offset) + Pos)) <= DataSize)
  10.972 +            {
  10.973 +                Pos += offset;
  10.974 +                return int (FilePos - DataSize + Pos);
  10.975 +            }
  10.976 +
  10.977 +            // Lightweight buffer "Flush". We do this to avoid an extra seek
  10.978 +            // back operation which would take place if we called FlushBuffer directly.
  10.979 +            origin = Seek_Set;
  10.980 +            OVR_ASSERT(((FilePos - DataSize + Pos) + (UInt64)offset) < ~(UInt64)0);
  10.981 +            offset = (int)(FilePos - DataSize + Pos) + offset;
  10.982 +            Pos = DataSize = 0;
  10.983 +        }
  10.984 +        else if (origin == Seek_Set)
  10.985 +        {
  10.986 +            if (((unsigned)offset - (FilePos-DataSize)) <= DataSize)
  10.987 +            {
  10.988 +                OVR_ASSERT((FilePos-DataSize) < ~(UInt64)0);
  10.989 +                Pos = (unsigned)offset - (unsigned)(FilePos-DataSize);
  10.990 +                return offset;
  10.991 +            }
  10.992 +            Pos = DataSize = 0;
  10.993 +        }
  10.994 +        else
  10.995 +        {
  10.996 +            FlushBuffer();
  10.997 +        }
  10.998 +    }
  10.999 +    else
 10.1000 +    {
 10.1001 +        FlushBuffer();
 10.1002 +    }    
 10.1003 +
 10.1004 +    /*
 10.1005 +    // Old Seek Logic
 10.1006 +    if (origin == Seek_Cur && offset + Pos < DataSize)
 10.1007 +    {
 10.1008 +        //OVR_ASSERT((FilePos - DataSize) >= (FilePos - DataSize + Pos + offset));
 10.1009 +        Pos += offset;
 10.1010 +        OVR_ASSERT(int (Pos) >= 0);
 10.1011 +        return int (FilePos - DataSize + Pos);
 10.1012 +    }
 10.1013 +    else if (origin == Seek_Set && unsigned(offset) >= FilePos - DataSize && unsigned(offset) < FilePos)
 10.1014 +    {
 10.1015 +        Pos = unsigned(offset - FilePos + DataSize);
 10.1016 +        OVR_ASSERT(int (Pos) >= 0);
 10.1017 +        return int (FilePos - DataSize + Pos);
 10.1018 +    }   
 10.1019 +    
 10.1020 +    FlushBuffer();
 10.1021 +    */
 10.1022 +
 10.1023 +
 10.1024 +    FilePos = pFile->Seek(offset,origin);
 10.1025 +    return int (FilePos);
 10.1026 +}
 10.1027 +
 10.1028 +SInt64  BufferedFile::LSeek(SInt64 offset, int origin)
 10.1029 +{
 10.1030 +    if (BufferMode == ReadBuffer)
 10.1031 +    {
 10.1032 +        if (origin == Seek_Cur)
 10.1033 +        {
 10.1034 +            // Seek can fall either before or after Pos in the buffer,
 10.1035 +            // but it must be within bounds.
 10.1036 +            if (((unsigned(offset) + Pos)) <= DataSize)
 10.1037 +            {
 10.1038 +                Pos += (unsigned)offset;
 10.1039 +                return SInt64(FilePos - DataSize + Pos);
 10.1040 +            }
 10.1041 +
 10.1042 +            // Lightweight buffer "Flush". We do this to avoid an extra seek
 10.1043 +            // back operation which would take place if we called FlushBuffer directly.
 10.1044 +            origin = Seek_Set;            
 10.1045 +            offset = (SInt64)(FilePos - DataSize + Pos) + offset;
 10.1046 +            Pos = DataSize = 0;
 10.1047 +        }
 10.1048 +        else if (origin == Seek_Set)
 10.1049 +        {
 10.1050 +            if (((UInt64)offset - (FilePos-DataSize)) <= DataSize)
 10.1051 +            {                
 10.1052 +                Pos = (unsigned)((UInt64)offset - (FilePos-DataSize));
 10.1053 +                return offset;
 10.1054 +            }
 10.1055 +            Pos = DataSize = 0;
 10.1056 +        }
 10.1057 +        else
 10.1058 +        {
 10.1059 +            FlushBuffer();
 10.1060 +        }
 10.1061 +    }
 10.1062 +    else
 10.1063 +    {
 10.1064 +        FlushBuffer();
 10.1065 +    }
 10.1066 +
 10.1067 +/*
 10.1068 +    OVR_ASSERT(BufferMode != NoBuffer);
 10.1069 +
 10.1070 +    if (origin == Seek_Cur && offset + Pos < DataSize)
 10.1071 +    {
 10.1072 +        Pos += int (offset);
 10.1073 +        return FilePos - DataSize + Pos;
 10.1074 +    }
 10.1075 +    else if (origin == Seek_Set && offset >= SInt64(FilePos - DataSize) && offset < SInt64(FilePos))
 10.1076 +    {
 10.1077 +        Pos = unsigned(offset - FilePos + DataSize);
 10.1078 +        return FilePos - DataSize + Pos;
 10.1079 +    }
 10.1080 +
 10.1081 +    FlushBuffer();
 10.1082 +    */
 10.1083 +
 10.1084 +    FilePos = pFile->LSeek(offset,origin);
 10.1085 +    return FilePos;
 10.1086 +}
 10.1087 +
 10.1088 +int     BufferedFile::CopyFromStream(File *pstream, int byteSize)
 10.1089 +{
 10.1090 +    // We can't rely on overridden Write()
 10.1091 +    // because delegation doesn't override virtual pointers
 10.1092 +    // So, just re-implement
 10.1093 +    UByte   buff[0x4000];
 10.1094 +    int     count = 0;
 10.1095 +    int     szRequest, szRead, szWritten;
 10.1096 +
 10.1097 +    while(byteSize)
 10.1098 +    {
 10.1099 +        szRequest = (byteSize > int(sizeof(buff))) ? int(sizeof(buff)) : byteSize;
 10.1100 +
 10.1101 +        szRead    = pstream->Read(buff,szRequest);
 10.1102 +        szWritten = 0;
 10.1103 +        if (szRead > 0)
 10.1104 +            szWritten = Write(buff,szRead);
 10.1105 +
 10.1106 +        count   +=szWritten;
 10.1107 +        byteSize-=szWritten;
 10.1108 +        if (szWritten < szRequest)
 10.1109 +            break;
 10.1110 +    }
 10.1111 +    return count;
 10.1112 +}
 10.1113 +
 10.1114 +// Closing files
 10.1115 +bool    BufferedFile::Close()
 10.1116 +{
 10.1117 +    switch(BufferMode)
 10.1118 +    {
 10.1119 +        case WriteBuffer:
 10.1120 +            FlushBuffer();
 10.1121 +            break;
 10.1122 +        case ReadBuffer:
 10.1123 +            // No need to seek back on close
 10.1124 +            BufferMode = NoBuffer;
 10.1125 +            break;
 10.1126 +        default:
 10.1127 +            break;
 10.1128 +    }
 10.1129 +    return pFile->Close();
 10.1130 +}
 10.1131 +
 10.1132 +
 10.1133 +// ***** Global path helpers
 10.1134 +
 10.1135 +// Find trailing short filename in a path.
 10.1136 +const char* OVR_CDECL GetShortFilename(const char* purl)
 10.1137 +{    
 10.1138 +    UPInt len = OVR_strlen(purl);
 10.1139 +    for (UPInt i=len; i>0; i--) 
 10.1140 +        if (purl[i]=='\\' || purl[i]=='/')
 10.1141 +            return purl+i+1;
 10.1142 +    return purl;
 10.1143 +}
 10.1144 +
 10.1145 +} // OVR
 10.1146 +
    11.1 --- a/libovr/Src/Kernel/OVR_File.h	Sat Sep 14 17:51:03 2013 +0300
    11.2 +++ b/libovr/Src/Kernel/OVR_File.h	Sun Sep 15 04:10:05 2013 +0300
    11.3 @@ -1,1 +1,518 @@
    11.4 -/************************************************************************************
    11.5 
    11.6 PublicHeader:   Kernel
    11.7 Filename    :   OVR_File.h
    11.8 Content     :   Header for all internal file management - functions and structures
    11.9                 to be inherited by OS specific subclasses.
   11.10 Created     :   September 19, 2012
   11.11 Notes       : 
   11.12 
   11.13 Notes       :   errno may not be preserved across use of BaseFile member functions
   11.14             :   Directories cannot be deleted while files opened from them are in use
   11.15                 (For the GetFullName function)
   11.16 
   11.17 Copyright   :   Copyright 2012 Oculus VR, Inc. All Rights reserved.
   11.18 
   11.19 Use of this software is subject to the terms of the Oculus license
   11.20 agreement provided at the time of installation or download, or which
   11.21 otherwise accompanies this software in either electronic or hard copy form.
   11.22 
   11.23 ************************************************************************************/
   11.24 
   11.25 #ifndef OVR_File_h
   11.26 #define OVR_File_h
   11.27 
   11.28 #include "OVR_RefCount.h"
   11.29 #include "OVR_Std.h"
   11.30 #include "OVR_Alg.h"
   11.31 
   11.32 #include <stdio.h>
   11.33 #include "OVR_String.h"
   11.34 
   11.35 namespace OVR {
   11.36 
   11.37 // ***** Declared classes
   11.38 class   FileConstants;
   11.39 class   File;
   11.40 class   DelegatedFile;
   11.41 class   BufferedFile;
   11.42 
   11.43 
   11.44 // ***** Flags for File & Directory accesses
   11.45 
   11.46 class FileConstants
   11.47 {
   11.48 public:
   11.49 
   11.50     // *** File open flags
   11.51     enum OpenFlags
   11.52     {
   11.53         Open_Read       = 1,
   11.54         Open_Write      = 2,
   11.55         Open_ReadWrite  = 3,
   11.56 
   11.57         // Opens file and truncates it to zero length
   11.58         // - file must have write permission
   11.59         // - when used with Create, it opens an existing 
   11.60         //   file and empties it or creates a new file
   11.61         Open_Truncate   = 4,
   11.62 
   11.63         // Creates and opens new file 
   11.64         // - does not erase contents if file already
   11.65         //   exists unless combined with Truncate
   11.66         Open_Create     = 8,
   11.67 
   11.68          // Returns an error value if the file already exists
   11.69         Open_CreateOnly = 24,
   11.70 
   11.71         // Open file with buffering
   11.72         Open_Buffered    = 32
   11.73     };
   11.74 
   11.75     // *** File Mode flags
   11.76     enum Modes
   11.77     {
   11.78         Mode_Read       = 0444,
   11.79         Mode_Write      = 0222,
   11.80         Mode_Execute    = 0111,
   11.81 
   11.82         Mode_ReadWrite  = 0666
   11.83     };
   11.84 
   11.85     // *** Seek operations
   11.86     enum SeekOps
   11.87     {
   11.88         Seek_Set        = 0,
   11.89         Seek_Cur        = 1,
   11.90         Seek_End        = 2
   11.91     };
   11.92 
   11.93     // *** Errors
   11.94     enum Errors
   11.95     {
   11.96         Error_FileNotFound  = 0x1001,
   11.97         Error_Access        = 0x1002,
   11.98         Error_IOError       = 0x1003,
   11.99         Error_DiskFull      = 0x1004
  11.100     };
  11.101 };
  11.102 
  11.103 
  11.104 //-----------------------------------------------------------------------------------
  11.105 // ***** File Class
  11.106 
  11.107 // The pure virtual base random-access file
  11.108 // This is a base class to all files
  11.109 
  11.110 class File : public RefCountBase<File>, public FileConstants
  11.111 {   
  11.112 public:
  11.113     File() { }
  11.114     // ** Location Information
  11.115 
  11.116     // Returns a file name path relative to the 'reference' directory
  11.117     // This is often a path that was used to create a file
  11.118     // (this is not a global path, global path can be obtained with help of directory)
  11.119     virtual const char* GetFilePath() = 0;
  11.120                                                                                         
  11.121 
  11.122     // ** File Information
  11.123 
  11.124     // Return 1 if file's usable (open)
  11.125     virtual bool        IsValid() = 0;
  11.126     // Return 1 if file's writable, otherwise 0                                         
  11.127     virtual bool        IsWritable() = 0;
  11.128                                                                                         
  11.129     // Return position
  11.130     virtual int         Tell() = 0;
  11.131     virtual SInt64      LTell() = 0;
  11.132     
  11.133     // File size                                                                        
  11.134     virtual int         GetLength() = 0;
  11.135     virtual SInt64      LGetLength() = 0;
  11.136                                                                                         
  11.137     // Returns file stats                                                               
  11.138     // 0 for failure                                                                    
  11.139     //virtual bool      Stat(FileStats *pfs) = 0;
  11.140                                                                                         
  11.141     // Return errno-based error code                                                    
  11.142     // Useful if any other function failed                                              
  11.143     virtual int         GetErrorCode() = 0;
  11.144                                                                                         
  11.145                                                                                         
  11.146     // ** Stream implementation & I/O
  11.147 
  11.148     // Blocking write, will write in the given number of bytes to the stream
  11.149     // Returns : -1 for error
  11.150     //           Otherwise number of bytes read 
  11.151     virtual int         Write(const UByte *pbufer, int numBytes) = 0;
  11.152     // Blocking read, will read in the given number of bytes or less from the stream
  11.153     // Returns : -1 for error
  11.154     //           Otherwise number of bytes read,
  11.155     //           if 0 or < numBytes, no more bytes available; end of file or the other side of stream is closed
  11.156     virtual int         Read(UByte *pbufer, int numBytes) = 0;
  11.157 
  11.158     // Skips (ignores) a given # of bytes
  11.159     // Same return values as Read
  11.160     virtual int         SkipBytes(int numBytes) = 0;
  11.161         
  11.162     // Returns the number of bytes available to read from a stream without blocking
  11.163     // For a file, this should generally be number of bytes to the end
  11.164     virtual int         BytesAvailable() = 0;
  11.165 
  11.166     // Causes any implementation's buffered data to be delivered to destination
  11.167     // Return 0 for error
  11.168     virtual bool        Flush() = 0;
  11.169                                                                                             
  11.170 
  11.171     // Need to provide a more optimized implementation that doe snot necessarily involve a lot of seeking
  11.172     inline bool         IsEOF() { return !BytesAvailable(); }
  11.173     
  11.174 
  11.175     // Seeking                                                                              
  11.176     // Returns new position, -1 for error                                                   
  11.177     virtual int         Seek(int offset, int origin=Seek_Set) = 0;
  11.178     virtual SInt64      LSeek(SInt64 offset, int origin=Seek_Set) = 0;
  11.179     // Seek simplification
  11.180     int                 SeekToBegin()           {return Seek(0); }
  11.181     int                 SeekToEnd()             {return Seek(0,Seek_End); }
  11.182     int                 Skip(int numBytes)     {return Seek(numBytes,Seek_Cur); }
  11.183                         
  11.184 
  11.185     // Appends other file data from a stream
  11.186     // Return -1 for error, else # of bytes written
  11.187     virtual int         CopyFromStream(File *pstream, int byteSize) = 0;
  11.188 
  11.189     // Closes the file
  11.190     // After close, file cannot be accessed 
  11.191     virtual bool        Close() = 0;
  11.192 
  11.193 
  11.194     // ***** Inlines for convenient primitive type serialization
  11.195 
  11.196     // Read/Write helpers
  11.197 private:
  11.198     UInt64  PRead64()           { UInt64 v = 0; Read((UByte*)&v, 8); return v; }
  11.199     UInt32  PRead32()           { UInt32 v = 0; Read((UByte*)&v, 4); return v; }
  11.200     UInt16  PRead16()           { UInt16 v = 0; Read((UByte*)&v, 2); return v; }
  11.201     UByte   PRead8()            { UByte  v = 0; Read((UByte*)&v, 1); return v; }
  11.202     void    PWrite64(UInt64 v)  { Write((UByte*)&v, 8); }
  11.203     void    PWrite32(UInt32 v)  { Write((UByte*)&v, 4); }
  11.204     void    PWrite16(UInt16 v)  { Write((UByte*)&v, 2); }
  11.205     void    PWrite8(UByte v)    { Write((UByte*)&v, 1); }
  11.206 
  11.207 public:
  11.208 
  11.209     // Writing primitive types - Little Endian
  11.210     inline void    WriteUByte(UByte v)         { PWrite8((UByte)Alg::ByteUtil::SystemToLE(v));     }
  11.211     inline void    WriteSByte(SByte v)         { PWrite8((UByte)Alg::ByteUtil::SystemToLE(v));     }
  11.212     inline void    WriteUInt8(UByte v)         { PWrite8((UByte)Alg::ByteUtil::SystemToLE(v));     }
  11.213     inline void    WriteSInt8(SByte v)         { PWrite8((UByte)Alg::ByteUtil::SystemToLE(v));     }
  11.214     inline void    WriteUInt16(UInt16 v)       { PWrite16((UInt16)Alg::ByteUtil::SystemToLE(v));   }
  11.215     inline void    WriteSInt16(SInt16 v)       { PWrite16((UInt16)Alg::ByteUtil::SystemToLE(v));   }
  11.216     inline void    WriteUInt32(UInt32 v)       { PWrite32((UInt32)Alg::ByteUtil::SystemToLE(v));   }
  11.217     inline void    WriteSInt32(SInt32 v)       { PWrite32((UInt32)Alg::ByteUtil::SystemToLE(v));   }
  11.218     inline void    WriteUInt64(UInt64 v)       { PWrite64((UInt64)Alg::ByteUtil::SystemToLE(v));   }
  11.219     inline void    WriteSInt64(SInt64 v)       { PWrite64((UInt64)Alg::ByteUtil::SystemToLE(v));   }
  11.220     inline void    WriteFloat(float v)         { v = Alg::ByteUtil::SystemToLE(v); Write((UByte*)&v, 4); } 
  11.221     inline void    WriteDouble(double v)       { v = Alg::ByteUtil::SystemToLE(v); Write((UByte*)&v, 8); }
  11.222     // Writing primitive types - Big Endian
  11.223     inline void    WriteUByteBE(UByte v)       { PWrite8((UByte)Alg::ByteUtil::SystemToBE(v));     }
  11.224     inline void    WriteSByteBE(SByte v)       { PWrite8((UByte)Alg::ByteUtil::SystemToBE(v));     }
  11.225     inline void    WriteUInt8BE(UInt16 v)      { PWrite8((UByte)Alg::ByteUtil::SystemToBE(v));     }
  11.226     inline void    WriteSInt8BE(SInt16 v)      { PWrite8((UByte)Alg::ByteUtil::SystemToBE(v));     }
  11.227     inline void    WriteUInt16BE(UInt16 v)     { PWrite16((UInt16)Alg::ByteUtil::SystemToBE(v));   }
  11.228     inline void    WriteSInt16BE(UInt16 v)     { PWrite16((UInt16)Alg::ByteUtil::SystemToBE(v));   }
  11.229     inline void    WriteUInt32BE(UInt32 v)     { PWrite32((UInt32)Alg::ByteUtil::SystemToBE(v));   }
  11.230     inline void    WriteSInt32BE(UInt32 v)     { PWrite32((UInt32)Alg::ByteUtil::SystemToBE(v));   }
  11.231     inline void    WriteUInt64BE(UInt64 v)     { PWrite64((UInt64)Alg::ByteUtil::SystemToBE(v));   }
  11.232     inline void    WriteSInt64BE(UInt64 v)     { PWrite64((UInt64)Alg::ByteUtil::SystemToBE(v));   }
  11.233     inline void    WriteFloatBE(float v)       { v = Alg::ByteUtil::SystemToBE(v); Write((UByte*)&v, 4); }
  11.234     inline void    WriteDoubleBE(double v)     { v = Alg::ByteUtil::SystemToBE(v); Write((UByte*)&v, 8); }
  11.235         
  11.236     // Reading primitive types - Little Endian
  11.237     inline UByte   ReadUByte()                 { return (UByte)Alg::ByteUtil::LEToSystem(PRead8());    }
  11.238     inline SByte   ReadSByte()                 { return (SByte)Alg::ByteUtil::LEToSystem(PRead8());    }
  11.239     inline UByte   ReadUInt8()                 { return (UByte)Alg::ByteUtil::LEToSystem(PRead8());    }
  11.240     inline SByte   ReadSInt8()                 { return (SByte)Alg::ByteUtil::LEToSystem(PRead8());    }
  11.241     inline UInt16  ReadUInt16()                { return (UInt16)Alg::ByteUtil::LEToSystem(PRead16());  }
  11.242     inline SInt16  ReadSInt16()                { return (SInt16)Alg::ByteUtil::LEToSystem(PRead16());  }
  11.243     inline UInt32  ReadUInt32()                { return (UInt32)Alg::ByteUtil::LEToSystem(PRead32());  }
  11.244     inline SInt32  ReadSInt32()                { return (SInt32)Alg::ByteUtil::LEToSystem(PRead32());  }
  11.245     inline UInt64  ReadUInt64()                { return (UInt64)Alg::ByteUtil::LEToSystem(PRead64());  }
  11.246     inline SInt64  ReadSInt64()                { return (SInt64)Alg::ByteUtil::LEToSystem(PRead64());  }
  11.247     inline float   ReadFloat()                 { float v = 0.0f; Read((UByte*)&v, 4); return Alg::ByteUtil::LEToSystem(v); }
  11.248     inline double  ReadDouble()                { double v = 0.0; Read((UByte*)&v, 8); return Alg::ByteUtil::LEToSystem(v); }
  11.249     // Reading primitive types - Big Endian
  11.250     inline UByte   ReadUByteBE()               { return (UByte)Alg::ByteUtil::BEToSystem(PRead8());    }
  11.251     inline SByte   ReadSByteBE()               { return (SByte)Alg::ByteUtil::BEToSystem(PRead8());    }
  11.252     inline UByte   ReadUInt8BE()               { return (UByte)Alg::ByteUtil::BEToSystem(PRead8());    }
  11.253     inline SByte   ReadSInt8BE()               { return (SByte)Alg::ByteUtil::BEToSystem(PRead8());    }
  11.254     inline UInt16  ReadUInt16BE()              { return (UInt16)Alg::ByteUtil::BEToSystem(PRead16());  }
  11.255     inline SInt16  ReadSInt16BE()              { return (SInt16)Alg::ByteUtil::BEToSystem(PRead16());  }
  11.256     inline UInt32  ReadUInt32BE()              { return (UInt32)Alg::ByteUtil::BEToSystem(PRead32());  }
  11.257     inline SInt32  ReadSInt32BE()              { return (SInt32)Alg::ByteUtil::BEToSystem(PRead32());  }
  11.258     inline UInt64  ReadUInt64BE()              { return (UInt64)Alg::ByteUtil::BEToSystem(PRead64());  }
  11.259     inline SInt64  ReadSInt64BE()              { return (SInt64)Alg::ByteUtil::BEToSystem(PRead64());  }
  11.260     inline float   ReadFloatBE()               { float v = 0.0f; Read((UByte*)&v, 4); return Alg::ByteUtil::BEToSystem(v); }
  11.261     inline double  ReadDoubleBE()              { double v = 0.0; Read((UByte*)&v, 8); return Alg::ByteUtil::BEToSystem(v); }
  11.262 };
  11.263 
  11.264 
  11.265 // *** Delegated File
  11.266 
  11.267 class DelegatedFile : public File
  11.268 {
  11.269 protected:
  11.270     // Delegating file pointer
  11.271     Ptr<File>     pFile;
  11.272 
  11.273     // Hidden default constructor
  11.274     DelegatedFile() : pFile(0)                             { }
  11.275     DelegatedFile(const DelegatedFile &source) : File()    { OVR_UNUSED(source); }
  11.276 public:
  11.277     // Constructors
  11.278     DelegatedFile(File *pfile) : pFile(pfile)     { }
  11.279 
  11.280     // ** Location Information  
  11.281     virtual const char* GetFilePath()                               { return pFile->GetFilePath(); }    
  11.282 
  11.283     // ** File Information                                                      
  11.284     virtual bool        IsValid()                                   { return pFile && pFile->IsValid(); }   
  11.285     virtual bool        IsWritable()                                { return pFile->IsWritable(); }
  11.286 //  virtual bool        IsRecoverable()                             { return pFile->IsRecoverable(); }          
  11.287                                                                     
  11.288     virtual int         Tell()                                      { return pFile->Tell(); }
  11.289     virtual SInt64      LTell()                                     { return pFile->LTell(); }
  11.290     
  11.291     virtual int         GetLength()                                 { return pFile->GetLength(); }
  11.292     virtual SInt64      LGetLength()                                { return pFile->LGetLength(); }
  11.293     
  11.294     //virtual bool      Stat(FileStats *pfs)                        { return pFile->Stat(pfs); }
  11.295     
  11.296     virtual int         GetErrorCode()                              { return pFile->GetErrorCode(); }
  11.297     
  11.298     // ** Stream implementation & I/O
  11.299     virtual int         Write(const UByte *pbuffer, int numBytes)   { return pFile->Write(pbuffer,numBytes); }  
  11.300     virtual int         Read(UByte *pbuffer, int numBytes)          { return pFile->Read(pbuffer,numBytes); }   
  11.301     
  11.302     virtual int         SkipBytes(int numBytes)                     { return pFile->SkipBytes(numBytes); }      
  11.303     
  11.304     virtual int         BytesAvailable()                            { return pFile->BytesAvailable(); } 
  11.305     
  11.306     virtual bool        Flush()                                     { return pFile->Flush(); }
  11.307                                                                     
  11.308     // Seeking                                                      
  11.309     virtual int         Seek(int offset, int origin=Seek_Set)       { return pFile->Seek(offset,origin); }
  11.310     virtual SInt64      LSeek(SInt64 offset, int origin=Seek_Set)   { return pFile->LSeek(offset,origin); }
  11.311 
  11.312     virtual int         CopyFromStream(File *pstream, int byteSize) { return pFile->CopyFromStream(pstream,byteSize); }
  11.313                         
  11.314     // Closing the file 
  11.315     virtual bool        Close()                                     { return pFile->Close(); }    
  11.316 };
  11.317 
  11.318 
  11.319 //-----------------------------------------------------------------------------------
  11.320 // ***** Buffered File
  11.321 
  11.322 // This file class adds buffering to an existing file
  11.323 // Buffered file never fails by itself; if there's not
  11.324 // enough memory for buffer, no buffer's used
  11.325 
  11.326 class BufferedFile : public DelegatedFile
  11.327 {   
  11.328 protected:  
  11.329     enum BufferModeType
  11.330     {
  11.331         NoBuffer,
  11.332         ReadBuffer,
  11.333         WriteBuffer
  11.334     };
  11.335 
  11.336     // Buffer & the mode it's in
  11.337     UByte*          pBuffer;
  11.338     BufferModeType  BufferMode;
  11.339     // Position in buffer
  11.340     unsigned        Pos;
  11.341     // Data in buffer if reading
  11.342     unsigned        DataSize;
  11.343     // Underlying file position 
  11.344     UInt64          FilePos;
  11.345 
  11.346     // Initializes buffering to a certain mode
  11.347     bool    SetBufferMode(BufferModeType mode);
  11.348     // Flushes buffer
  11.349     // WriteBuffer - write data to disk, ReadBuffer - reset buffer & fix file position  
  11.350     void    FlushBuffer();
  11.351     // Loads data into ReadBuffer
  11.352     // WARNING: Right now LoadBuffer() assumes the buffer's empty
  11.353     void    LoadBuffer();
  11.354 
  11.355     // Hidden constructor
  11.356     BufferedFile();
  11.357     inline BufferedFile(const BufferedFile &source) : DelegatedFile() { OVR_UNUSED(source); }
  11.358 public:
  11.359 
  11.360     // Constructor
  11.361     // - takes another file as source
  11.362     BufferedFile(File *pfile);
  11.363     ~BufferedFile();
  11.364     
  11.365     
  11.366     // ** Overridden functions
  11.367 
  11.368     // We override all the functions that can possibly
  11.369     // require buffer mode switch, flush, or extra calculations
  11.370     virtual int         Tell();
  11.371     virtual SInt64      LTell();
  11.372 
  11.373     virtual int         GetLength();
  11.374     virtual SInt64      LGetLength();
  11.375 
  11.376 //  virtual bool        Stat(GFileStats *pfs);  
  11.377 
  11.378     virtual int         Write(const UByte *pbufer, int numBytes);
  11.379     virtual int         Read(UByte *pbufer, int numBytes);
  11.380 
  11.381     virtual int         SkipBytes(int numBytes);
  11.382 
  11.383     virtual int         BytesAvailable();
  11.384 
  11.385     virtual bool        Flush();
  11.386 
  11.387     virtual int         Seek(int offset, int origin=Seek_Set);
  11.388     virtual SInt64      LSeek(SInt64 offset, int origin=Seek_Set);
  11.389 
  11.390     virtual int         CopyFromStream(File *pstream, int byteSize);
  11.391     
  11.392     virtual bool        Close();    
  11.393 };                          
  11.394 
  11.395 
  11.396 //-----------------------------------------------------------------------------------
  11.397 // ***** Memory File
  11.398 
  11.399 class MemoryFile : public File
  11.400 {
  11.401 public:
  11.402 
  11.403     const char* GetFilePath()       { return FilePath.ToCStr(); }
  11.404 
  11.405     bool        IsValid()           { return Valid; }
  11.406     bool        IsWritable()        { return false; }
  11.407 
  11.408     bool        Flush()             { return true; }
  11.409     int         GetErrorCode()      { return 0; }
  11.410 
  11.411     int         Tell()              { return FileIndex; }
  11.412     SInt64      LTell()             { return (SInt64) FileIndex; }
  11.413 
  11.414     int         GetLength()         { return FileSize; }
  11.415     SInt64      LGetLength()        { return (SInt64) FileSize; }
  11.416 
  11.417     bool        Close()
  11.418     {
  11.419         Valid = false;
  11.420         return false;
  11.421     }
  11.422 
  11.423     int         CopyFromStream(File *pstream, int byteSize)
  11.424     {   OVR_UNUSED2(pstream, byteSize);
  11.425         return 0;
  11.426     }
  11.427 
  11.428     int         Write(const UByte *pbuffer, int numBytes)
  11.429     {   OVR_UNUSED2(pbuffer, numBytes);
  11.430         return 0;
  11.431     }
  11.432 
  11.433     int         Read(UByte *pbufer, int numBytes)
  11.434     {
  11.435         if (FileIndex + numBytes > FileSize)
  11.436         {
  11.437             numBytes = FileSize - FileIndex;
  11.438         }
  11.439 
  11.440         if (numBytes > 0)
  11.441         {
  11.442             ::memcpy (pbufer, &FileData [FileIndex], numBytes);
  11.443 
  11.444             FileIndex += numBytes;
  11.445         }
  11.446 
  11.447         return numBytes;
  11.448     }
  11.449 
  11.450     int         SkipBytes(int numBytes)
  11.451     {
  11.452         if (FileIndex + numBytes > FileSize)
  11.453         {
  11.454             numBytes = FileSize - FileIndex;
  11.455         }
  11.456 
  11.457         FileIndex += numBytes;
  11.458 
  11.459         return numBytes;
  11.460     }
  11.461 
  11.462     int         BytesAvailable()
  11.463     {
  11.464         return (FileSize - FileIndex);
  11.465     }
  11.466 
  11.467     int         Seek(int offset, int origin = Seek_Set)
  11.468     {
  11.469         switch (origin)
  11.470         {
  11.471         case Seek_Set : FileIndex  = offset;               break;
  11.472         case Seek_Cur : FileIndex += offset;               break;
  11.473         case Seek_End : FileIndex  = FileSize - offset;  break;
  11.474         }
  11.475 
  11.476         return FileIndex;
  11.477     }
  11.478 
  11.479     SInt64      LSeek(SInt64 offset, int origin = Seek_Set)
  11.480     {
  11.481         return (SInt64) Seek((int) offset, origin);
  11.482     }
  11.483 
  11.484 public:
  11.485 
  11.486     MemoryFile (const String& fileName, const UByte *pBuffer, int buffSize)
  11.487         : FilePath(fileName)
  11.488     {
  11.489         FileData  = pBuffer;
  11.490         FileSize  = buffSize;
  11.491         FileIndex = 0;
  11.492         Valid     = (!fileName.IsEmpty() && pBuffer && buffSize > 0) ? true : false;
  11.493     }
  11.494 
  11.495     // pfileName should be encoded as UTF-8 to support international file names.
  11.496     MemoryFile (const char* pfileName, const UByte *pBuffer, int buffSize)
  11.497         : FilePath(pfileName)
  11.498     {
  11.499         FileData  = pBuffer;
  11.500         FileSize  = buffSize;
  11.501         FileIndex = 0;
  11.502         Valid     = (pfileName && pBuffer && buffSize > 0) ? true : false;
  11.503     }
  11.504 private:
  11.505 
  11.506     String       FilePath;
  11.507     const UByte *FileData;
  11.508     int          FileSize;
  11.509     int          FileIndex;
  11.510     bool         Valid;
  11.511 };
  11.512 
  11.513 
  11.514 // ***** Global path helpers
  11.515 
  11.516 // Find trailing short filename in a path.
  11.517 const char* OVR_CDECL GetShortFilename(const char* purl);
  11.518 
  11.519 } // OVR
  11.520 
  11.521 #endif
  11.522 \ No newline at end of file
  11.523 +/************************************************************************************
  11.524 +
  11.525 +PublicHeader:   Kernel
  11.526 +Filename    :   OVR_File.h
  11.527 +Content     :   Header for all internal file management - functions and structures
  11.528 +                to be inherited by OS specific subclasses.
  11.529 +Created     :   September 19, 2012
  11.530 +Notes       : 
  11.531 +
  11.532 +Notes       :   errno may not be preserved across use of BaseFile member functions
  11.533 +            :   Directories cannot be deleted while files opened from them are in use
  11.534 +                (For the GetFullName function)
  11.535 +
  11.536 +Copyright   :   Copyright 2012 Oculus VR, Inc. All Rights reserved.
  11.537 +
  11.538 +Use of this software is subject to the terms of the Oculus license
  11.539 +agreement provided at the time of installation or download, or which
  11.540 +otherwise accompanies this software in either electronic or hard copy form.
  11.541 +
  11.542 +************************************************************************************/
  11.543 +
  11.544 +#ifndef OVR_File_h
  11.545 +#define OVR_File_h
  11.546 +
  11.547 +#include "OVR_RefCount.h"
  11.548 +#include "OVR_Std.h"
  11.549 +#include "OVR_Alg.h"
  11.550 +
  11.551 +#include <stdio.h>
  11.552 +#include "OVR_String.h"
  11.553 +
  11.554 +namespace OVR {
  11.555 +
  11.556 +// ***** Declared classes
  11.557 +class   FileConstants;
  11.558 +class   File;
  11.559 +class   DelegatedFile;
  11.560 +class   BufferedFile;
  11.561 +
  11.562 +
  11.563 +// ***** Flags for File & Directory accesses
  11.564 +
  11.565 +class FileConstants
  11.566 +{
  11.567 +public:
  11.568 +
  11.569 +    // *** File open flags
  11.570 +    enum OpenFlags
  11.571 +    {
  11.572 +        Open_Read       = 1,
  11.573 +        Open_Write      = 2,
  11.574 +        Open_ReadWrite  = 3,
  11.575 +
  11.576 +        // Opens file and truncates it to zero length
  11.577 +        // - file must have write permission
  11.578 +        // - when used with Create, it opens an existing 
  11.579 +        //   file and empties it or creates a new file
  11.580 +        Open_Truncate   = 4,
  11.581 +
  11.582 +        // Creates and opens new file 
  11.583 +        // - does not erase contents if file already
  11.584 +        //   exists unless combined with Truncate
  11.585 +        Open_Create     = 8,
  11.586 +
  11.587 +         // Returns an error value if the file already exists
  11.588 +        Open_CreateOnly = 24,
  11.589 +
  11.590 +        // Open file with buffering
  11.591 +        Open_Buffered    = 32
  11.592 +    };
  11.593 +
  11.594 +    // *** File Mode flags
  11.595 +    enum Modes
  11.596 +    {
  11.597 +        Mode_Read       = 0444,
  11.598 +        Mode_Write      = 0222,
  11.599 +        Mode_Execute    = 0111,
  11.600 +
  11.601 +        Mode_ReadWrite  = 0666
  11.602 +    };
  11.603 +
  11.604 +    // *** Seek operations
  11.605 +    enum SeekOps
  11.606 +    {
  11.607 +        Seek_Set        = 0,
  11.608 +        Seek_Cur        = 1,
  11.609 +        Seek_End        = 2
  11.610 +    };
  11.611 +
  11.612 +    // *** Errors
  11.613 +    enum Errors
  11.614 +    {
  11.615 +        Error_FileNotFound  = 0x1001,
  11.616 +        Error_Access        = 0x1002,
  11.617 +        Error_IOError       = 0x1003,
  11.618 +        Error_DiskFull      = 0x1004
  11.619 +    };
  11.620 +};
  11.621 +
  11.622 +
  11.623 +//-----------------------------------------------------------------------------------
  11.624 +// ***** File Class
  11.625 +
  11.626 +// The pure virtual base random-access file
  11.627 +// This is a base class to all files
  11.628 +
  11.629 +class File : public RefCountBase<File>, public FileConstants
  11.630 +{   
  11.631 +public:
  11.632 +    File() { }
  11.633 +    // ** Location Information
  11.634 +
  11.635 +    // Returns a file name path relative to the 'reference' directory
  11.636 +    // This is often a path that was used to create a file
  11.637 +    // (this is not a global path, global path can be obtained with help of directory)
  11.638 +    virtual const char* GetFilePath() = 0;
  11.639 +                                                                                        
  11.640 +
  11.641 +    // ** File Information
  11.642 +
  11.643 +    // Return 1 if file's usable (open)
  11.644 +    virtual bool        IsValid() = 0;
  11.645 +    // Return 1 if file's writable, otherwise 0                                         
  11.646 +    virtual bool        IsWritable() = 0;
  11.647 +                                                                                        
  11.648 +    // Return position
  11.649 +    virtual int         Tell() = 0;
  11.650 +    virtual SInt64      LTell() = 0;
  11.651 +    
  11.652 +    // File size                                                                        
  11.653 +    virtual int         GetLength() = 0;
  11.654 +    virtual SInt64      LGetLength() = 0;
  11.655 +                                                                                        
  11.656 +    // Returns file stats                                                               
  11.657 +    // 0 for failure                                                                    
  11.658 +    //virtual bool      Stat(FileStats *pfs) = 0;
  11.659 +                                                                                        
  11.660 +    // Return errno-based error code                                                    
  11.661 +    // Useful if any other function failed                                              
  11.662 +    virtual int         GetErrorCode() = 0;
  11.663 +                                                                                        
  11.664 +                                                                                        
  11.665 +    // ** Stream implementation & I/O
  11.666 +
  11.667 +    // Blocking write, will write in the given number of bytes to the stream
  11.668 +    // Returns : -1 for error
  11.669 +    //           Otherwise number of bytes read 
  11.670 +    virtual int         Write(const UByte *pbufer, int numBytes) = 0;
  11.671 +    // Blocking read, will read in the given number of bytes or less from the stream
  11.672 +    // Returns : -1 for error
  11.673 +    //           Otherwise number of bytes read,
  11.674 +    //           if 0 or < numBytes, no more bytes available; end of file or the other side of stream is closed
  11.675 +    virtual int         Read(UByte *pbufer, int numBytes) = 0;
  11.676 +
  11.677 +    // Skips (ignores) a given # of bytes
  11.678 +    // Same return values as Read
  11.679 +    virtual int         SkipBytes(int numBytes) = 0;
  11.680 +        
  11.681 +    // Returns the number of bytes available to read from a stream without blocking
  11.682 +    // For a file, this should generally be number of bytes to the end
  11.683 +    virtual int         BytesAvailable() = 0;
  11.684 +
  11.685 +    // Causes any implementation's buffered data to be delivered to destination
  11.686 +    // Return 0 for error
  11.687 +    virtual bool        Flush() = 0;
  11.688 +                                                                                            
  11.689 +
  11.690 +    // Need to provide a more optimized implementation that doe snot necessarily involve a lot of seeking
  11.691 +    inline bool         IsEOF() { return !BytesAvailable(); }
  11.692 +    
  11.693 +
  11.694 +    // Seeking                                                                              
  11.695 +    // Returns new position, -1 for error                                                   
  11.696 +    virtual int         Seek(int offset, int origin=Seek_Set) = 0;
  11.697 +    virtual SInt64      LSeek(SInt64 offset, int origin=Seek_Set) = 0;
  11.698 +    // Seek simplification
  11.699 +    int                 SeekToBegin()           {return Seek(0); }
  11.700 +    int                 SeekToEnd()             {return Seek(0,Seek_End); }
  11.701 +    int                 Skip(int numBytes)     {return Seek(numBytes,Seek_Cur); }
  11.702 +                        
  11.703 +
  11.704 +    // Appends other file data from a stream
  11.705 +    // Return -1 for error, else # of bytes written
  11.706 +    virtual int         CopyFromStream(File *pstream, int byteSize) = 0;
  11.707 +
  11.708 +    // Closes the file
  11.709 +    // After close, file cannot be accessed 
  11.710 +    virtual bool        Close() = 0;
  11.711 +
  11.712 +
  11.713 +    // ***** Inlines for convenient primitive type serialization
  11.714 +
  11.715 +    // Read/Write helpers
  11.716 +private:
  11.717 +    UInt64  PRead64()           { UInt64 v = 0; Read((UByte*)&v, 8); return v; }
  11.718 +    UInt32  PRead32()           { UInt32 v = 0; Read((UByte*)&v, 4); return v; }
  11.719 +    UInt16  PRead16()           { UInt16 v = 0; Read((UByte*)&v, 2); return v; }
  11.720 +    UByte   PRead8()            { UByte  v = 0; Read((UByte*)&v, 1); return v; }
  11.721 +    void    PWrite64(UInt64 v)  { Write((UByte*)&v, 8); }
  11.722 +    void    PWrite32(UInt32 v)  { Write((UByte*)&v, 4); }
  11.723 +    void    PWrite16(UInt16 v)  { Write((UByte*)&v, 2); }
  11.724 +    void    PWrite8(UByte v)    { Write((UByte*)&v, 1); }
  11.725 +
  11.726 +public:
  11.727 +
  11.728 +    // Writing primitive types - Little Endian
  11.729 +    inline void    WriteUByte(UByte v)         { PWrite8((UByte)Alg::ByteUtil::SystemToLE(v));     }
  11.730 +    inline void    WriteSByte(SByte v)         { PWrite8((UByte)Alg::ByteUtil::SystemToLE(v));     }
  11.731 +    inline void    WriteUInt8(UByte v)         { PWrite8((UByte)Alg::ByteUtil::SystemToLE(v));     }
  11.732 +    inline void    WriteSInt8(SByte v)         { PWrite8((UByte)Alg::ByteUtil::SystemToLE(v));     }
  11.733 +    inline void    WriteUInt16(UInt16 v)       { PWrite16((UInt16)Alg::ByteUtil::SystemToLE(v));   }
  11.734 +    inline void    WriteSInt16(SInt16 v)       { PWrite16((UInt16)Alg::ByteUtil::SystemToLE(v));   }
  11.735 +    inline void    WriteUInt32(UInt32 v)       { PWrite32((UInt32)Alg::ByteUtil::SystemToLE(v));   }
  11.736 +    inline void    WriteSInt32(SInt32 v)       { PWrite32((UInt32)Alg::ByteUtil::SystemToLE(v));   }
  11.737 +    inline void    WriteUInt64(UInt64 v)       { PWrite64((UInt64)Alg::ByteUtil::SystemToLE(v));   }
  11.738 +    inline void    WriteSInt64(SInt64 v)       { PWrite64((UInt64)Alg::ByteUtil::SystemToLE(v));   }
  11.739 +    inline void    WriteFloat(float v)         { v = Alg::ByteUtil::SystemToLE(v); Write((UByte*)&v, 4); } 
  11.740 +    inline void    WriteDouble(double v)       { v = Alg::ByteUtil::SystemToLE(v); Write((UByte*)&v, 8); }
  11.741 +    // Writing primitive types - Big Endian
  11.742 +    inline void    WriteUByteBE(UByte v)       { PWrite8((UByte)Alg::ByteUtil::SystemToBE(v));     }
  11.743 +    inline void    WriteSByteBE(SByte v)       { PWrite8((UByte)Alg::ByteUtil::SystemToBE(v));     }
  11.744 +    inline void    WriteUInt8BE(UInt16 v)      { PWrite8((UByte)Alg::ByteUtil::SystemToBE(v));     }
  11.745 +    inline void    WriteSInt8BE(SInt16 v)      { PWrite8((UByte)Alg::ByteUtil::SystemToBE(v));     }
  11.746 +    inline void    WriteUInt16BE(UInt16 v)     { PWrite16((UInt16)Alg::ByteUtil::SystemToBE(v));   }
  11.747 +    inline void    WriteSInt16BE(UInt16 v)     { PWrite16((UInt16)Alg::ByteUtil::SystemToBE(v));   }
  11.748 +    inline void    WriteUInt32BE(UInt32 v)     { PWrite32((UInt32)Alg::ByteUtil::SystemToBE(v));   }
  11.749 +    inline void    WriteSInt32BE(UInt32 v)     { PWrite32((UInt32)Alg::ByteUtil::SystemToBE(v));   }
  11.750 +    inline void    WriteUInt64BE(UInt64 v)     { PWrite64((UInt64)Alg::ByteUtil::SystemToBE(v));   }
  11.751 +    inline void    WriteSInt64BE(UInt64 v)     { PWrite64((UInt64)Alg::ByteUtil::SystemToBE(v));   }
  11.752 +    inline void    WriteFloatBE(float v)       { v = Alg::ByteUtil::SystemToBE(v); Write((UByte*)&v, 4); }
  11.753 +    inline void    WriteDoubleBE(double v)     { v = Alg::ByteUtil::SystemToBE(v); Write((UByte*)&v, 8); }
  11.754 +        
  11.755 +    // Reading primitive types - Little Endian
  11.756 +    inline UByte   ReadUByte()                 { return (UByte)Alg::ByteUtil::LEToSystem(PRead8());    }
  11.757 +    inline SByte   ReadSByte()                 { return (SByte)Alg::ByteUtil::LEToSystem(PRead8());    }
  11.758 +    inline UByte   ReadUInt8()                 { return (UByte)Alg::ByteUtil::LEToSystem(PRead8());    }
  11.759 +    inline SByte   ReadSInt8()                 { return (SByte)Alg::ByteUtil::LEToSystem(PRead8());    }
  11.760 +    inline UInt16  ReadUInt16()                { return (UInt16)Alg::ByteUtil::LEToSystem(PRead16());  }
  11.761 +    inline SInt16  ReadSInt16()                { return (SInt16)Alg::ByteUtil::LEToSystem(PRead16());  }
  11.762 +    inline UInt32  ReadUInt32()                { return (UInt32)Alg::ByteUtil::LEToSystem(PRead32());  }
  11.763 +    inline SInt32  ReadSInt32()                { return (SInt32)Alg::ByteUtil::LEToSystem(PRead32());  }
  11.764 +    inline UInt64  ReadUInt64()                { return (UInt64)Alg::ByteUtil::LEToSystem(PRead64());  }
  11.765 +    inline SInt64  ReadSInt64()                { return (SInt64)Alg::ByteUtil::LEToSystem(PRead64());  }
  11.766 +    inline float   ReadFloat()                 { float v = 0.0f; Read((UByte*)&v, 4); return Alg::ByteUtil::LEToSystem(v); }
  11.767 +    inline double  ReadDouble()                { double v = 0.0; Read((UByte*)&v, 8); return Alg::ByteUtil::LEToSystem(v); }
  11.768 +    // Reading primitive types - Big Endian
  11.769 +    inline UByte   ReadUByteBE()               { return (UByte)Alg::ByteUtil::BEToSystem(PRead8());    }
  11.770 +    inline SByte   ReadSByteBE()               { return (SByte)Alg::ByteUtil::BEToSystem(PRead8());    }
  11.771 +    inline UByte   ReadUInt8BE()               { return (UByte)Alg::ByteUtil::BEToSystem(PRead8());    }
  11.772 +    inline SByte   ReadSInt8BE()               { return (SByte)Alg::ByteUtil::BEToSystem(PRead8());    }
  11.773 +    inline UInt16  ReadUInt16BE()              { return (UInt16)Alg::ByteUtil::BEToSystem(PRead16());  }
  11.774 +    inline SInt16  ReadSInt16BE()              { return (SInt16)Alg::ByteUtil::BEToSystem(PRead16());  }
  11.775 +    inline UInt32  ReadUInt32BE()              { return (UInt32)Alg::ByteUtil::BEToSystem(PRead32());  }
  11.776 +    inline SInt32  ReadSInt32BE()              { return (SInt32)Alg::ByteUtil::BEToSystem(PRead32());  }
  11.777 +    inline UInt64  ReadUInt64BE()              { return (UInt64)Alg::ByteUtil::BEToSystem(PRead64());  }
  11.778 +    inline SInt64  ReadSInt64BE()              { return (SInt64)Alg::ByteUtil::BEToSystem(PRead64());  }
  11.779 +    inline float   ReadFloatBE()               { float v = 0.0f; Read((UByte*)&v, 4); return Alg::ByteUtil::BEToSystem(v); }
  11.780 +    inline double  ReadDoubleBE()              { double v = 0.0; Read((UByte*)&v, 8); return Alg::ByteUtil::BEToSystem(v); }
  11.781 +};
  11.782 +
  11.783 +
  11.784 +// *** Delegated File
  11.785 +
  11.786 +class DelegatedFile : public File
  11.787 +{
  11.788 +protected:
  11.789 +    // Delegating file pointer
  11.790 +    Ptr<File>     pFile;
  11.791 +
  11.792 +    // Hidden default constructor
  11.793 +    DelegatedFile() : pFile(0)                             { }
  11.794 +    DelegatedFile(const DelegatedFile &source) : File()    { OVR_UNUSED(source); }
  11.795 +public:
  11.796 +    // Constructors
  11.797 +    DelegatedFile(File *pfile) : pFile(pfile)     { }
  11.798 +
  11.799 +    // ** Location Information  
  11.800 +    virtual const char* GetFilePath()                               { return pFile->GetFilePath(); }    
  11.801 +
  11.802 +    // ** File Information                                                      
  11.803 +    virtual bool        IsValid()                                   { return pFile && pFile->IsValid(); }   
  11.804 +    virtual bool        IsWritable()                                { return pFile->IsWritable(); }
  11.805 +//  virtual bool        IsRecoverable()                             { return pFile->IsRecoverable(); }          
  11.806 +                                                                    
  11.807 +    virtual int         Tell()                                      { return pFile->Tell(); }
  11.808 +    virtual SInt64      LTell()                                     { return pFile->LTell(); }
  11.809 +    
  11.810 +    virtual int         GetLength()                                 { return pFile->GetLength(); }
  11.811 +    virtual SInt64      LGetLength()                                { return pFile->LGetLength(); }
  11.812 +    
  11.813 +    //virtual bool      Stat(FileStats *pfs)                        { return pFile->Stat(pfs); }
  11.814 +    
  11.815 +    virtual int         GetErrorCode()                              { return pFile->GetErrorCode(); }
  11.816 +    
  11.817 +    // ** Stream implementation & I/O
  11.818 +    virtual int         Write(const UByte *pbuffer, int numBytes)   { return pFile->Write(pbuffer,numBytes); }  
  11.819 +    virtual int         Read(UByte *pbuffer, int numBytes)          { return pFile->Read(pbuffer,numBytes); }   
  11.820 +    
  11.821 +    virtual int         SkipBytes(int numBytes)                     { return pFile->SkipBytes(numBytes); }      
  11.822 +    
  11.823 +    virtual int         BytesAvailable()                            { return pFile->BytesAvailable(); } 
  11.824 +    
  11.825 +    virtual bool        Flush()                                     { return pFile->Flush(); }
  11.826 +                                                                    
  11.827 +    // Seeking                                                      
  11.828 +    virtual int         Seek(int offset, int origin=Seek_Set)       { return pFile->Seek(offset,origin); }
  11.829 +    virtual SInt64      LSeek(SInt64 offset, int origin=Seek_Set)   { return pFile->LSeek(offset,origin); }
  11.830 +
  11.831 +    virtual int         CopyFromStream(File *pstream, int byteSize) { return pFile->CopyFromStream(pstream,byteSize); }
  11.832 +                        
  11.833 +    // Closing the file 
  11.834 +    virtual bool        Close()                                     { return pFile->Close(); }    
  11.835 +};
  11.836 +
  11.837 +
  11.838 +//-----------------------------------------------------------------------------------
  11.839 +// ***** Buffered File
  11.840 +
  11.841 +// This file class adds buffering to an existing file
  11.842 +// Buffered file never fails by itself; if there's not
  11.843 +// enough memory for buffer, no buffer's used
  11.844 +
  11.845 +class BufferedFile : public DelegatedFile
  11.846 +{   
  11.847 +protected:  
  11.848 +    enum BufferModeType
  11.849 +    {
  11.850 +        NoBuffer,
  11.851 +        ReadBuffer,
  11.852 +        WriteBuffer
  11.853 +    };
  11.854 +
  11.855 +    // Buffer & the mode it's in
  11.856 +    UByte*          pBuffer;
  11.857 +    BufferModeType  BufferMode;
  11.858 +    // Position in buffer
  11.859 +    unsigned        Pos;
  11.860 +    // Data in buffer if reading
  11.861 +    unsigned        DataSize;
  11.862 +    // Underlying file position 
  11.863 +    UInt64          FilePos;
  11.864 +
  11.865 +    // Initializes buffering to a certain mode
  11.866 +    bool    SetBufferMode(BufferModeType mode);
  11.867 +    // Flushes buffer
  11.868 +    // WriteBuffer - write data to disk, ReadBuffer - reset buffer & fix file position  
  11.869 +    void    FlushBuffer();
  11.870 +    // Loads data into ReadBuffer
  11.871 +    // WARNING: Right now LoadBuffer() assumes the buffer's empty
  11.872 +    void    LoadBuffer();
  11.873 +
  11.874 +    // Hidden constructor
  11.875 +    BufferedFile();
  11.876 +    inline BufferedFile(const BufferedFile &source) : DelegatedFile() { OVR_UNUSED(source); }
  11.877 +public:
  11.878 +
  11.879 +    // Constructor
  11.880 +    // - takes another file as source
  11.881 +    BufferedFile(File *pfile);
  11.882 +    ~BufferedFile();
  11.883 +    
  11.884 +    
  11.885 +    // ** Overridden functions
  11.886 +
  11.887 +    // We override all the functions that can possibly
  11.888 +    // require buffer mode switch, flush, or extra calculations
  11.889 +    virtual int         Tell();
  11.890 +    virtual SInt64      LTell();
  11.891 +
  11.892 +    virtual int         GetLength();
  11.893 +    virtual SInt64      LGetLength();
  11.894 +
  11.895 +//  virtual bool        Stat(GFileStats *pfs);  
  11.896 +
  11.897 +    virtual int         Write(const UByte *pbufer, int numBytes);
  11.898 +    virtual int         Read(UByte *pbufer, int numBytes);
  11.899 +
  11.900 +    virtual int         SkipBytes(int numBytes);
  11.901 +
  11.902 +    virtual int         BytesAvailable();
  11.903 +
  11.904 +    virtual bool        Flush();
  11.905 +
  11.906 +    virtual int         Seek(int offset, int origin=Seek_Set);
  11.907 +    virtual SInt64      LSeek(SInt64 offset, int origin=Seek_Set);
  11.908 +
  11.909 +    virtual int         CopyFromStream(File *pstream, int byteSize);
  11.910 +    
  11.911 +    virtual bool        Close();    
  11.912 +};                          
  11.913 +
  11.914 +
  11.915 +//-----------------------------------------------------------------------------------
  11.916 +// ***** Memory File
  11.917 +
  11.918 +class MemoryFile : public File
  11.919 +{
  11.920 +public:
  11.921 +
  11.922 +    const char* GetFilePath()       { return FilePath.ToCStr(); }
  11.923 +
  11.924 +    bool        IsValid()           { return Valid; }
  11.925 +    bool        IsWritable()        { return false; }
  11.926 +
  11.927 +    bool        Flush()             { return true; }
  11.928 +    int         GetErrorCode()      { return 0; }
  11.929 +
  11.930 +    int         Tell()              { return FileIndex; }
  11.931 +    SInt64      LTell()             { return (SInt64) FileIndex; }
  11.932 +
  11.933 +    int         GetLength()         { return FileSize; }
  11.934 +    SInt64      LGetLength()        { return (SInt64) FileSize; }
  11.935 +
  11.936 +    bool        Close()
  11.937 +    {
  11.938 +        Valid = false;
  11.939 +        return false;
  11.940 +    }
  11.941 +
  11.942 +    int         CopyFromStream(File *pstream, int byteSize)
  11.943 +    {   OVR_UNUSED2(pstream, byteSize);
  11.944 +        return 0;
  11.945 +    }
  11.946 +
  11.947 +    int         Write(const UByte *pbuffer, int numBytes)
  11.948 +    {   OVR_UNUSED2(pbuffer, numBytes);
  11.949 +        return 0;
  11.950 +    }
  11.951 +
  11.952 +    int         Read(UByte *pbufer, int numBytes)
  11.953 +    {
  11.954 +        if (FileIndex + numBytes > FileSize)
  11.955 +        {
  11.956 +            numBytes = FileSize - FileIndex;
  11.957 +        }
  11.958 +
  11.959 +        if (numBytes > 0)
  11.960 +        {
  11.961 +            ::memcpy (pbufer, &FileData [FileIndex], numBytes);
  11.962 +
  11.963 +            FileIndex += numBytes;
  11.964 +        }
  11.965 +
  11.966 +        return numBytes;
  11.967 +    }
  11.968 +
  11.969 +    int         SkipBytes(int numBytes)
  11.970 +    {
  11.971 +        if (FileIndex + numBytes > FileSize)
  11.972 +        {
  11.973 +            numBytes = FileSize - FileIndex;
  11.974 +        }
  11.975 +
  11.976 +        FileIndex += numBytes;
  11.977 +
  11.978 +        return numBytes;
  11.979 +    }
  11.980 +
  11.981 +    int         BytesAvailable()
  11.982 +    {
  11.983 +        return (FileSize - FileIndex);
  11.984 +    }
  11.985 +
  11.986 +    int         Seek(int offset, int origin = Seek_Set)
  11.987 +    {
  11.988 +        switch (origin)
  11.989 +        {
  11.990 +        case Seek_Set : FileIndex  = offset;               break;
  11.991 +        case Seek_Cur : FileIndex += offset;               break;
  11.992 +        case Seek_End : FileIndex  = FileSize - offset;  break;
  11.993 +        }
  11.994 +
  11.995 +        return FileIndex;
  11.996 +    }
  11.997 +
  11.998 +    SInt64      LSeek(SInt64 offset, int origin = Seek_Set)
  11.999 +    {
 11.1000 +        return (SInt64) Seek((int) offset, origin);
 11.1001 +    }
 11.1002 +
 11.1003 +public:
 11.1004 +
 11.1005 +    MemoryFile (const String& fileName, const UByte *pBuffer, int buffSize)
 11.1006 +        : FilePath(fileName)
 11.1007 +    {
 11.1008 +        FileData  = pBuffer;
 11.1009 +        FileSize  = buffSize;
 11.1010 +        FileIndex = 0;
 11.1011 +        Valid     = (!fileName.IsEmpty() && pBuffer && buffSize > 0) ? true : false;
 11.1012 +    }
 11.1013 +
 11.1014 +    // pfileName should be encoded as UTF-8 to support international file names.
 11.1015 +    MemoryFile (const char* pfileName, const UByte *pBuffer, int buffSize)
 11.1016 +        : FilePath(pfileName)
 11.1017 +    {
 11.1018 +        FileData  = pBuffer;
 11.1019 +        FileSize  = buffSize;
 11.1020 +        FileIndex = 0;
 11.1021 +        Valid     = (pfileName && pBuffer && buffSize > 0) ? true : false;
 11.1022 +    }
 11.1023 +private:
 11.1024 +
 11.1025 +    String       FilePath;
 11.1026 +    const UByte *FileData;
 11.1027 +    int          FileSize;
 11.1028 +    int          FileIndex;
 11.1029 +    bool         Valid;
 11.1030 +};
 11.1031 +
 11.1032 +
 11.1033 +// ***** Global path helpers
 11.1034 +
 11.1035 +// Find trailing short filename in a path.
 11.1036 +const char* OVR_CDECL GetShortFilename(const char* purl);
 11.1037 +
 11.1038 +} // OVR
 11.1039 +
 11.1040 +#endif
    12.1 --- a/libovr/Src/Kernel/OVR_FileFILE.cpp	Sat Sep 14 17:51:03 2013 +0300
    12.2 +++ b/libovr/Src/Kernel/OVR_FileFILE.cpp	Sun Sep 15 04:10:05 2013 +0300
    12.3 @@ -1,1 +1,583 @@
    12.4 -/**************************************************************************
    12.5 
    12.6 Filename    :   OVR_FileFILE.cpp
    12.7 Content     :   File wrapper class implementation (Win32)
    12.8 
    12.9 Created     :   April 5, 1999
   12.10 Authors     :   Michael Antonov
   12.11 
   12.12 Copyright   :   Copyright 2012 Oculus VR, Inc. All Rights reserved.
   12.13 
   12.14 Use of this software is subject to the terms of the Oculus license
   12.15 agreement provided at the time of installation or download, or which
   12.16 otherwise accompanies this software in either electronic or hard copy form.
   12.17 
   12.18 **************************************************************************/
   12.19 
   12.20 #define  GFILE_CXX
   12.21 
   12.22 #include "OVR_Types.h"
   12.23 #include "OVR_Log.h"
   12.24 
   12.25 // Standard C library (Captain Obvious guarantees!)
   12.26 #include <stdio.h>
   12.27 #ifndef OVR_OS_WINCE
   12.28 #include <sys/stat.h>
   12.29 #endif
   12.30 
   12.31 #include "OVR_SysFile.h"
   12.32 
   12.33 #ifndef OVR_OS_WINCE
   12.34 #include <errno.h>
   12.35 #endif
   12.36 
   12.37 namespace OVR {
   12.38 
   12.39 // ***** File interface
   12.40 
   12.41 // ***** FILEFile - C streams file
   12.42 
   12.43 static int SFerror ()
   12.44 {
   12.45     if (errno == ENOENT)
   12.46         return FileConstants::Error_FileNotFound;
   12.47     else if (errno == EACCES || errno == EPERM)
   12.48         return FileConstants::Error_Access;
   12.49     else if (errno == ENOSPC)
   12.50         return FileConstants::Error_DiskFull;
   12.51     else
   12.52         return FileConstants::Error_IOError;
   12.53 };
   12.54 
   12.55 #ifdef OVR_OS_WIN32
   12.56 #include "windows.h"
   12.57 // A simple helper class to disable/enable system error mode, if necessary
   12.58 // Disabling happens conditionally only if a drive name is involved
   12.59 class SysErrorModeDisabler
   12.60 {
   12.61     BOOL    Disabled;
   12.62     UINT    OldMode;
   12.63 public:
   12.64     SysErrorModeDisabler(const char* pfileName)
   12.65     {
   12.66         if (pfileName && (pfileName[0]!=0) && pfileName[1]==':')
   12.67         {
   12.68             Disabled = 1;
   12.69             OldMode = ::SetErrorMode(SEM_FAILCRITICALERRORS);
   12.70         }
   12.71         else
   12.72             Disabled = 0;
   12.73     }
   12.74 
   12.75     ~SysErrorModeDisabler()
   12.76     {
   12.77         if (Disabled) ::SetErrorMode(OldMode);
   12.78     }
   12.79 };
   12.80 #else
   12.81 class SysErrorModeDisabler
   12.82 {
   12.83 public:
   12.84     SysErrorModeDisabler(const char* pfileName) { }
   12.85 };
   12.86 #endif // OVR_OS_WIN32
   12.87 
   12.88 
   12.89 // This macro enables verification of I/O results after seeks against a pre-loaded
   12.90 // full file buffer copy. This is generally not necessary, but can been used to debug
   12.91 // memory corruptions; we've seen this fail due to EAX2/DirectSound corrupting memory
   12.92 // under FMOD with XP64 (32-bit) and Realtek HA Audio driver.
   12.93 //#define GFILE_VERIFY_SEEK_ERRORS
   12.94 
   12.95 
   12.96 // This is the simplest possible file implementation, it wraps around the descriptor
   12.97 // This file is delegated to by SysFile.
   12.98 
   12.99 class FILEFile : public File
  12.100 {
  12.101 protected:
  12.102 
  12.103     // Allocated filename
  12.104     String      FileName;
  12.105 
  12.106     // File handle & open mode
  12.107     bool        Opened;
  12.108     FILE*       fs;
  12.109     int         OpenFlags;
  12.110     // Error code for last request
  12.111     int         ErrorCode;
  12.112 
  12.113     int         LastOp;
  12.114 
  12.115 #ifdef OVR_FILE_VERIFY_SEEK_ERRORS
  12.116     UByte*      pFileTestBuffer;
  12.117     unsigned    FileTestLength;
  12.118     unsigned    TestPos; // File pointer position during tests.
  12.119 #endif
  12.120 
  12.121 public:
  12.122 
  12.123     FILEFile()
  12.124     {
  12.125         Opened = 0; FileName = "";
  12.126 
  12.127 #ifdef OVR_FILE_VERIFY_SEEK_ERRORS
  12.128         pFileTestBuffer =0;
  12.129         FileTestLength  =0;
  12.130         TestPos         =0;
  12.131 #endif
  12.132     }
  12.133     // Initialize file by opening it
  12.134     FILEFile(const String& fileName, int flags, int Mode);
  12.135     // The 'pfileName' should be encoded as UTF-8 to support international file names.
  12.136     FILEFile(const char* pfileName, int flags, int Mode);
  12.137 
  12.138     ~FILEFile()
  12.139     {
  12.140         if (Opened)
  12.141             Close();
  12.142     }
  12.143 
  12.144     virtual const char* GetFilePath();
  12.145 
  12.146     // ** File Information
  12.147     virtual bool        IsValid();
  12.148     virtual bool        IsWritable();
  12.149 
  12.150     // Return position / file size
  12.151     virtual int         Tell();
  12.152     virtual SInt64      LTell();
  12.153     virtual int         GetLength();
  12.154     virtual SInt64      LGetLength();
  12.155 
  12.156 //  virtual bool        Stat(FileStats *pfs);
  12.157     virtual int         GetErrorCode();
  12.158 
  12.159     // ** Stream implementation & I/O
  12.160     virtual int         Write(const UByte *pbuffer, int numBytes);
  12.161     virtual int         Read(UByte *pbuffer, int numBytes);
  12.162     virtual int         SkipBytes(int numBytes);
  12.163     virtual int         BytesAvailable();
  12.164     virtual bool        Flush();
  12.165     virtual int         Seek(int offset, int origin);
  12.166     virtual SInt64      LSeek(SInt64 offset, int origin);
  12.167     
  12.168     virtual int         CopyFromStream(File *pStream, int byteSize);
  12.169     virtual bool        Close();    
  12.170 private:
  12.171     void                init();
  12.172 };
  12.173 
  12.174 
  12.175 // Initialize file by opening it
  12.176 FILEFile::FILEFile(const String& fileName, int flags, int mode)
  12.177   : FileName(fileName), OpenFlags(flags)
  12.178 {
  12.179     OVR_UNUSED(mode);
  12.180     init();
  12.181 }
  12.182 
  12.183 // The 'pfileName' should be encoded as UTF-8 to support international file names.
  12.184 FILEFile::FILEFile(const char* pfileName, int flags, int mode)
  12.185   : FileName(pfileName), OpenFlags(flags)
  12.186 {
  12.187     OVR_UNUSED(mode);
  12.188     init();
  12.189 }
  12.190 
  12.191 void FILEFile::init()
  12.192 {
  12.193     // Open mode for file's open
  12.194     const char *omode = "rb";
  12.195 
  12.196     if (OpenFlags & Open_Truncate)
  12.197     {
  12.198         if (OpenFlags & Open_Read)
  12.199             omode = "w+b";
  12.200         else
  12.201             omode = "wb";
  12.202     }
  12.203     else if (OpenFlags & Open_Create)
  12.204     {
  12.205         if (OpenFlags & Open_Read)
  12.206             omode = "a+b";
  12.207         else
  12.208             omode = "ab";
  12.209     }
  12.210     else if (OpenFlags & Open_Write)
  12.211         omode = "r+b";
  12.212 
  12.213 #ifdef OVR_OS_WIN32
  12.214     SysErrorModeDisabler disabler(FileName.ToCStr());
  12.215 #endif
  12.216 
  12.217 #if defined(OVR_CC_MSVC) && (OVR_CC_MSVC >= 1400)
  12.218     wchar_t womode[16];
  12.219     wchar_t *pwFileName = (wchar_t*)OVR_ALLOC((UTF8Util::GetLength(FileName.ToCStr())+1) * sizeof(wchar_t));
  12.220     UTF8Util::DecodeString(pwFileName, FileName.ToCStr());
  12.221     OVR_ASSERT(strlen(omode) < sizeof(womode)/sizeof(womode[0]));
  12.222     UTF8Util::DecodeString(womode, omode);
  12.223     _wfopen_s(&fs, pwFileName, womode);
  12.224     OVR_FREE(pwFileName);
  12.225 #else
  12.226     fs = fopen(FileName.ToCStr(), omode);
  12.227 #endif
  12.228     if (fs)
  12.229         rewind (fs);
  12.230     Opened = (fs != NULL);
  12.231     // Set error code
  12.232     if (!Opened)
  12.233         ErrorCode = SFerror();
  12.234     else
  12.235     {
  12.236         // If we are testing file seek correctness, pre-load the entire file so
  12.237         // that we can do comparison tests later.
  12.238 #ifdef OVR_FILE_VERIFY_SEEK_ERRORS        
  12.239         TestPos         = 0;
  12.240         fseek(fs, 0, SEEK_END);
  12.241         FileTestLength  = ftell(fs);
  12.242         fseek(fs, 0, SEEK_SET);
  12.243         pFileTestBuffer = (UByte*)OVR_ALLOC(FileTestLength);
  12.244         if (pFileTestBuffer)
  12.245         {
  12.246             OVR_ASSERT(FileTestLength == (unsigned)Read(pFileTestBuffer, FileTestLength));
  12.247             Seek(0, Seek_Set);
  12.248         }        
  12.249 #endif
  12.250 
  12.251         ErrorCode = 0;
  12.252     }
  12.253     LastOp = 0;
  12.254 }
  12.255 
  12.256 
  12.257 const char* FILEFile::GetFilePath()
  12.258 {
  12.259     return FileName.ToCStr();
  12.260 }
  12.261 
  12.262 
  12.263 // ** File Information
  12.264 bool    FILEFile::IsValid()
  12.265 {
  12.266     return Opened;
  12.267 }
  12.268 bool    FILEFile::IsWritable()
  12.269 {
  12.270     return IsValid() && (OpenFlags&Open_Write);
  12.271 }
  12.272 /*
  12.273 bool    FILEFile::IsRecoverable()
  12.274 {
  12.275     return IsValid() && ((OpenFlags&OVR_FO_SAFETRUNC) == OVR_FO_SAFETRUNC);
  12.276 }
  12.277 */
  12.278 
  12.279 // Return position / file size
  12.280 int     FILEFile::Tell()
  12.281 {
  12.282     int pos = (int)ftell (fs);
  12.283     if (pos < 0)
  12.284         ErrorCode = SFerror();
  12.285     return pos;
  12.286 }
  12.287 
  12.288 SInt64  FILEFile::LTell()
  12.289 {
  12.290     SInt64 pos = ftell(fs);
  12.291     if (pos < 0)
  12.292         ErrorCode = SFerror();
  12.293     return pos;
  12.294 }
  12.295 
  12.296 int     FILEFile::GetLength()
  12.297 {
  12.298     int pos = Tell();
  12.299     if (pos >= 0)
  12.300     {
  12.301         Seek (0, Seek_End);
  12.302         int size = Tell();
  12.303         Seek (pos, Seek_Set);
  12.304         return size;
  12.305     }
  12.306     return -1;
  12.307 }
  12.308 SInt64  FILEFile::LGetLength()
  12.309 {
  12.310     SInt64 pos = LTell();
  12.311     if (pos >= 0)
  12.312     {
  12.313         LSeek (0, Seek_End);
  12.314         SInt64 size = LTell();
  12.315         LSeek (pos, Seek_Set);
  12.316         return size;
  12.317     }
  12.318     return -1;
  12.319 }
  12.320 
  12.321 int     FILEFile::GetErrorCode()
  12.322 {
  12.323     return ErrorCode;
  12.324 }
  12.325 
  12.326 // ** Stream implementation & I/O
  12.327 int     FILEFile::Write(const UByte *pbuffer, int numBytes)
  12.328 {
  12.329     if (LastOp && LastOp != Open_Write)
  12.330         fflush(fs);
  12.331     LastOp = Open_Write;
  12.332     int written = (int) fwrite(pbuffer, 1, numBytes, fs);
  12.333     if (written < numBytes)
  12.334         ErrorCode = SFerror();
  12.335 
  12.336 #ifdef OVR_FILE_VERIFY_SEEK_ERRORS
  12.337     if (written > 0)
  12.338         TestPos += written;
  12.339 #endif
  12.340 
  12.341     return written;
  12.342 }
  12.343 
  12.344 int     FILEFile::Read(UByte *pbuffer, int numBytes)
  12.345 {
  12.346     if (LastOp && LastOp != Open_Read)
  12.347         fflush(fs);
  12.348     LastOp = Open_Read;
  12.349     int read = (int) fread(pbuffer, 1, numBytes, fs);
  12.350     if (read < numBytes)
  12.351         ErrorCode = SFerror();
  12.352 
  12.353 #ifdef OVR_FILE_VERIFY_SEEK_ERRORS
  12.354     if (read > 0)
  12.355     {
  12.356         // Read-in data must match our pre-loaded buffer data!
  12.357         UByte* pcompareBuffer = pFileTestBuffer + TestPos;
  12.358         for (int i=0; i< read; i++)
  12.359         {
  12.360             OVR_ASSERT(pcompareBuffer[i] == pbuffer[i]);
  12.361         }
  12.362 
  12.363         //OVR_ASSERT(!memcmp(pFileTestBuffer + TestPos, pbuffer, read));
  12.364         TestPos += read;
  12.365         OVR_ASSERT(ftell(fs) == (int)TestPos);
  12.366     }
  12.367 #endif
  12.368 
  12.369     return read;
  12.370 }
  12.371 
  12.372 // Seeks ahead to skip bytes
  12.373 int     FILEFile::SkipBytes(int numBytes)
  12.374 {
  12.375     SInt64 pos    = LTell();
  12.376     SInt64 newPos = LSeek(numBytes, Seek_Cur);
  12.377 
  12.378     // Return -1 for major error
  12.379     if ((pos==-1) || (newPos==-1))
  12.380     {
  12.381         return -1;
  12.382     }
  12.383     //ErrorCode = ((NewPos-Pos)<numBytes) ? errno : 0;
  12.384 
  12.385     return int (newPos-(int)pos);
  12.386 }
  12.387 
  12.388 // Return # of bytes till EOF
  12.389 int     FILEFile::BytesAvailable()
  12.390 {
  12.391     SInt64 pos    = LTell();
  12.392     SInt64 endPos = LGetLength();
  12.393 
  12.394     // Return -1 for major error
  12.395     if ((pos==-1) || (endPos==-1))
  12.396     {
  12.397         ErrorCode = SFerror();
  12.398         return 0;
  12.399     }
  12.400     else
  12.401         ErrorCode = 0;
  12.402 
  12.403     return int (endPos-(int)pos);
  12.404 }
  12.405 
  12.406 // Flush file contents
  12.407 bool    FILEFile::Flush()
  12.408 {
  12.409     return !fflush(fs);
  12.410 }
  12.411 
  12.412 int     FILEFile::Seek(int offset, int origin)
  12.413 {
  12.414     int newOrigin = 0;
  12.415     switch(origin)
  12.416     {
  12.417     case Seek_Set: newOrigin = SEEK_SET; break;
  12.418     case Seek_Cur: newOrigin = SEEK_CUR; break;
  12.419     case Seek_End: newOrigin = SEEK_END; break;
  12.420     }
  12.421 
  12.422     if (newOrigin == SEEK_SET && offset == Tell())
  12.423         return Tell();
  12.424 
  12.425     if (fseek (fs, offset, newOrigin))
  12.426     {
  12.427 #ifdef OVR_FILE_VERIFY_SEEK_ERRORS
  12.428         OVR_ASSERT(0);
  12.429 #endif
  12.430         return -1;
  12.431     }
  12.432     
  12.433 #ifdef OVR_FILE_VERIFY_SEEK_ERRORS
  12.434     // Track file position after seeks for read verification later.
  12.435     switch(origin)
  12.436     {
  12.437     case Seek_Set:  TestPos = offset;       break;
  12.438     case Seek_Cur:  TestPos += offset;      break;    
  12.439     case Seek_End:  TestPos = FileTestLength + offset; break;
  12.440     }
  12.441     OVR_ASSERT((int)TestPos == Tell());
  12.442 #endif
  12.443 
  12.444     return (int)Tell();
  12.445 }
  12.446 
  12.447 SInt64  FILEFile::LSeek(SInt64 offset, int origin)
  12.448 {
  12.449     return Seek((int)offset,origin);
  12.450 }
  12.451 
  12.452 int FILEFile::CopyFromStream(File *pstream, int byteSize)
  12.453 {
  12.454     UByte   buff[0x4000];
  12.455     int     count = 0;
  12.456     int     szRequest, szRead, szWritten;
  12.457 
  12.458     while (byteSize)
  12.459     {
  12.460         szRequest = (byteSize > int(sizeof(buff))) ? int(sizeof(buff)) : byteSize;
  12.461 
  12.462         szRead    = pstream->Read(buff, szRequest);
  12.463         szWritten = 0;
  12.464         if (szRead > 0)
  12.465             szWritten = Write(buff, szRead);
  12.466 
  12.467         count    += szWritten;
  12.468         byteSize -= szWritten;
  12.469         if (szWritten < szRequest)
  12.470             break;
  12.471     }
  12.472     return count;
  12.473 }
  12.474 
  12.475 
  12.476 bool FILEFile::Close()
  12.477 {
  12.478 #ifdef OVR_FILE_VERIFY_SEEK_ERRORS
  12.479     if (pFileTestBuffer)
  12.480     {
  12.481         OVR_FREE(pFileTestBuffer);
  12.482         pFileTestBuffer = 0;
  12.483         FileTestLength  = 0;
  12.484     }
  12.485 #endif
  12.486 
  12.487     bool closeRet = !fclose(fs);
  12.488 
  12.489     if (!closeRet)
  12.490     {
  12.491         ErrorCode = SFerror();
  12.492         return 0;
  12.493     }
  12.494     else
  12.495     {
  12.496         Opened    = 0;
  12.497         fs        = 0;
  12.498         ErrorCode = 0;
  12.499     }
  12.500 
  12.501     // Handle safe truncate
  12.502     /*
  12.503     if ((OpenFlags & OVR_FO_SAFETRUNC) == OVR_FO_SAFETRUNC)
  12.504     {
  12.505         // Delete original file (if it existed)
  12.506         DWORD oldAttributes = FileUtilWin32::GetFileAttributes(FileName);
  12.507         if (oldAttributes!=0xFFFFFFFF)
  12.508             if (!FileUtilWin32::DeleteFile(FileName))
  12.509             {
  12.510                 // Try to remove the readonly attribute
  12.511                 FileUtilWin32::SetFileAttributes(FileName, oldAttributes & (~FILE_ATTRIBUTE_READONLY) );
  12.512                 // And delete the file again
  12.513                 if (!FileUtilWin32::DeleteFile(FileName))
  12.514                     return 0;
  12.515             }
  12.516 
  12.517         // Rename temp file to real filename
  12.518         if (!FileUtilWin32::MoveFile(TempName, FileName))
  12.519         {
  12.520             //ErrorCode = errno;
  12.521             return 0;
  12.522         }
  12.523     }
  12.524     */
  12.525     return 1;
  12.526 }
  12.527 
  12.528 /*
  12.529 bool    FILEFile::CloseCancel()
  12.530 {
  12.531     bool closeRet = (bool)::CloseHandle(fd);
  12.532 
  12.533     if (!closeRet)
  12.534     {
  12.535         //ErrorCode = errno;
  12.536         return 0;
  12.537     }
  12.538     else
  12.539     {
  12.540         Opened    = 0;
  12.541         fd        = INVALID_HANDLE_VALUE;
  12.542         ErrorCode = 0;
  12.543     }
  12.544 
  12.545     // Handle safe truncate (delete tmp file, leave original unchanged)
  12.546     if ((OpenFlags&OVR_FO_SAFETRUNC) == OVR_FO_SAFETRUNC)
  12.547         if (!FileUtilWin32::DeleteFile(TempName))
  12.548         {
  12.549             //ErrorCode = errno;
  12.550             return 0;
  12.551         }
  12.552     return 1;
  12.553 }
  12.554 */
  12.555 
  12.556 File *FileFILEOpen(const String& path, int flags, int mode)
  12.557 {
  12.558     return new FILEFile(path, flags, mode);
  12.559 }
  12.560 
  12.561 // Helper function: obtain file information time.
  12.562 bool    SysFile::GetFileStat(FileStat* pfileStat, const String& path)
  12.563 {
  12.564 #if defined(OVR_OS_WIN32)
  12.565     // 64-bit implementation on Windows.
  12.566     struct __stat64 fileStat;
  12.567     // Stat returns 0 for success.
  12.568     wchar_t *pwpath = (wchar_t*)OVR_ALLOC((UTF8Util::GetLength(path.ToCStr())+1)*sizeof(wchar_t));
  12.569     UTF8Util::DecodeString(pwpath, path.ToCStr());
  12.570 
  12.571     int ret = _wstat64(pwpath, &fileStat);
  12.572     OVR_FREE(pwpath);
  12.573     if (ret) return false;
  12.574 #else
  12.575     struct stat fileStat;
  12.576     // Stat returns 0 for success.
  12.577     if (stat(path, &fileStat) != 0)
  12.578         return false;
  12.579 #endif
  12.580     pfileStat->AccessTime = fileStat.st_atime;
  12.581     pfileStat->ModifyTime = fileStat.st_mtime;
  12.582     pfileStat->FileSize   = fileStat.st_size;
  12.583     return true;
  12.584 }
  12.585 
  12.586 } // Scaleform
  12.587 \ No newline at end of file
  12.588 +/**************************************************************************
  12.589 +
  12.590 +Filename    :   OVR_FileFILE.cpp
  12.591 +Content     :   File wrapper class implementation (Win32)
  12.592 +
  12.593 +Created     :   April 5, 1999
  12.594 +Authors     :   Michael Antonov
  12.595 +
  12.596 +Copyright   :   Copyright 2012 Oculus VR, Inc. All Rights reserved.
  12.597 +
  12.598 +Use of this software is subject to the terms of the Oculus license
  12.599 +agreement provided at the time of installation or download, or which
  12.600 +otherwise accompanies this software in either electronic or hard copy form.
  12.601 +
  12.602 +**************************************************************************/
  12.603 +
  12.604 +#define  GFILE_CXX
  12.605 +
  12.606 +#include "OVR_Types.h"
  12.607 +#include "OVR_Log.h"
  12.608 +
  12.609 +// Standard C library (Captain Obvious guarantees!)
  12.610 +#include <stdio.h>
  12.611 +#ifndef OVR_OS_WINCE
  12.612 +#include <sys/stat.h>
  12.613 +#endif
  12.614 +
  12.615 +#include "OVR_SysFile.h"
  12.616 +
  12.617 +#ifndef OVR_OS_WINCE
  12.618 +#include <errno.h>
  12.619 +#endif
  12.620 +
  12.621 +namespace OVR {
  12.622 +
  12.623 +// ***** File interface
  12.624 +
  12.625 +// ***** FILEFile - C streams file
  12.626 +
  12.627 +static int SFerror ()
  12.628 +{
  12.629 +    if (errno == ENOENT)
  12.630 +        return FileConstants::Error_FileNotFound;
  12.631 +    else if (errno == EACCES || errno == EPERM)
  12.632 +        return FileConstants::Error_Access;
  12.633 +    else if (errno == ENOSPC)
  12.634 +        return FileConstants::Error_DiskFull;
  12.635 +    else
  12.636 +        return FileConstants::Error_IOError;
  12.637 +};
  12.638 +
  12.639 +#ifdef OVR_OS_WIN32
  12.640 +#include "windows.h"
  12.641 +// A simple helper class to disable/enable system error mode, if necessary
  12.642 +// Disabling happens conditionally only if a drive name is involved
  12.643 +class SysErrorModeDisabler
  12.644 +{
  12.645 +    BOOL    Disabled;
  12.646 +    UINT    OldMode;
  12.647 +public:
  12.648 +    SysErrorModeDisabler(const char* pfileName)
  12.649 +    {
  12.650 +        if (pfileName && (pfileName[0]!=0) && pfileName[1]==':')
  12.651 +        {
  12.652 +            Disabled = 1;
  12.653 +            OldMode = ::SetErrorMode(SEM_FAILCRITICALERRORS);
  12.654 +        }
  12.655 +        else
  12.656 +            Disabled = 0;
  12.657 +    }
  12.658 +
  12.659 +    ~SysErrorModeDisabler()
  12.660 +    {
  12.661 +        if (Disabled) ::SetErrorMode(OldMode);
  12.662 +    }
  12.663 +};
  12.664 +#else
  12.665 +class SysErrorModeDisabler
  12.666 +{
  12.667 +public:
  12.668 +    SysErrorModeDisabler(const char* pfileName) { }
  12.669 +};
  12.670 +#endif // OVR_OS_WIN32
  12.671 +
  12.672 +
  12.673 +// This macro enables verification of I/O results after seeks against a pre-loaded
  12.674 +// full file buffer copy. This is generally not necessary, but can been used to debug
  12.675 +// memory corruptions; we've seen this fail due to EAX2/DirectSound corrupting memory
  12.676 +// under FMOD with XP64 (32-bit) and Realtek HA Audio driver.
  12.677 +//#define GFILE_VERIFY_SEEK_ERRORS
  12.678 +
  12.679 +
  12.680 +// This is the simplest possible file implementation, it wraps around the descriptor
  12.681 +// This file is delegated to by SysFile.
  12.682 +
  12.683 +class FILEFile : public File
  12.684 +{
  12.685 +protected:
  12.686 +
  12.687 +    // Allocated filename
  12.688 +    String      FileName;
  12.689 +
  12.690 +    // File handle & open mode
  12.691 +    bool        Opened;
  12.692 +    FILE*       fs;
  12.693 +    int         OpenFlags;
  12.694 +    // Error code for last request
  12.695 +    int         ErrorCode;
  12.696 +
  12.697 +    int         LastOp;
  12.698 +
  12.699 +#ifdef OVR_FILE_VERIFY_SEEK_ERRORS
  12.700 +    UByte*      pFileTestBuffer;
  12.701 +    unsigned    FileTestLength;
  12.702 +    unsigned    TestPos; // File pointer position during tests.
  12.703 +#endif
  12.704 +
  12.705 +public:
  12.706 +
  12.707 +    FILEFile()
  12.708 +    {
  12.709 +        Opened = 0; FileName = "";
  12.710 +
  12.711 +#ifdef OVR_FILE_VERIFY_SEEK_ERRORS
  12.712 +        pFileTestBuffer =0;
  12.713 +        FileTestLength  =0;
  12.714 +        TestPos         =0;
  12.715 +#endif
  12.716 +    }
  12.717 +    // Initialize file by opening it
  12.718 +    FILEFile(const String& fileName, int flags, int Mode);
  12.719 +    // The 'pfileName' should be encoded as UTF-8 to support international file names.
  12.720 +    FILEFile(const char* pfileName, int flags, int Mode);
  12.721 +
  12.722 +    ~FILEFile()
  12.723 +    {
  12.724 +        if (Opened)
  12.725 +            Close();
  12.726 +    }
  12.727 +
  12.728 +    virtual const char* GetFilePath();
  12.729 +
  12.730 +    // ** File Information
  12.731 +    virtual bool        IsValid();
  12.732 +    virtual bool        IsWritable();
  12.733 +
  12.734 +    // Return position / file size
  12.735 +    virtual int         Tell();
  12.736 +    virtual SInt64      LTell();
  12.737 +    virtual int         GetLength();
  12.738 +    virtual SInt64      LGetLength();
  12.739 +
  12.740 +//  virtual bool        Stat(FileStats *pfs);
  12.741 +    virtual int         GetErrorCode();
  12.742 +
  12.743 +    // ** Stream implementation & I/O
  12.744 +    virtual int         Write(const UByte *pbuffer, int numBytes);
  12.745 +    virtual int         Read(UByte *pbuffer, int numBytes);
  12.746 +    virtual int         SkipBytes(int numBytes);
  12.747 +    virtual int         BytesAvailable();
  12.748 +    virtual bool        Flush();
  12.749 +    virtual int         Seek(int offset, int origin);
  12.750 +    virtual SInt64      LSeek(SInt64 offset, int origin);
  12.751 +    
  12.752 +    virtual int         CopyFromStream(File *pStream, int byteSize);
  12.753 +    virtual bool        Close();    
  12.754 +private:
  12.755 +    void                init();
  12.756 +};
  12.757 +
  12.758 +
  12.759 +// Initialize file by opening it
  12.760 +FILEFile::FILEFile(const String& fileName, int flags, int mode)
  12.761 +  : FileName(fileName), OpenFlags(flags)
  12.762 +{
  12.763 +    OVR_UNUSED(mode);
  12.764 +    init();
  12.765 +}
  12.766 +
  12.767 +// The 'pfileName' should be encoded as UTF-8 to support international file names.
  12.768 +FILEFile::FILEFile(const char* pfileName, int flags, int mode)
  12.769 +  : FileName(pfileName), OpenFlags(flags)
  12.770 +{
  12.771 +    OVR_UNUSED(mode);
  12.772 +    init();
  12.773 +}
  12.774 +
  12.775 +void FILEFile::init()
  12.776 +{
  12.777 +    // Open mode for file's open
  12.778 +    const char *omode = "rb";
  12.779 +
  12.780 +    if (OpenFlags & Open_Truncate)
  12.781 +    {
  12.782 +        if (OpenFlags & Open_Read)
  12.783 +            omode = "w+b";
  12.784 +        else
  12.785 +            omode = "wb";
  12.786 +    }
  12.787 +    else if (OpenFlags & Open_Create)
  12.788 +    {
  12.789 +        if (OpenFlags & Open_Read)
  12.790 +            omode = "a+b";
  12.791 +        else
  12.792 +            omode = "ab";
  12.793 +    }
  12.794 +    else if (OpenFlags & Open_Write)
  12.795 +        omode = "r+b";
  12.796 +
  12.797 +#ifdef OVR_OS_WIN32
  12.798 +    SysErrorModeDisabler disabler(FileName.ToCStr());
  12.799 +#endif
  12.800 +
  12.801 +#if defined(OVR_CC_MSVC) && (OVR_CC_MSVC >= 1400)
  12.802 +    wchar_t womode[16];
  12.803 +    wchar_t *pwFileName = (wchar_t*)OVR_ALLOC((UTF8Util::GetLength(FileName.ToCStr())+1) * sizeof(wchar_t));
  12.804 +    UTF8Util::DecodeString(pwFileName, FileName.ToCStr());
  12.805 +    OVR_ASSERT(strlen(omode) < sizeof(womode)/sizeof(womode[0]));
  12.806 +    UTF8Util::DecodeString(womode, omode);
  12.807 +    _wfopen_s(&fs, pwFileName, womode);
  12.808 +    OVR_FREE(pwFileName);
  12.809 +#else
  12.810 +    fs = fopen(FileName.ToCStr(), omode);
  12.811 +#endif
  12.812 +    if (fs)
  12.813 +        rewind (fs);
  12.814 +    Opened = (fs != NULL);
  12.815 +    // Set error code
  12.816 +    if (!Opened)
  12.817 +        ErrorCode = SFerror();
  12.818 +    else
  12.819 +    {
  12.820 +        // If we are testing file seek correctness, pre-load the entire file so
  12.821 +        // that we can do comparison tests later.
  12.822 +#ifdef OVR_FILE_VERIFY_SEEK_ERRORS        
  12.823 +        TestPos         = 0;
  12.824 +        fseek(fs, 0, SEEK_END);
  12.825 +        FileTestLength  = ftell(fs);
  12.826 +        fseek(fs, 0, SEEK_SET);
  12.827 +        pFileTestBuffer = (UByte*)OVR_ALLOC(FileTestLength);
  12.828 +        if (pFileTestBuffer)
  12.829 +        {
  12.830 +            OVR_ASSERT(FileTestLength == (unsigned)Read(pFileTestBuffer, FileTestLength));
  12.831 +            Seek(0, Seek_Set);
  12.832 +        }        
  12.833 +#endif
  12.834 +
  12.835 +        ErrorCode = 0;
  12.836 +    }
  12.837 +    LastOp = 0;
  12.838 +}
  12.839 +
  12.840 +
  12.841 +const char* FILEFile::GetFilePath()
  12.842 +{
  12.843 +    return FileName.ToCStr();
  12.844 +}
  12.845 +
  12.846 +
  12.847 +// ** File Information
  12.848 +bool    FILEFile::IsValid()
  12.849 +{
  12.850 +    return Opened;
  12.851 +}
  12.852 +bool    FILEFile::IsWritable()
  12.853 +{
  12.854 +    return IsValid() && (OpenFlags&Open_Write);
  12.855 +}
  12.856 +/*
  12.857 +bool    FILEFile::IsRecoverable()
  12.858 +{
  12.859 +    return IsValid() && ((OpenFlags&OVR_FO_SAFETRUNC) == OVR_FO_SAFETRUNC);
  12.860 +}
  12.861 +*/
  12.862 +
  12.863 +// Return position / file size
  12.864 +int     FILEFile::Tell()
  12.865 +{
  12.866 +    int pos = (int)ftell (fs);
  12.867 +    if (pos < 0)
  12.868 +        ErrorCode = SFerror();
  12.869 +    return pos;
  12.870 +}
  12.871 +
  12.872 +SInt64  FILEFile::LTell()
  12.873 +{
  12.874 +    SInt64 pos = ftell(fs);
  12.875 +    if (pos < 0)
  12.876 +        ErrorCode = SFerror();
  12.877 +    return pos;
  12.878 +}
  12.879 +
  12.880 +int     FILEFile::GetLength()
  12.881 +{
  12.882 +    int pos = Tell();
  12.883 +    if (pos >= 0)
  12.884 +    {
  12.885 +        Seek (0, Seek_End);
  12.886 +        int size = Tell();
  12.887 +        Seek (pos, Seek_Set);
  12.888 +        return size;
  12.889 +    }
  12.890 +    return -1;
  12.891 +}
  12.892 +SInt64  FILEFile::LGetLength()
  12.893 +{
  12.894 +    SInt64 pos = LTell();
  12.895 +    if (pos >= 0)
  12.896 +    {
  12.897 +        LSeek (0, Seek_End);
  12.898 +        SInt64 size = LTell();
  12.899 +        LSeek (pos, Seek_Set);
  12.900 +        return size;
  12.901 +    }
  12.902 +    return -1;
  12.903 +}
  12.904 +
  12.905 +int     FILEFile::GetErrorCode()
  12.906 +{
  12.907 +    return ErrorCode;
  12.908 +}
  12.909 +
  12.910 +// ** Stream implementation & I/O
  12.911 +int     FILEFile::Write(const UByte *pbuffer, int numBytes)
  12.912 +{
  12.913 +    if (LastOp && LastOp != Open_Write)
  12.914 +        fflush(fs);
  12.915 +    LastOp = Open_Write;
  12.916 +    int written = (int) fwrite(pbuffer, 1, numBytes, fs);
  12.917 +    if (written < numBytes)
  12.918 +        ErrorCode = SFerror();
  12.919 +
  12.920 +#ifdef OVR_FILE_VERIFY_SEEK_ERRORS
  12.921 +    if (written > 0)
  12.922 +        TestPos += written;
  12.923 +#endif
  12.924 +
  12.925 +    return written;
  12.926 +}
  12.927 +
  12.928 +int     FILEFile::Read(UByte *pbuffer, int numBytes)
  12.929 +{
  12.930 +    if (LastOp && LastOp != Open_Read)
  12.931 +        fflush(fs);
  12.932 +    LastOp = Open_Read;
  12.933 +    int read = (int) fread(pbuffer, 1, numBytes, fs);
  12.934 +    if (read < numBytes)
  12.935 +        ErrorCode = SFerror();
  12.936 +
  12.937 +#ifdef OVR_FILE_VERIFY_SEEK_ERRORS
  12.938 +    if (read > 0)
  12.939 +    {
  12.940 +        // Read-in data must match our pre-loaded buffer data!
  12.941 +        UByte* pcompareBuffer = pFileTestBuffer + TestPos;
  12.942 +        for (int i=0; i< read; i++)
  12.943 +        {
  12.944 +            OVR_ASSERT(pcompareBuffer[i] == pbuffer[i]);
  12.945 +        }
  12.946 +
  12.947 +        //OVR_ASSERT(!memcmp(pFileTestBuffer + TestPos, pbuffer, read));
  12.948 +        TestPos += read;
  12.949 +        OVR_ASSERT(ftell(fs) == (int)TestPos);
  12.950 +    }
  12.951 +#endif
  12.952 +
  12.953 +    return read;
  12.954 +}
  12.955 +
  12.956 +// Seeks ahead to skip bytes
  12.957 +int     FILEFile::SkipBytes(int numBytes)
  12.958 +{
  12.959 +    SInt64 pos    = LTell();
  12.960 +    SInt64 newPos = LSeek(numBytes, Seek_Cur);
  12.961 +
  12.962 +    // Return -1 for major error
  12.963 +    if ((pos==-1) || (newPos==-1))
  12.964 +    {
  12.965 +        return -1;
  12.966 +    }
  12.967 +    //ErrorCode = ((NewPos-Pos)<numBytes) ? errno : 0;
  12.968 +
  12.969 +    return int (newPos-(int)pos);
  12.970 +}
  12.971 +
  12.972 +// Return # of bytes till EOF
  12.973 +int     FILEFile::BytesAvailable()
  12.974 +{
  12.975 +    SInt64 pos    = LTell();
  12.976 +    SInt64 endPos = LGetLength();
  12.977 +
  12.978 +    // Return -1 for major error
  12.979 +    if ((pos==-1) || (endPos==-1))
  12.980 +    {
  12.981 +        ErrorCode = SFerror();
  12.982 +        return 0;
  12.983 +    }
  12.984 +    else
  12.985 +        ErrorCode = 0;
  12.986 +
  12.987 +    return int (endPos-(int)pos);
  12.988 +}
  12.989 +
  12.990 +// Flush file contents
  12.991 +bool    FILEFile::Flush()
  12.992 +{
  12.993 +    return !fflush(fs);
  12.994 +}
  12.995 +
  12.996 +int     FILEFile::Seek(int offset, int origin)
  12.997 +{
  12.998 +    int newOrigin = 0;
  12.999 +    switch(origin)
 12.1000 +    {
 12.1001 +    case Seek_Set: newOrigin = SEEK_SET; break;
 12.1002 +    case Seek_Cur: newOrigin = SEEK_CUR; break;
 12.1003 +    case Seek_End: newOrigin = SEEK_END; break;
 12.1004 +    }
 12.1005 +
 12.1006 +    if (newOrigin == SEEK_SET && offset == Tell())
 12.1007 +        return Tell();
 12.1008 +
 12.1009 +    if (fseek (fs, offset, newOrigin))
 12.1010 +    {
 12.1011 +#ifdef OVR_FILE_VERIFY_SEEK_ERRORS
 12.1012 +        OVR_ASSERT(0);
 12.1013 +#endif
 12.1014 +        return -1;
 12.1015 +    }
 12.1016 +    
 12.1017 +#ifdef OVR_FILE_VERIFY_SEEK_ERRORS
 12.1018 +    // Track file position after seeks for read verification later.
 12.1019 +    switch(origin)
 12.1020 +    {
 12.1021 +    case Seek_Set:  TestPos = offset;       break;
 12.1022 +    case Seek_Cur:  TestPos += offset;      break;    
 12.1023 +    case Seek_End:  TestPos = FileTestLength + offset; break;
 12.1024 +    }
 12.1025 +    OVR_ASSERT((int)TestPos == Tell());
 12.1026 +#endif
 12.1027 +
 12.1028 +    return (int)Tell();
 12.1029 +}
 12.1030 +
 12.1031 +SInt64  FILEFile::LSeek(SInt64 offset, int origin)
 12.1032 +{
 12.1033 +    return Seek((int)offset,origin);
 12.1034 +}
 12.1035 +
 12.1036 +int FILEFile::CopyFromStream(File *pstream, int byteSize)
 12.1037 +{
 12.1038 +    UByte   buff[0x4000];
 12.1039 +    int     count = 0;
 12.1040 +    int     szRequest, szRead, szWritten;
 12.1041 +
 12.1042 +    while (byteSize)
 12.1043 +    {
 12.1044 +        szRequest = (byteSize > int(sizeof(buff))) ? int(sizeof(buff)) : byteSize;
 12.1045 +
 12.1046 +        szRead    = pstream->Read(buff, szRequest);
 12.1047 +        szWritten = 0;
 12.1048 +        if (szRead > 0)
 12.1049 +            szWritten = Write(buff, szRead);
 12.1050 +
 12.1051 +        count    += szWritten;
 12.1052 +        byteSize -= szWritten;
 12.1053 +        if (szWritten < szRequest)
 12.1054 +            break;
 12.1055 +    }
 12.1056 +    return count;
 12.1057 +}
 12.1058 +
 12.1059 +
 12.1060 +bool FILEFile::Close()
 12.1061 +{
 12.1062 +#ifdef OVR_FILE_VERIFY_SEEK_ERRORS
 12.1063 +    if (pFileTestBuffer)
 12.1064 +    {
 12.1065 +        OVR_FREE(pFileTestBuffer);
 12.1066 +        pFileTestBuffer = 0;
 12.1067 +        FileTestLength  = 0;
 12.1068 +    }
 12.1069 +#endif
 12.1070 +
 12.1071 +    bool closeRet = !fclose(fs);
 12.1072 +
 12.1073 +    if (!closeRet)
 12.1074 +    {
 12.1075 +        ErrorCode = SFerror();
 12.1076 +        return 0;
 12.1077 +    }
 12.1078 +    else
 12.1079 +    {
 12.1080 +        Opened    = 0;
 12.1081 +        fs        = 0;
 12.1082 +        ErrorCode = 0;
 12.1083 +    }
 12.1084 +
 12.1085 +    // Handle safe truncate
 12.1086 +    /*
 12.1087 +    if ((OpenFlags & OVR_FO_SAFETRUNC) == OVR_FO_SAFETRUNC)
 12.1088 +    {
 12.1089 +        // Delete original file (if it existed)
 12.1090 +        DWORD oldAttributes = FileUtilWin32::GetFileAttributes(FileName);
 12.1091 +        if (oldAttributes!=0xFFFFFFFF)
 12.1092 +            if (!FileUtilWin32::DeleteFile(FileName))
 12.1093 +            {
 12.1094 +                // Try to remove the readonly attribute
 12.1095 +                FileUtilWin32::SetFileAttributes(FileName, oldAttributes & (~FILE_ATTRIBUTE_READONLY) );
 12.1096 +                // And delete the file again
 12.1097 +                if (!FileUtilWin32::DeleteFile(FileName))
 12.1098 +                    return 0;
 12.1099 +            }
 12.1100 +
 12.1101 +        // Rename temp file to real filename
 12.1102 +        if (!FileUtilWin32::MoveFile(TempName, FileName))
 12.1103 +        {
 12.1104 +            //ErrorCode = errno;
 12.1105 +            return 0;
 12.1106 +        }
 12.1107 +    }
 12.1108 +    */
 12.1109 +    return 1;
 12.1110 +}
 12.1111 +
 12.1112 +/*
 12.1113 +bool    FILEFile::CloseCancel()
 12.1114 +{
 12.1115 +    bool closeRet = (bool)::CloseHandle(fd);
 12.1116 +
 12.1117 +    if (!closeRet)
 12.1118 +    {
 12.1119 +        //ErrorCode = errno;
 12.1120 +        return 0;
 12.1121 +    }
 12.1122 +    else
 12.1123 +    {
 12.1124 +        Opened    = 0;
 12.1125 +        fd        = INVALID_HANDLE_VALUE;
 12.1126 +        ErrorCode = 0;
 12.1127 +    }
 12.1128 +
 12.1129 +    // Handle safe truncate (delete tmp file, leave original unchanged)
 12.1130 +    if ((OpenFlags&OVR_FO_SAFETRUNC) == OVR_FO_SAFETRUNC)
 12.1131 +        if (!FileUtilWin32::DeleteFile(TempName))
 12.1132 +        {
 12.1133 +            //ErrorCode = errno;
 12.1134 +            return 0;
 12.1135 +        }
 12.1136 +    return 1;
 12.1137 +}
 12.1138 +*/
 12.1139 +
 12.1140 +File *FileFILEOpen(const String& path, int flags, int mode)
 12.1141 +{
 12.1142 +    return new FILEFile(path, flags, mode);
 12.1143 +}
 12.1144 +
 12.1145 +// Helper function: obtain file information time.
 12.1146 +bool    SysFile::GetFileStat(FileStat* pfileStat, const String& path)
 12.1147 +{
 12.1148 +#if defined(OVR_OS_WIN32)
 12.1149 +    // 64-bit implementation on Windows.
 12.1150 +    struct __stat64 fileStat;
 12.1151 +    // Stat returns 0 for success.
 12.1152 +    wchar_t *pwpath = (wchar_t*)OVR_ALLOC((UTF8Util::GetLength(path.ToCStr())+1)*sizeof(wchar_t));
 12.1153 +    UTF8Util::DecodeString(pwpath, path.ToCStr());
 12.1154 +
 12.1155 +    int ret = _wstat64(pwpath, &fileStat);
 12.1156 +    OVR_FREE(pwpath);
 12.1157 +    if (ret) return false;
 12.1158 +#else
 12.1159 +    struct stat fileStat;
 12.1160 +    // Stat returns 0 for success.
 12.1161 +    if (stat(path, &fileStat) != 0)
 12.1162 +        return false;
 12.1163 +#endif
 12.1164 +    pfileStat->AccessTime = fileStat.st_atime;
 12.1165 +    pfileStat->ModifyTime = fileStat.st_mtime;
 12.1166 +    pfileStat->FileSize   = fileStat.st_size;
 12.1167 +    return true;
 12.1168 +}
 12.1169 +
 12.1170 +} // Scaleform
    13.1 --- a/libovr/Src/Kernel/OVR_Hash.h	Sat Sep 14 17:51:03 2013 +0300
    13.2 +++ b/libovr/Src/Kernel/OVR_Hash.h	Sun Sep 15 04:10:05 2013 +0300
    13.3 @@ -1,1 +1,1291 @@
    13.4 -/************************************************************************************
    13.5 
    13.6 PublicHeader:   None
    13.7 Filename    :   OVR_Hash.h
    13.8 Content     :   Template hash-table/set implementation
    13.9 Created     :   September 19, 2012
   13.10 Notes       : 
   13.11 
   13.12 Copyright   :   Copyright 2012 Oculus VR, Inc. All Rights reserved.
   13.13 
   13.14 Use of this software is subject to the terms of the Oculus license
   13.15 agreement provided at the time of installation or download, or which
   13.16 otherwise accompanies this software in either electronic or hard copy form.
   13.17 
   13.18 ************************************************************************************/
   13.19 
   13.20 #ifndef OVR_Hash_h
   13.21 #define OVR_Hash_h
   13.22 
   13.23 #include "OVR_ContainerAllocator.h"
   13.24 #include "OVR_Alg.h"
   13.25 
   13.26 // 'new' operator is redefined/used in this file.
   13.27 #undef new
   13.28 
   13.29 namespace OVR {
   13.30 
   13.31 //-----------------------------------------------------------------------------------
   13.32 // ***** Hash Table Implementation
   13.33 
   13.34 // HastSet and Hash.
   13.35 //
   13.36 // Hash table, linear probing, internal chaining.  One  interesting/nice thing
   13.37 // about this implementation is that the table itself is a flat chunk of memory
   13.38 // containing no pointers, only relative indices. If the key and value types
   13.39 // of the Hash contain no pointers, then the Hash can be serialized using raw IO.
   13.40 //
   13.41 // Never shrinks, unless you explicitly Clear() it.  Expands on
   13.42 // demand, though.  For best results, if you know roughly how big your
   13.43 // table will be, default it to that size when you create it.
   13.44 //
   13.45 // Key usability feature:
   13.46 //
   13.47 //   1. Allows node hash values to either be cached or not.
   13.48 //
   13.49 //   2. Allows for alternative keys with methods such as GetAlt(). Handy
   13.50 //      if you need to search nodes by their components; no need to create
   13.51 //      temporary nodes.
   13.52 //
   13.53 
   13.54 
   13.55 // *** Hash functors:
   13.56 //
   13.57 //  IdentityHash  - use when the key is already a good hash
   13.58 //  HFixedSizeHash - general hash based on object's in-memory representation.
   13.59 
   13.60 
   13.61 // Hash is just the input value; can use this for integer-indexed hash tables.
   13.62 template<class C>
   13.63 class IdentityHash
   13.64 {
   13.65 public:
   13.66     UPInt operator()(const C& data) const
   13.67     { return (UPInt) data; }
   13.68 };
   13.69 
   13.70 // Computes a hash of an object's representation.
   13.71 template<class C>
   13.72 class FixedSizeHash
   13.73 {
   13.74 public:
   13.75     // Alternative: "sdbm" hash function, suggested at same web page
   13.76     // above, http::/www.cs.yorku.ca/~oz/hash.html
   13.77     // This is somewhat slower then Bernstein, but it works way better than the above
   13.78     // hash function for hashing large numbers of 32-bit ints.
   13.79     static OVR_FORCE_INLINE UPInt SDBM_Hash(const void* data_in, UPInt size, UPInt seed = 5381)     
   13.80     {
   13.81         const UByte* data = (const UByte*) data_in;
   13.82         UPInt        h = seed;
   13.83         while (size > 0)
   13.84         {
   13.85             size--;
   13.86             h = (h << 16) + (h << 6) - h + (UPInt)data[size];
   13.87         }   
   13.88         return h;
   13.89     }
   13.90 
   13.91     UPInt operator()(const C& data) const
   13.92     {
   13.93         unsigned char*  p = (unsigned char*) &data;
   13.94         int size = sizeof(C);
   13.95 
   13.96         return SDBM_Hash(p, size);
   13.97     }
   13.98 };
   13.99 
  13.100 
  13.101 
  13.102 // *** HashsetEntry Entry types. 
  13.103 
  13.104 // Compact hash table Entry type that re-computes hash keys during hash traversal.
  13.105 // Good to use if the hash function is cheap or the hash value is already cached in C.
  13.106 template<class C, class HashF>
  13.107 class HashsetEntry
  13.108 {
  13.109 public:
  13.110     // Internal chaining for collisions.
  13.111     SPInt       NextInChain;
  13.112     C           Value;
  13.113 
  13.114     HashsetEntry()
  13.115         : NextInChain(-2) { }
  13.116     HashsetEntry(const HashsetEntry& e)
  13.117         : NextInChain(e.NextInChain), Value(e.Value) { }
  13.118     HashsetEntry(const C& key, SPInt next)
  13.119         : NextInChain(next), Value(key) { }
  13.120 
  13.121     bool    IsEmpty() const          { return NextInChain == -2;  }
  13.122     bool    IsEndOfChain() const     { return NextInChain == -1;  }
  13.123 
  13.124     // Cached hash value access - can be optimized bu storing hash locally.
  13.125     // Mask value only needs to be used if SetCachedHash is not implemented.
  13.126     UPInt   GetCachedHash(UPInt maskValue) const  { return HashF()(Value) & maskValue; }
  13.127     void    SetCachedHash(UPInt)                  {}
  13.128 
  13.129     void    Clear()
  13.130     {        
  13.131         Value.~C(); // placement delete
  13.132         NextInChain = -2;
  13.133     }
  13.134     // Free is only used from dtor of hash; Clear is used during regular operations:
  13.135     // assignment, hash reallocations, value reassignments, so on.
  13.136     void    Free() { Clear(); }
  13.137 };
  13.138 
  13.139 // Hash table Entry type that caches the Entry hash value for nodes, so that it
  13.140 // does not need to be re-computed during access.
  13.141 template<class C, class HashF>
  13.142 class HashsetCachedEntry
  13.143 {
  13.144 public:
  13.145     // Internal chaining for collisions.
  13.146     SPInt       NextInChain;
  13.147     UPInt       HashValue;
  13.148     C           Value;
  13.149 
  13.150     HashsetCachedEntry()
  13.151         : NextInChain(-2) { }
  13.152     HashsetCachedEntry(const HashsetCachedEntry& e)
  13.153         : NextInChain(e.NextInChain), HashValue(e.HashValue), Value(e.Value) { }
  13.154     HashsetCachedEntry(const C& key, SPInt next)
  13.155         : NextInChain(next), Value(key) { }
  13.156 
  13.157     bool    IsEmpty() const          { return NextInChain == -2;  }
  13.158     bool    IsEndOfChain() const     { return NextInChain == -1;  }
  13.159 
  13.160     // Cached hash value access - can be optimized bu storing hash locally.
  13.161     // Mask value only needs to be used if SetCachedHash is not implemented.
  13.162     UPInt   GetCachedHash(UPInt maskValue) const  { OVR_UNUSED(maskValue); return HashValue; }
  13.163     void    SetCachedHash(UPInt hashValue)        { HashValue = hashValue; }
  13.164 
  13.165     void    Clear()
  13.166     {
  13.167         Value.~C();
  13.168         NextInChain = -2;
  13.169     }
  13.170     // Free is only used from dtor of hash; Clear is used during regular operations:
  13.171     // assignment, hash reallocations, value reassignments, so on.
  13.172     void    Free() { Clear(); }
  13.173 };
  13.174 
  13.175 
  13.176 //-----------------------------------------------------------------------------------
  13.177 // *** HashSet implementation - relies on either cached or regular entries.
  13.178 //
  13.179 // Use: Entry = HashsetCachedEntry<C, HashF> if hashes are expensive to
  13.180 //              compute and thus need caching in entries.
  13.181 //      Entry = HashsetEntry<C, HashF> if hashes are already externally cached.
  13.182 //
  13.183 template<class C, class HashF = FixedSizeHash<C>,
  13.184          class AltHashF = HashF, 
  13.185          class Allocator = ContainerAllocator<C>,
  13.186          class Entry = HashsetCachedEntry<C, HashF> >
  13.187 class HashSetBase
  13.188 {
  13.189     enum { HashMinSize = 8 };
  13.190 
  13.191 public:
  13.192     OVR_MEMORY_REDEFINE_NEW(HashSetBase)
  13.193 
  13.194     typedef HashSetBase<C, HashF, AltHashF, Allocator, Entry>    SelfType;
  13.195 
  13.196     HashSetBase() : pTable(NULL)                       {   }
  13.197     HashSetBase(int sizeHint) : pTable(NULL)           { SetCapacity(this, sizeHint);  }
  13.198     HashSetBase(const SelfType& src) : pTable(NULL)    { Assign(this, src); }
  13.199 
  13.200     ~HashSetBase()                                     
  13.201     { 
  13.202         if (pTable)
  13.203         {
  13.204             // Delete the entries.
  13.205             for (UPInt i = 0, n = pTable->SizeMask; i <= n; i++)
  13.206             {
  13.207                 Entry*  e = &E(i);
  13.208                 if (!e->IsEmpty())             
  13.209                     e->Free();
  13.210             }            
  13.211 
  13.212             Allocator::Free(pTable);
  13.213             pTable = NULL;
  13.214         }
  13.215     }
  13.216 
  13.217 
  13.218     void Assign(const SelfType& src)
  13.219     {
  13.220         Clear();
  13.221         if (src.IsEmpty() == false)
  13.222         {
  13.223             SetCapacity(src.GetSize());
  13.224 
  13.225             for (ConstIterator it = src.Begin(); it != src.End(); ++it)
  13.226             {
  13.227                 Add(*it);
  13.228             }
  13.229         }
  13.230     }
  13.231 
  13.232 
  13.233     // Remove all entries from the HashSet table.
  13.234     void Clear() 
  13.235     {
  13.236         if (pTable)
  13.237         {
  13.238             // Delete the entries.
  13.239             for (UPInt i = 0, n = pTable->SizeMask; i <= n; i++)
  13.240             {
  13.241                 Entry*  e = &E(i);
  13.242                 if (!e->IsEmpty())             
  13.243                     e->Clear();
  13.244             }            
  13.245                 
  13.246             Allocator::Free(pTable);
  13.247             pTable = NULL;
  13.248         }
  13.249     }
  13.250 
  13.251     // Returns true if the HashSet is empty.
  13.252     bool IsEmpty() const
  13.253     {
  13.254         return pTable == NULL || pTable->EntryCount == 0;
  13.255     }
  13.256 
  13.257 
  13.258     // Set a new or existing value under the key, to the value.
  13.259     // Pass a different class of 'key' so that assignment reference object
  13.260     // can be passed instead of the actual object.
  13.261     template<class CRef>
  13.262     void Set(const CRef& key)
  13.263     {
  13.264         UPInt  hashValue = HashF()(key);
  13.265         SPInt  index     = (SPInt)-1;
  13.266 
  13.267         if (pTable != NULL)
  13.268             index = findIndexCore(key, hashValue & pTable->SizeMask);
  13.269 
  13.270         if (index >= 0)
  13.271         {            
  13.272             E(index).Value = key;
  13.273         }
  13.274         else
  13.275         {
  13.276             // Entry under key doesn't exist.
  13.277             add(key, hashValue);
  13.278         }
  13.279     }
  13.280 
  13.281     template<class CRef>
  13.282     inline void Add(const CRef& key)
  13.283     {
  13.284         UPInt hashValue = HashF()(key);
  13.285         add(key, hashValue);
  13.286     }
  13.287 
  13.288     // Remove by alternative key.
  13.289     template<class K>
  13.290     void RemoveAlt(const K& key)
  13.291     {   
  13.292         if (pTable == NULL)
  13.293             return;
  13.294 
  13.295         UPInt   hashValue = AltHashF()(key);
  13.296         SPInt   index     = hashValue & pTable->SizeMask;
  13.297 
  13.298         Entry*  e = &E(index);
  13.299 
  13.300         // If empty node or occupied by collider, we have nothing to remove.
  13.301         if (e->IsEmpty() || (e->GetCachedHash(pTable->SizeMask) != (UPInt)index))
  13.302             return;        
  13.303 
  13.304         // Save index
  13.305         SPInt   naturalIndex = index;
  13.306         SPInt   prevIndex    = -1;
  13.307 
  13.308         while ((e->GetCachedHash(pTable->SizeMask) != (UPInt)naturalIndex) || !(e->Value == key))
  13.309         {
  13.310             // Keep looking through the chain.
  13.311             prevIndex   = index;
  13.312             index       = e->NextInChain;
  13.313             if (index == -1)
  13.314                 return; // End of chain, item not found
  13.315             e = &E(index);
  13.316         }
  13.317 
  13.318         // Found it - our item is at index
  13.319         if (naturalIndex == index)
  13.320         {
  13.321             // If we have a follower, move it to us
  13.322             if (!e->IsEndOfChain())
  13.323             {               
  13.324                 Entry*  enext = &E(e->NextInChain);
  13.325                 e->Clear();
  13.326                 new (e) Entry(*enext);
  13.327                 // Point us to the follower's cell that will be cleared
  13.328                 e = enext;
  13.329             }
  13.330         }
  13.331         else
  13.332         {
  13.333             // We are not at natural index, so deal with the prev items next index
  13.334             E(prevIndex).NextInChain = e->NextInChain;
  13.335         }
  13.336 
  13.337         // Clear us, of the follower cell that was moved.
  13.338         e->Clear();
  13.339         pTable->EntryCount --;
  13.340         // Should we check the size to condense hash? ...
  13.341     }
  13.342 
  13.343     // Remove by main key.
  13.344     template<class CRef>
  13.345     void Remove(const CRef& key)
  13.346     {
  13.347         RemoveAlt(key);
  13.348     }
  13.349 
  13.350     // Retrieve the pointer to a value under the given key.
  13.351     //  - If there's no value under the key, then return NULL.    
  13.352     //  - If there is a value, return the pointer.    
  13.353     template<class K>
  13.354     C* Get(const K& key)
  13.355     {
  13.356         SPInt   index = findIndex(key);
  13.357         if (index >= 0)        
  13.358             return &E(index).Value;        
  13.359         return 0;
  13.360     }   
  13.361 
  13.362     template<class K>
  13.363     const C* Get(const K& key) const
  13.364     {
  13.365         SPInt   index = findIndex(key);
  13.366         if (index >= 0)        
  13.367             return &E(index).Value;        
  13.368         return 0;
  13.369     }
  13.370 
  13.371     // Alternative key versions of Get. Used by Hash.
  13.372     template<class K>
  13.373     const C* GetAlt(const K& key) const
  13.374     {
  13.375         SPInt   index = findIndexAlt(key);
  13.376         if (index >= 0)        
  13.377             return &E(index).Value;
  13.378         return 0;
  13.379     }
  13.380 
  13.381     template<class K>
  13.382     C* GetAlt(const K& key)
  13.383     {
  13.384         SPInt   index = findIndexAlt(key);
  13.385         if (index >= 0)        
  13.386             return &E(index).Value;
  13.387         return 0;
  13.388     }   
  13.389 
  13.390     template<class K>
  13.391     bool GetAlt(const K& key, C* pval) const
  13.392     {
  13.393         SPInt   index = findIndexAlt(key);
  13.394         if (index >= 0)
  13.395         {
  13.396             if (pval)
  13.397                 *pval = E(index).Value;
  13.398             return true;
  13.399         }
  13.400         return false;
  13.401     }
  13.402 
  13.403 
  13.404     UPInt GetSize() const
  13.405     {
  13.406         return pTable == NULL ? 0 : (UPInt)pTable->EntryCount;
  13.407     }
  13.408 
  13.409 
  13.410     // Resize the HashSet table to fit one more Entry.  Often this
  13.411     // doesn't involve any action.
  13.412     void CheckExpand()
  13.413     {
  13.414         if (pTable == NULL)
  13.415         {
  13.416             // Initial creation of table.  Make a minimum-sized table.
  13.417             setRawCapacity(HashMinSize);
  13.418         }
  13.419         else if (pTable->EntryCount * 5 > (pTable->SizeMask + 1) * 4)
  13.420         {
  13.421             // pTable is more than 5/4 ths full.  Expand.
  13.422             setRawCapacity((pTable->SizeMask + 1) * 2);
  13.423         }
  13.424     }
  13.425 
  13.426     // Hint the bucket count to >= n.
  13.427     void Resize(UPInt n)    
  13.428     {
  13.429         // Not really sure what this means in relation to
  13.430         // STLport's hash_map... they say they "increase the
  13.431         // bucket count to at least n" -- but does that mean
  13.432         // their real capacity after Resize(n) is more like
  13.433         // n*2 (since they do linked-list chaining within
  13.434         // buckets?).
  13.435         SetCapacity(n);
  13.436     }
  13.437 
  13.438     // Size the HashSet so that it can comfortably contain the given
  13.439     // number of elements.  If the HashSet already contains more
  13.440     // elements than newSize, then this may be a no-op.
  13.441     void SetCapacity(UPInt newSize)
  13.442     {
  13.443         UPInt newRawSize = (newSize * 5) / 4;
  13.444         if (newRawSize <= GetSize())
  13.445             return;
  13.446         setRawCapacity(newRawSize);
  13.447     }
  13.448 
  13.449     // Disable inappropriate 'operator ->' warning on MSVC6.
  13.450 #ifdef OVR_CC_MSVC
  13.451 #if (OVR_CC_MSVC < 1300)
  13.452 # pragma warning(disable : 4284)
  13.453 #endif
  13.454 #endif
  13.455 
  13.456     // Iterator API, like STL.
  13.457     struct ConstIterator
  13.458     {   
  13.459         const C&    operator * () const
  13.460         {            
  13.461             OVR_ASSERT(Index >= 0 && Index <= (SPInt)pHash->pTable->SizeMask);
  13.462             return pHash->E(Index).Value;
  13.463         }
  13.464 
  13.465         const C*    operator -> () const
  13.466         {
  13.467             OVR_ASSERT(Index >= 0 && Index <= (SPInt)pHash->pTable->SizeMask);
  13.468             return &pHash->E(Index).Value;
  13.469         }
  13.470 
  13.471         void    operator ++ ()
  13.472         {
  13.473             // Find next non-empty Entry.
  13.474             if (Index <= (SPInt)pHash->pTable->SizeMask)
  13.475             {
  13.476                 Index++;
  13.477                 while ((UPInt)Index <= pHash->pTable->SizeMask &&
  13.478                     pHash->E(Index).IsEmpty())
  13.479                 {
  13.480                     Index++;
  13.481                 }
  13.482             }
  13.483         }
  13.484 
  13.485         bool    operator == (const ConstIterator& it) const
  13.486         {
  13.487             if (IsEnd() && it.IsEnd())
  13.488             {
  13.489                 return true;
  13.490             }
  13.491             else
  13.492             {
  13.493                 return (pHash == it.pHash) && (Index == it.Index);
  13.494             }
  13.495         }
  13.496 
  13.497         bool    operator != (const ConstIterator& it) const
  13.498         {
  13.499             return ! (*this == it);
  13.500         }
  13.501 
  13.502 
  13.503         bool    IsEnd() const
  13.504         {
  13.505             return (pHash == NULL) || 
  13.506                 (pHash->pTable == NULL) || 
  13.507                 (Index > (SPInt)pHash->pTable->SizeMask);
  13.508         }
  13.509 
  13.510         ConstIterator()
  13.511             : pHash(NULL), Index(0)
  13.512         { }
  13.513 
  13.514     public:
  13.515         // Constructor was intentionally made public to allow create
  13.516         // iterator with arbitrary index.
  13.517         ConstIterator(const SelfType* h, SPInt index)
  13.518             : pHash(h), Index(index)
  13.519         { }
  13.520 
  13.521         const SelfType* GetContainer() const
  13.522         {
  13.523             return pHash;
  13.524         }
  13.525         SPInt GetIndex() const
  13.526         {
  13.527             return Index;
  13.528         }
  13.529 
  13.530     protected:
  13.531         friend class HashSetBase<C, HashF, AltHashF, Allocator, Entry>;
  13.532 
  13.533         const SelfType* pHash;
  13.534         SPInt           Index;
  13.535     };
  13.536 
  13.537     friend struct ConstIterator;
  13.538 
  13.539 
  13.540     // Non-const Iterator; Get most of it from ConstIterator.
  13.541     struct Iterator : public ConstIterator
  13.542     {      
  13.543         // Allow non-const access to entries.
  13.544         C&  operator*() const
  13.545         {            
  13.546             OVR_ASSERT(ConstIterator::Index >= 0 && ConstIterator::Index <= (SPInt)ConstIterator::pHash->pTable->SizeMask);
  13.547             return const_cast<SelfType*>(ConstIterator::pHash)->E(ConstIterator::Index).Value;
  13.548         }    
  13.549 
  13.550         C*  operator->() const 
  13.551         {
  13.552             return &(operator*());
  13.553         }
  13.554 
  13.555         Iterator()
  13.556             : ConstIterator(NULL, 0)
  13.557         { }
  13.558 
  13.559         // Removes current element from Hash
  13.560         void Remove()
  13.561         {
  13.562             RemoveAlt(operator*());
  13.563         }
  13.564 
  13.565         template <class K>
  13.566         void RemoveAlt(const K& key)
  13.567         {
  13.568             SelfType*   phash = const_cast<SelfType*>(ConstIterator::pHash);
  13.569             //Entry*      ee = &phash->E(ConstIterator::Index);
  13.570             //const C&    key = ee->Value;
  13.571 
  13.572             UPInt       hashValue = AltHashF()(key);
  13.573             SPInt       index     = hashValue & phash->pTable->SizeMask;
  13.574 
  13.575             Entry*      e = &phash->E(index);
  13.576 
  13.577             // If empty node or occupied by collider, we have nothing to remove.
  13.578             if (e->IsEmpty() || (e->GetCachedHash(phash->pTable->SizeMask) != (UPInt)index))
  13.579                 return;        
  13.580 
  13.581             // Save index
  13.582             SPInt   naturalIndex = index;
  13.583             SPInt   prevIndex    = -1;
  13.584 
  13.585             while ((e->GetCachedHash(phash->pTable->SizeMask) != (UPInt)naturalIndex) || !(e->Value == key))
  13.586             {
  13.587                 // Keep looking through the chain.
  13.588                 prevIndex   = index;
  13.589                 index       = e->NextInChain;
  13.590                 if (index == -1)
  13.591                     return; // End of chain, item not found
  13.592                 e = &phash->E(index);
  13.593             }
  13.594 
  13.595             if (index == (SPInt)ConstIterator::Index)
  13.596             {
  13.597                 // Found it - our item is at index
  13.598                 if (naturalIndex == index)
  13.599                 {
  13.600                     // If we have a follower, move it to us
  13.601                     if (!e->IsEndOfChain())
  13.602                     {               
  13.603                         Entry*  enext = &phash->E(e->NextInChain);
  13.604                         e->Clear();
  13.605                         new (e) Entry(*enext);
  13.606                         // Point us to the follower's cell that will be cleared
  13.607                         e = enext;
  13.608                         --ConstIterator::Index;
  13.609                     }
  13.610                 }
  13.611                 else
  13.612                 {
  13.613                     // We are not at natural index, so deal with the prev items next index
  13.614                     phash->E(prevIndex).NextInChain = e->NextInChain;
  13.615                 }
  13.616 
  13.617                 // Clear us, of the follower cell that was moved.
  13.618                 e->Clear();
  13.619                 phash->pTable->EntryCount --;
  13.620             }
  13.621             else 
  13.622                 OVR_ASSERT(0); //?
  13.623         }
  13.624 
  13.625     private:
  13.626         friend class HashSetBase<C, HashF, AltHashF, Allocator, Entry>;
  13.627 
  13.628         Iterator(SelfType* h, SPInt i0)
  13.629             : ConstIterator(h, i0)
  13.630         { }
  13.631     };
  13.632 
  13.633     friend struct Iterator;
  13.634 
  13.635     Iterator    Begin()
  13.636     {
  13.637         if (pTable == 0)
  13.638             return Iterator(NULL, 0);
  13.639 
  13.640         // Scan till we hit the First valid Entry.
  13.641         UPInt  i0 = 0;
  13.642         while (i0 <= pTable->SizeMask && E(i0).IsEmpty())
  13.643         {
  13.644             i0++;
  13.645         }
  13.646         return Iterator(this, i0);
  13.647     }
  13.648     Iterator        End()           { return Iterator(NULL, 0); }
  13.649 
  13.650     ConstIterator   Begin() const   { return const_cast<SelfType*>(this)->Begin();     }
  13.651     ConstIterator   End() const     { return const_cast<SelfType*>(this)->End();   }
  13.652 
  13.653     template<class K>
  13.654     Iterator Find(const K& key)
  13.655     {
  13.656         SPInt index = findIndex(key);
  13.657         if (index >= 0)        
  13.658             return Iterator(this, index);        
  13.659         return Iterator(NULL, 0);
  13.660     }
  13.661 
  13.662     template<class K>
  13.663     Iterator FindAlt(const K& key)
  13.664     {
  13.665         SPInt index = findIndexAlt(key);
  13.666         if (index >= 0)        
  13.667             return Iterator(this, index);        
  13.668         return Iterator(NULL, 0);
  13.669     }
  13.670 
  13.671     template<class K>
  13.672     ConstIterator Find(const K& key) const       { return const_cast<SelfType*>(this)->Find(key); }
  13.673 
  13.674     template<class K>
  13.675     ConstIterator FindAlt(const K& key) const    { return const_cast<SelfType*>(this)->FindAlt(key); }
  13.676 
  13.677 private:
  13.678     // Find the index of the matching Entry.  If no match, then return -1.
  13.679     template<class K>
  13.680     SPInt findIndex(const K& key) const
  13.681     {
  13.682         if (pTable == NULL)
  13.683             return -1;
  13.684         UPInt hashValue = HashF()(key) & pTable->SizeMask;
  13.685         return findIndexCore(key, hashValue);
  13.686     }
  13.687 
  13.688     template<class K>
  13.689     SPInt findIndexAlt(const K& key) const
  13.690     {
  13.691         if (pTable == NULL)
  13.692             return -1;
  13.693         UPInt hashValue = AltHashF()(key) & pTable->SizeMask;
  13.694         return findIndexCore(key, hashValue);
  13.695     }
  13.696 
  13.697     // Find the index of the matching Entry.  If no match, then return -1.
  13.698     template<class K>
  13.699     SPInt findIndexCore(const K& key, UPInt hashValue) const
  13.700     {
  13.701         // Table must exist.
  13.702         OVR_ASSERT(pTable != 0);
  13.703         // Hash key must be 'and-ed' by the caller.
  13.704         OVR_ASSERT((hashValue & ~pTable->SizeMask) == 0);
  13.705 
  13.706         UPInt           index = hashValue;
  13.707         const Entry*    e     = &E(index);
  13.708 
  13.709         // If empty or occupied by a collider, not found.
  13.710         if (e->IsEmpty() || (e->GetCachedHash(pTable->SizeMask) != index))
  13.711             return -1;
  13.712 
  13.713         while(1)
  13.714         {
  13.715             OVR_ASSERT(e->GetCachedHash(pTable->SizeMask) == hashValue);
  13.716 
  13.717             if (e->GetCachedHash(pTable->SizeMask) == hashValue && e->Value == key)
  13.718             {
  13.719                 // Found it.
  13.720                 return index;
  13.721             }
  13.722             // Values can not be equal at this point.
  13.723             // That would mean that the hash key for the same value differs.
  13.724             OVR_ASSERT(!(e->Value == key));
  13.725 
  13.726             // Keep looking through the chain.
  13.727             index = e->NextInChain;
  13.728             if (index == (UPInt)-1)
  13.729                 break; // end of chain
  13.730 
  13.731             e = &E(index);
  13.732             OVR_ASSERT(!e->IsEmpty());
  13.733         }
  13.734         return -1;
  13.735     }
  13.736 
  13.737 
  13.738     // Add a new value to the HashSet table, under the specified key.
  13.739     template<class CRef>
  13.740     void add(const CRef& key, UPInt hashValue)
  13.741     {
  13.742         CheckExpand();
  13.743         hashValue &= pTable->SizeMask;
  13.744 
  13.745         pTable->EntryCount++;
  13.746 
  13.747         SPInt   index        = hashValue;
  13.748         Entry*  naturalEntry = &(E(index));
  13.749 
  13.750         if (naturalEntry->IsEmpty())
  13.751         {
  13.752             // Put the new Entry in.
  13.753             new (naturalEntry) Entry(key, -1);
  13.754         }
  13.755         else
  13.756         {
  13.757             // Find a blank spot.
  13.758             SPInt blankIndex = index;
  13.759             do {
  13.760                 blankIndex = (blankIndex + 1) & pTable->SizeMask;
  13.761             } while(!E(blankIndex).IsEmpty());
  13.762 
  13.763             Entry*  blankEntry = &E(blankIndex);
  13.764 
  13.765             if (naturalEntry->GetCachedHash(pTable->SizeMask) == (UPInt)index)
  13.766             {
  13.767                 // Collision.  Link into this chain.
  13.768 
  13.769                 // Move existing list head.
  13.770                 new (blankEntry) Entry(*naturalEntry);    // placement new, copy ctor
  13.771 
  13.772                 // Put the new info in the natural Entry.
  13.773                 naturalEntry->Value       = key;
  13.774                 naturalEntry->NextInChain = blankIndex;
  13.775             }
  13.776             else
  13.777             {
  13.778                 // Existing Entry does not naturally
  13.779                 // belong in this slot.  Existing
  13.780                 // Entry must be moved.
  13.781 
  13.782                 // Find natural location of collided element (i.e. root of chain)
  13.783                 SPInt collidedIndex = naturalEntry->GetCachedHash(pTable->SizeMask);
  13.784                 OVR_ASSERT(collidedIndex >= 0 && collidedIndex <= (SPInt)pTable->SizeMask);
  13.785                 for (;;)
  13.786                 {
  13.787                     Entry*  e = &E(collidedIndex);
  13.788                     if (e->NextInChain == index)
  13.789                     {
  13.790                         // Here's where we need to splice.
  13.791                         new (blankEntry) Entry(*naturalEntry);
  13.792                         e->NextInChain = blankIndex;
  13.793                         break;
  13.794                     }
  13.795                     collidedIndex = e->NextInChain;
  13.796                     OVR_ASSERT(collidedIndex >= 0 && collidedIndex <= (SPInt)pTable->SizeMask);
  13.797                 }
  13.798 
  13.799                 // Put the new data in the natural Entry.
  13.800                 naturalEntry->Value       = key;
  13.801                 naturalEntry->NextInChain = -1;                
  13.802             }            
  13.803         }
  13.804 
  13.805         // Record hash value: has effect only if cached node is used.
  13.806         naturalEntry->SetCachedHash(hashValue);
  13.807     }
  13.808 
  13.809     // Index access helpers.
  13.810     Entry& E(UPInt index)
  13.811     {
  13.812         // Must have pTable and access needs to be within bounds.
  13.813         OVR_ASSERT(index <= pTable->SizeMask);
  13.814         return *(((Entry*) (pTable + 1)) + index);
  13.815     }
  13.816     const Entry& E(UPInt index) const
  13.817     {        
  13.818         OVR_ASSERT(index <= pTable->SizeMask);
  13.819         return *(((Entry*) (pTable + 1)) + index);
  13.820     }
  13.821 
  13.822 
  13.823     // Resize the HashSet table to the given size (Rehash the
  13.824     // contents of the current table).  The arg is the number of
  13.825     // HashSet table entries, not the number of elements we should
  13.826     // actually contain (which will be less than this).
  13.827     void    setRawCapacity(UPInt newSize)    
  13.828     {
  13.829         if (newSize == 0)
  13.830         {
  13.831             // Special case.
  13.832             Clear();
  13.833             return;
  13.834         }
  13.835 
  13.836         // Minimum size; don't incur rehashing cost when expanding
  13.837         // very small tables. Not that we perform this check before 
  13.838         // 'log2f' call to avoid fp exception with newSize == 1.
  13.839         if (newSize < HashMinSize)        
  13.840             newSize = HashMinSize;       
  13.841         else
  13.842         {
  13.843             // Force newSize to be a power of two.
  13.844             int bits = Alg::UpperBit(newSize-1) + 1; // Chop( Log2f((float)(newSize-1)) + 1);
  13.845             OVR_ASSERT((UPInt(1) << bits) >= newSize);
  13.846             newSize = UPInt(1) << bits;
  13.847         }
  13.848 
  13.849         SelfType  newHash;
  13.850         newHash.pTable = (TableType*)
  13.851             Allocator::Alloc(                
  13.852                 sizeof(TableType) + sizeof(Entry) * newSize);
  13.853         // Need to do something on alloc failure!
  13.854         OVR_ASSERT(newHash.pTable);
  13.855 
  13.856         newHash.pTable->EntryCount = 0;
  13.857         newHash.pTable->SizeMask = newSize - 1;
  13.858         UPInt i, n;
  13.859 
  13.860         // Mark all entries as empty.
  13.861         for (i = 0; i < newSize; i++)
  13.862             newHash.E(i).NextInChain = -2;
  13.863 
  13.864         // Copy stuff to newHash
  13.865         if (pTable)
  13.866         {            
  13.867             for (i = 0, n = pTable->SizeMask; i <= n; i++)
  13.868             {
  13.869                 Entry*  e = &E(i);
  13.870                 if (e->IsEmpty() == false)
  13.871                 {
  13.872                     // Insert old Entry into new HashSet.
  13.873                     newHash.Add(e->Value);
  13.874                     // placement delete of old element
  13.875                     e->Clear();
  13.876                 }
  13.877             }
  13.878 
  13.879             // Delete our old data buffer.
  13.880             Allocator::Free(pTable);
  13.881         }
  13.882 
  13.883         // Steal newHash's data.
  13.884         pTable = newHash.pTable;
  13.885         newHash.pTable = NULL;
  13.886     }
  13.887 
  13.888     struct TableType
  13.889     {
  13.890         UPInt EntryCount;
  13.891         UPInt SizeMask;
  13.892         // Entry array follows this structure
  13.893         // in memory.
  13.894     };
  13.895     TableType*  pTable;
  13.896 };
  13.897 
  13.898 
  13.899 
  13.900 //-----------------------------------------------------------------------------------
  13.901 template<class C, class HashF = FixedSizeHash<C>,
  13.902          class AltHashF = HashF, 
  13.903          class Allocator = ContainerAllocator<C>,
  13.904          class Entry = HashsetCachedEntry<C, HashF> >
  13.905 class HashSet : public HashSetBase<C, HashF, AltHashF, Allocator, Entry>
  13.906 {
  13.907 public:
  13.908     typedef HashSetBase<C, HashF, AltHashF, Allocator, Entry> BaseType;
  13.909     typedef HashSet<C, HashF, AltHashF, Allocator, Entry>     SelfType;
  13.910 
  13.911     HashSet()                                      {   }
  13.912     HashSet(int sizeHint) : BaseType(sizeHint)     {   }
  13.913     HashSet(const SelfType& src) : BaseType(src)   {   }
  13.914     ~HashSet()                                     {   }
  13.915 
  13.916     void operator = (const SelfType& src)   { BaseType::Assign(src); }
  13.917 
  13.918     // Set a new or existing value under the key, to the value.
  13.919     // Pass a different class of 'key' so that assignment reference object
  13.920     // can be passed instead of the actual object.
  13.921     template<class CRef>
  13.922     void Set(const CRef& key)
  13.923     {
  13.924         BaseType::Set(key);
  13.925     }
  13.926 
  13.927     template<class CRef>
  13.928     inline void Add(const CRef& key)
  13.929     {
  13.930         BaseType::Add(key);
  13.931     }
  13.932 
  13.933     // Hint the bucket count to >= n.
  13.934     void Resize(UPInt n)    
  13.935     {
  13.936         BaseType::SetCapacity(n);
  13.937     }
  13.938 
  13.939     // Size the HashSet so that it can comfortably contain the given
  13.940     // number of elements.  If the HashSet already contains more
  13.941     // elements than newSize, then this may be a no-op.
  13.942     void SetCapacity(UPInt newSize)
  13.943     {
  13.944         BaseType::SetCapacity(newSize);
  13.945     }
  13.946 
  13.947 };
  13.948 
  13.949 // HashSet with uncached hash code; declared for convenience.
  13.950 template<class C, class HashF = FixedSizeHash<C>,
  13.951                   class AltHashF = HashF,
  13.952                   class Allocator = ContainerAllocator<C> >
  13.953 class HashSetUncached : public HashSet<C, HashF, AltHashF, Allocator, HashsetEntry<C, HashF> >
  13.954 {
  13.955 public:
  13.956     
  13.957     typedef HashSetUncached<C, HashF, AltHashF, Allocator>                  SelfType;
  13.958     typedef HashSet<C, HashF, AltHashF, Allocator, HashsetEntry<C, HashF> > BaseType;
  13.959 
  13.960     // Delegated constructors.
  13.961     HashSetUncached()                                        { }
  13.962     HashSetUncached(int sizeHint) : BaseType(sizeHint)       { }
  13.963     HashSetUncached(const SelfType& src) : BaseType(src)     { }
  13.964     ~HashSetUncached()                                       { }
  13.965     
  13.966     void    operator = (const SelfType& src)
  13.967     {
  13.968         BaseType::operator = (src);
  13.969     }
  13.970 };
  13.971 
  13.972 
  13.973 //-----------------------------------------------------------------------------------
  13.974 // ***** Hash hash table implementation
  13.975 
  13.976 // Node for Hash - necessary so that Hash can delegate its implementation
  13.977 // to HashSet.
  13.978 template<class C, class U, class HashF>
  13.979 struct HashNode
  13.980 {
  13.981     typedef HashNode<C, U, HashF>   SelfType;
  13.982     typedef C                       FirstType;
  13.983     typedef U                       SecondType;
  13.984 
  13.985     C   First;
  13.986     U   Second;
  13.987 
  13.988     // NodeRef is used to allow passing of elements into HashSet
  13.989     // without using a temporary object.
  13.990     struct NodeRef
  13.991     {
  13.992         const C*   pFirst;
  13.993         const U*   pSecond;
  13.994 
  13.995         NodeRef(const C& f, const U& s) : pFirst(&f), pSecond(&s) { }
  13.996         NodeRef(const NodeRef& src)     : pFirst(src.pFirst), pSecond(src.pSecond) { }
  13.997 
  13.998         // Enable computation of ghash_node_hashf.
  13.999         inline UPInt GetHash() const            { return HashF()(*pFirst); } 
 13.1000         // Necessary conversion to allow HashNode::operator == to work.
 13.1001         operator const C& () const              { return *pFirst; }
 13.1002     };
 13.1003 
 13.1004     // Note: No default constructor is necessary.
 13.1005      HashNode(const HashNode& src) : First(src.First), Second(src.Second)    { }
 13.1006      HashNode(const NodeRef& src) : First(*src.pFirst), Second(*src.pSecond)  { }
 13.1007     void operator = (const NodeRef& src)  { First  = *src.pFirst; Second = *src.pSecond; }
 13.1008 
 13.1009     template<class K>
 13.1010     bool operator == (const K& src) const   { return (First == src); }
 13.1011 
 13.1012     template<class K>
 13.1013     static UPInt CalcHash(const K& data)   { return HashF()(data); }
 13.1014     inline UPInt GetHash() const           { return HashF()(First); }
 13.1015 
 13.1016     // Hash functors used with this node. A separate functor is used for alternative
 13.1017     // key lookup so that it does not need to access the '.First' element.    
 13.1018     struct NodeHashF
 13.1019     {    
 13.1020         template<class K>
 13.1021         UPInt operator()(const K& data) const { return data.GetHash(); } 
 13.1022     };    
 13.1023     struct NodeAltHashF
 13.1024     {
 13.1025         template<class K>
 13.1026         UPInt operator()(const K& data) const { return HashNode<C,U,HashF>::CalcHash(data); }
 13.1027     };
 13.1028 };
 13.1029 
 13.1030 
 13.1031 
 13.1032 // **** Extra hashset_entry types to allow NodeRef construction.
 13.1033 
 13.1034 // The big difference between the below types and the ones used in hash_set is that
 13.1035 // these allow initializing the node with 'typename C::NodeRef& keyRef', which
 13.1036 // is critical to avoid temporary node allocation on stack when using placement new.
 13.1037 
 13.1038 // Compact hash table Entry type that re-computes hash keys during hash traversal.
 13.1039 // Good to use if the hash function is cheap or the hash value is already cached in C.
 13.1040 template<class C, class HashF>
 13.1041 class HashsetNodeEntry
 13.1042 {
 13.1043 public:
 13.1044     // Internal chaining for collisions.
 13.1045     SPInt NextInChain;
 13.1046     C     Value;
 13.1047 
 13.1048     HashsetNodeEntry()
 13.1049         : NextInChain(-2) { }
 13.1050     HashsetNodeEntry(const HashsetNodeEntry& e)
 13.1051         : NextInChain(e.NextInChain), Value(e.Value) { }
 13.1052     HashsetNodeEntry(const C& key, SPInt next)
 13.1053         : NextInChain(next), Value(key) { }    
 13.1054     HashsetNodeEntry(const typename C::NodeRef& keyRef, SPInt next)
 13.1055         : NextInChain(next), Value(keyRef) { }
 13.1056 
 13.1057     bool    IsEmpty() const             { return NextInChain == -2;  }
 13.1058     bool    IsEndOfChain() const        { return NextInChain == -1;  }
 13.1059     UPInt   GetCachedHash(UPInt maskValue) const  { return HashF()(Value) & maskValue; }
 13.1060     void    SetCachedHash(UPInt hashValue)        { OVR_UNUSED(hashValue); }
 13.1061 
 13.1062     void    Clear()
 13.1063     {        
 13.1064         Value.~C(); // placement delete
 13.1065         NextInChain = -2;
 13.1066     }
 13.1067     // Free is only used from dtor of hash; Clear is used during regular operations:
 13.1068     // assignment, hash reallocations, value reassignments, so on.
 13.1069     void    Free() { Clear(); }
 13.1070 };
 13.1071 
 13.1072 // Hash table Entry type that caches the Entry hash value for nodes, so that it
 13.1073 // does not need to be re-computed during access.
 13.1074 template<class C, class HashF>
 13.1075 class HashsetCachedNodeEntry
 13.1076 {
 13.1077 public:
 13.1078     // Internal chaining for collisions.
 13.1079     SPInt NextInChain;
 13.1080     UPInt HashValue;
 13.1081     C     Value;
 13.1082 
 13.1083     HashsetCachedNodeEntry()
 13.1084         : NextInChain(-2) { }
 13.1085     HashsetCachedNodeEntry(const HashsetCachedNodeEntry& e)
 13.1086         : NextInChain(e.NextInChain), HashValue(e.HashValue), Value(e.Value) { }
 13.1087     HashsetCachedNodeEntry(const C& key, SPInt next)
 13.1088         : NextInChain(next), Value(key) { }
 13.1089     HashsetCachedNodeEntry(const typename C::NodeRef& keyRef, SPInt next)
 13.1090         : NextInChain(next), Value(keyRef) { }
 13.1091 
 13.1092     bool    IsEmpty() const            { return NextInChain == -2;  }
 13.1093     bool    IsEndOfChain() const       { return NextInChain == -1;  }
 13.1094     UPInt   GetCachedHash(UPInt maskValue) const  { OVR_UNUSED(maskValue); return HashValue; }
 13.1095     void    SetCachedHash(UPInt hashValue)        { HashValue = hashValue; }
 13.1096 
 13.1097     void    Clear()
 13.1098     {
 13.1099         Value.~C();
 13.1100         NextInChain = -2;
 13.1101     }
 13.1102     // Free is only used from dtor of hash; Clear is used during regular operations:
 13.1103     // assignment, hash reallocations, value reassignments, so on.
 13.1104     void    Free() { Clear(); }
 13.1105 };
 13.1106 
 13.1107 
 13.1108 //-----------------------------------------------------------------------------------
 13.1109 template<class C, class U,
 13.1110          class HashF = FixedSizeHash<C>,
 13.1111          class Allocator = ContainerAllocator<C>,
 13.1112          class HashNode = OVR::HashNode<C,U,HashF>,
 13.1113          class Entry = HashsetCachedNodeEntry<HashNode, typename HashNode::NodeHashF>,
 13.1114          class Container =  HashSet<HashNode, typename HashNode::NodeHashF,
 13.1115              typename HashNode::NodeAltHashF, Allocator,
 13.1116              Entry> >
 13.1117 class Hash
 13.1118 {
 13.1119 public:
 13.1120     OVR_MEMORY_REDEFINE_NEW(Hash)
 13.1121 
 13.1122     // Types used for hash_set.
 13.1123     typedef U                                                           ValueType;
 13.1124     typedef Hash<C, U, HashF, Allocator, HashNode, Entry, Container>    SelfType;
 13.1125 
 13.1126     // Actual hash table itself, implemented as hash_set.
 13.1127     Container   mHash;
 13.1128 
 13.1129 public:
 13.1130     Hash()     {  }
 13.1131     Hash(int sizeHint) : mHash(sizeHint)                        { }
 13.1132     Hash(const SelfType& src) : mHash(src.mHash)                { }
 13.1133     ~Hash()                                                     { }
 13.1134 
 13.1135     void    operator = (const SelfType& src)    { mHash = src.mHash; }
 13.1136 
 13.1137     // Remove all entries from the Hash table.
 13.1138     inline void    Clear() { mHash.Clear(); }
 13.1139     // Returns true if the Hash is empty.
 13.1140     inline bool    IsEmpty() const { return mHash.IsEmpty(); }
 13.1141 
 13.1142     // Access (set).
 13.1143     inline void    Set(const C& key, const U& value)
 13.1144     {
 13.1145         typename HashNode::NodeRef e(key, value);
 13.1146         mHash.Set(e);
 13.1147     }
 13.1148     inline void    Add(const C& key, const U& value)
 13.1149     {
 13.1150         typename HashNode::NodeRef e(key, value);
 13.1151         mHash.Add(e);
 13.1152     }
 13.1153 
 13.1154     // Removes an element by clearing its Entry.
 13.1155     inline void     Remove(const C& key)
 13.1156     {   
 13.1157         mHash.RemoveAlt(key);
 13.1158     }
 13.1159     template<class K>
 13.1160     inline void     RemoveAlt(const K& key)
 13.1161     {   
 13.1162         mHash.RemoveAlt(key);
 13.1163     }
 13.1164 
 13.1165     // Retrieve the value under the given key.    
 13.1166     //  - If there's no value under the key, then return false and leave *pvalue alone.
 13.1167     //  - If there is a value, return true, and Set *Pvalue to the Entry's value.
 13.1168     //  - If value == NULL, return true or false according to the presence of the key.    
 13.1169     bool    Get(const C& key, U* pvalue) const   
 13.1170     {
 13.1171         const HashNode* p = mHash.GetAlt(key);
 13.1172         if (p)
 13.1173         {
 13.1174             if (pvalue)
 13.1175                 *pvalue = p->Second;
 13.1176             return true;
 13.1177         }
 13.1178         return false;
 13.1179     }
 13.1180 
 13.1181     template<class K>
 13.1182     bool    GetAlt(const K& key, U* pvalue) const   
 13.1183     {
 13.1184         const HashNode* p = mHash.GetAlt(key);
 13.1185         if (p)
 13.1186         {
 13.1187             if (pvalue)
 13.1188                 *pvalue = p->Second;
 13.1189             return true;
 13.1190         }
 13.1191         return false;
 13.1192     }
 13.1193 
 13.1194     // Retrieve the pointer to a value under the given key.    
 13.1195     //  - If there's no value under the key, then return NULL.    
 13.1196     //  - If there is a value, return the pointer.    
 13.1197     inline U*  Get(const C& key)
 13.1198     {
 13.1199         HashNode* p = mHash.GetAlt(key);
 13.1200         return p ? &p->Second : 0;
 13.1201     }
 13.1202     inline const U* Get(const C& key) const
 13.1203     {
 13.1204         const HashNode* p = mHash.GetAlt(key);
 13.1205         return p ? &p->Second : 0;
 13.1206     }
 13.1207 
 13.1208     template<class K>
 13.1209     inline U*  GetAlt(const K& key)
 13.1210     {
 13.1211         HashNode* p = mHash.GetAlt(key);
 13.1212         return p ? &p->Second : 0;
 13.1213     }
 13.1214     template<class K>
 13.1215     inline const U* GetAlt(const K& key) const
 13.1216     {
 13.1217         const HashNode* p = mHash.GetAlt(key);
 13.1218         return p ? &p->Second : 0;
 13.1219     }
 13.1220 
 13.1221     // Sizing methods - delegate to Hash.
 13.1222     inline UPInt   GetSize() const              { return mHash.GetSize(); }    
 13.1223     inline void    Resize(UPInt n)              { mHash.Resize(n); }
 13.1224     inline void    SetCapacity(UPInt newSize)   { mHash.SetCapacity(newSize); }
 13.1225 
 13.1226     // Iterator API, like STL.
 13.1227     typedef typename Container::ConstIterator   ConstIterator;
 13.1228     typedef typename Container::Iterator        Iterator;
 13.1229 
 13.1230     inline Iterator        Begin()              { return mHash.Begin(); }
 13.1231     inline Iterator        End()                { return mHash.End(); }
 13.1232     inline ConstIterator   Begin() const        { return mHash.Begin(); }
 13.1233     inline ConstIterator   End() const          { return mHash.End();   }
 13.1234 
 13.1235     Iterator        Find(const C& key)          { return mHash.FindAlt(key);  }
 13.1236     ConstIterator   Find(const C& key) const    { return mHash.FindAlt(key);  }
 13.1237 
 13.1238     template<class K>
 13.1239     Iterator        FindAlt(const K& key)       { return mHash.FindAlt(key);  }
 13.1240     template<class K>
 13.1241     ConstIterator   FindAlt(const K& key) const { return mHash.FindAlt(key);  }
 13.1242 };
 13.1243 
 13.1244 
 13.1245 
 13.1246 // Hash with uncached hash code; declared for convenience.
 13.1247 template<class C, class U, class HashF = FixedSizeHash<C>, class Allocator = ContainerAllocator<C> >
 13.1248 class HashUncached
 13.1249     : public Hash<C, U, HashF, Allocator, HashNode<C,U,HashF>,
 13.1250                    HashsetNodeEntry<HashNode<C,U,HashF>, typename HashNode<C,U,HashF>::NodeHashF> >
 13.1251 {
 13.1252 public:
 13.1253     typedef HashUncached<C, U, HashF, Allocator>                SelfType;
 13.1254     typedef Hash<C, U, HashF, Allocator, HashNode<C,U,HashF>,
 13.1255                  HashsetNodeEntry<HashNode<C,U,HashF>,
 13.1256                  typename HashNode<C,U,HashF>::NodeHashF> >     BaseType;
 13.1257 
 13.1258     // Delegated constructors.
 13.1259     HashUncached()                                        { }
 13.1260     HashUncached(int sizeHint) : BaseType(sizeHint)       { }
 13.1261     HashUncached(const SelfType& src) : BaseType(src)     { }
 13.1262     ~HashUncached()                                       { }
 13.1263     void operator = (const SelfType& src)                 { BaseType::operator = (src); }
 13.1264 };
 13.1265 
 13.1266 
 13.1267 
 13.1268 // And identity hash in which keys serve as hash value. Can be uncached,
 13.1269 // since hash computation is assumed cheap.
 13.1270 template<class C, class U, class Allocator = ContainerAllocator<C>, class HashF = IdentityHash<C> >
 13.1271 class HashIdentity
 13.1272     : public HashUncached<C, U, HashF, Allocator>
 13.1273 {
 13.1274 public:
 13.1275     typedef HashIdentity<C, U, Allocator, HashF> SelfType;
 13.1276     typedef HashUncached<C, U, HashF, Allocator> BaseType;
 13.1277 
 13.1278     // Delegated constructors.
 13.1279     HashIdentity()                                        { }
 13.1280     HashIdentity(int sizeHint) : BaseType(sizeHint)       { }
 13.1281     HashIdentity(const SelfType& src) : BaseType(src)     { }
 13.1282     ~HashIdentity()                                       { }
 13.1283     void operator = (const SelfType& src)                 { BaseType::operator = (src); }
 13.1284 };
 13.1285 
 13.1286 
 13.1287 } // OVR
 13.1288 
 13.1289 
 13.1290 #ifdef OVR_DEFINE_NEW
 13.1291 #define new OVR_DEFINE_NEW
 13.1292 #endif
 13.1293 
 13.1294 #endif
 13.1295 \ No newline at end of file
 13.1296 +/************************************************************************************
 13.1297 +
 13.1298 +PublicHeader:   None
 13.1299 +Filename    :   OVR_Hash.h
 13.1300 +Content     :   Template hash-table/set implementation
 13.1301 +Created     :   September 19, 2012
 13.1302 +Notes       : 
 13.1303 +
 13.1304 +Copyright   :   Copyright 2012 Oculus VR, Inc. All Rights reserved.
 13.1305 +
 13.1306 +Use of this software is subject to the terms of the Oculus license
 13.1307 +agreement provided at the time of installation or download, or which
 13.1308 +otherwise accompanies this software in either electronic or hard copy form.
 13.1309 +
 13.1310 +************************************************************************************/
 13.1311 +
 13.1312 +#ifndef OVR_Hash_h
 13.1313 +#define OVR_Hash_h
 13.1314 +
 13.1315 +#include "OVR_ContainerAllocator.h"
 13.1316 +#include "OVR_Alg.h"
 13.1317 +
 13.1318 +// 'new' operator is redefined/used in this file.
 13.1319 +#undef new
 13.1320 +
 13.1321 +namespace OVR {
 13.1322 +
 13.1323 +//-----------------------------------------------------------------------------------
 13.1324 +// ***** Hash Table Implementation
 13.1325 +
 13.1326 +// HastSet and Hash.
 13.1327 +//
 13.1328 +// Hash table, linear probing, internal chaining.  One  interesting/nice thing
 13.1329 +// about this implementation is that the table itself is a flat chunk of memory
 13.1330 +// containing no pointers, only relative indices. If the key and value types
 13.1331 +// of the Hash contain no pointers, then the Hash can be serialized using raw IO.
 13.1332 +//
 13.1333 +// Never shrinks, unless you explicitly Clear() it.  Expands on
 13.1334 +// demand, though.  For best results, if you know roughly how big your
 13.1335 +// table will be, default it to that size when you create it.
 13.1336 +//
 13.1337 +// Key usability feature:
 13.1338 +//
 13.1339 +//   1. Allows node hash values to either be cached or not.
 13.1340 +//
 13.1341 +//   2. Allows for alternative keys with methods such as GetAlt(). Handy
 13.1342 +//      if you need to search nodes by their components; no need to create
 13.1343 +//      temporary nodes.
 13.1344 +//
 13.1345 +
 13.1346 +
 13.1347 +// *** Hash functors:
 13.1348 +//
 13.1349 +//  IdentityHash  - use when the key is already a good hash
 13.1350 +//  HFixedSizeHash - general hash based on object's in-memory representation.
 13.1351 +
 13.1352 +
 13.1353 +// Hash is just the input value; can use this for integer-indexed hash tables.
 13.1354 +template<class C>
 13.1355 +class IdentityHash
 13.1356 +{
 13.1357 +public:
 13.1358 +    UPInt operator()(const C& data) const
 13.1359 +    { return (UPInt) data; }
 13.1360 +};
 13.1361 +
 13.1362 +// Computes a hash of an object's representation.
 13.1363 +template<class C>
 13.1364 +class FixedSizeHash
 13.1365 +{
 13.1366 +public:
 13.1367 +    // Alternative: "sdbm" hash function, suggested at same web page
 13.1368 +    // above, http::/www.cs.yorku.ca/~oz/hash.html
 13.1369 +    // This is somewhat slower then Bernstein, but it works way better than the above
 13.1370 +    // hash function for hashing large numbers of 32-bit ints.
 13.1371 +    static OVR_FORCE_INLINE UPInt SDBM_Hash(const void* data_in, UPInt size, UPInt seed = 5381)     
 13.1372 +    {
 13.1373 +        const UByte* data = (const UByte*) data_in;
 13.1374 +        UPInt        h = seed;
 13.1375 +        while (size > 0)
 13.1376 +        {
 13.1377 +            size--;
 13.1378 +            h = (h << 16) + (h << 6) - h + (UPInt)data[size];
 13.1379 +        }   
 13.1380 +        return h;
 13.1381 +    }
 13.1382 +
 13.1383 +    UPInt operator()(const C& data) const
 13.1384 +    {
 13.1385 +        unsigned char*  p = (unsigned char*) &data;
 13.1386 +        int size = sizeof(C);
 13.1387 +
 13.1388 +        return SDBM_Hash(p, size);
 13.1389 +    }
 13.1390 +};
 13.1391 +
 13.1392 +
 13.1393 +
 13.1394 +// *** HashsetEntry Entry types. 
 13.1395 +
 13.1396 +// Compact hash table Entry type that re-computes hash keys during hash traversal.
 13.1397 +// Good to use if the hash function is cheap or the hash value is already cached in C.
 13.1398 +template<class C, class HashF>
 13.1399 +class HashsetEntry
 13.1400 +{
 13.1401 +public:
 13.1402 +    // Internal chaining for collisions.
 13.1403 +    SPInt       NextInChain;
 13.1404 +    C           Value;
 13.1405 +
 13.1406 +    HashsetEntry()
 13.1407 +        : NextInChain(-2) { }
 13.1408 +    HashsetEntry(const HashsetEntry& e)
 13.1409 +        : NextInChain(e.NextInChain), Value(e.Value) { }
 13.1410 +    HashsetEntry(const C& key, SPInt next)
 13.1411 +        : NextInChain(next), Value(key) { }
 13.1412 +
 13.1413 +    bool    IsEmpty() const          { return NextInChain == -2;  }
 13.1414 +    bool    IsEndOfChain() const     { return NextInChain == -1;  }
 13.1415 +
 13.1416 +    // Cached hash value access - can be optimized bu storing hash locally.
 13.1417 +    // Mask value only needs to be used if SetCachedHash is not implemented.
 13.1418 +    UPInt   GetCachedHash(UPInt maskValue) const  { return HashF()(Value) & maskValue; }
 13.1419 +    void    SetCachedHash(UPInt)                  {}
 13.1420 +
 13.1421 +    void    Clear()
 13.1422 +    {        
 13.1423 +        Value.~C(); // placement delete
 13.1424 +        NextInChain = -2;
 13.1425 +    }
 13.1426 +    // Free is only used from dtor of hash; Clear is used during regular operations:
 13.1427 +    // assignment, hash reallocations, value reassignments, so on.
 13.1428 +    void    Free() { Clear(); }
 13.1429 +};
 13.1430 +
 13.1431 +// Hash table Entry type that caches the Entry hash value for nodes, so that it
 13.1432 +// does not need to be re-computed during access.
 13.1433 +template<class C, class HashF>
 13.1434 +class HashsetCachedEntry
 13.1435 +{
 13.1436 +public:
 13.1437 +    // Internal chaining for collisions.
 13.1438 +    SPInt       NextInChain;
 13.1439 +    UPInt       HashValue;
 13.1440 +    C           Value;
 13.1441 +
 13.1442 +    HashsetCachedEntry()
 13.1443 +        : NextInChain(-2) { }
 13.1444 +    HashsetCachedEntry(const HashsetCachedEntry& e)
 13.1445 +        : NextInChain(e.NextInChain), HashValue(e.HashValue), Value(e.Value) { }
 13.1446 +    HashsetCachedEntry(const C& key, SPInt next)
 13.1447 +        : NextInChain(next), Value(key) { }
 13.1448 +
 13.1449 +    bool    IsEmpty() const          { return NextInChain == -2;  }
 13.1450 +    bool    IsEndOfChain() const     { return NextInChain == -1;  }
 13.1451 +
 13.1452 +    // Cached hash value access - can be optimized bu storing hash locally.
 13.1453 +    // Mask value only needs to be used if SetCachedHash is not implemented.
 13.1454 +    UPInt   GetCachedHash(UPInt maskValue) const  { OVR_UNUSED(maskValue); return HashValue; }
 13.1455 +    void    SetCachedHash(UPInt hashValue)        { HashValue = hashValue; }
 13.1456 +
 13.1457 +    void    Clear()
 13.1458 +    {
 13.1459 +        Value.~C();
 13.1460 +        NextInChain = -2;
 13.1461 +    }
 13.1462 +    // Free is only used from dtor of hash; Clear is used during regular operations:
 13.1463 +    // assignment, hash reallocations, value reassignments, so on.
 13.1464 +    void    Free() { Clear(); }
 13.1465 +};
 13.1466 +
 13.1467 +
 13.1468 +//-----------------------------------------------------------------------------------
 13.1469 +// *** HashSet implementation - relies on either cached or regular entries.
 13.1470 +//
 13.1471 +// Use: Entry = HashsetCachedEntry<C, HashF> if hashes are expensive to
 13.1472 +//              compute and thus need caching in entries.
 13.1473 +//      Entry = HashsetEntry<C, HashF> if hashes are already externally cached.
 13.1474 +//
 13.1475 +template<class C, class HashF = FixedSizeHash<C>,
 13.1476 +         class AltHashF = HashF, 
 13.1477 +         class Allocator = ContainerAllocator<C>,
 13.1478 +         class Entry = HashsetCachedEntry<C, HashF> >
 13.1479 +class HashSetBase
 13.1480 +{
 13.1481 +    enum { HashMinSize = 8 };
 13.1482 +
 13.1483 +public:
 13.1484 +    OVR_MEMORY_REDEFINE_NEW(HashSetBase)
 13.1485 +
 13.1486 +    typedef HashSetBase<C, HashF, AltHashF, Allocator, Entry>    SelfType;
 13.1487 +
 13.1488 +    HashSetBase() : pTable(NULL)                       {   }
 13.1489 +    HashSetBase(int sizeHint) : pTable(NULL)           { SetCapacity(this, sizeHint);  }
 13.1490 +    HashSetBase(const SelfType& src) : pTable(NULL)    { Assign(this, src); }
 13.1491 +
 13.1492 +    ~HashSetBase()                                     
 13.1493 +    { 
 13.1494 +        if (pTable)
 13.1495 +        {
 13.1496 +            // Delete the entries.
 13.1497 +            for (UPInt i = 0, n = pTable->SizeMask; i <= n; i++)
 13.1498 +            {
 13.1499 +                Entry*  e = &E(i);
 13.1500 +                if (!e->IsEmpty())             
 13.1501 +                    e->Free();
 13.1502 +            }            
 13.1503 +
 13.1504 +            Allocator::Free(pTable);
 13.1505 +            pTable = NULL;
 13.1506 +        }
 13.1507 +    }
 13.1508 +
 13.1509 +
 13.1510 +    void Assign(const SelfType& src)
 13.1511 +    {
 13.1512 +        Clear();
 13.1513 +        if (src.IsEmpty() == false)
 13.1514 +        {
 13.1515 +            SetCapacity(src.GetSize());
 13.1516 +
 13.1517 +            for (ConstIterator it = src.Begin(); it != src.End(); ++it)
 13.1518 +            {
 13.1519 +                Add(*it);
 13.1520 +            }
 13.1521 +        }
 13.1522 +    }
 13.1523 +
 13.1524 +
 13.1525 +    // Remove all entries from the HashSet table.
 13.1526 +    void Clear() 
 13.1527 +    {
 13.1528 +        if (pTable)
 13.1529 +        {
 13.1530 +            // Delete the entries.
 13.1531 +            for (UPInt i = 0, n = pTable->SizeMask; i <= n; i++)
 13.1532 +            {
 13.1533 +                Entry*  e = &E(i);
 13.1534 +                if (!e->IsEmpty())             
 13.1535 +                    e->Clear();
 13.1536 +            }            
 13.1537 +                
 13.1538 +            Allocator::Free(pTable);
 13.1539 +            pTable = NULL;
 13.1540 +        }
 13.1541 +    }
 13.1542 +
 13.1543 +    // Returns true if the HashSet is empty.
 13.1544 +    bool IsEmpty() const
 13.1545 +    {
 13.1546 +        return pTable == NULL || pTable->EntryCount == 0;
 13.1547 +    }
 13.1548 +
 13.1549 +
 13.1550 +    // Set a new or existing value under the key, to the value.
 13.1551 +    // Pass a different class of 'key' so that assignment reference object
 13.1552 +    // can be passed instead of the actual object.
 13.1553 +    template<class CRef>
 13.1554 +    void Set(const CRef& key)
 13.1555 +    {
 13.1556 +        UPInt  hashValue = HashF()(key);
 13.1557 +        SPInt  index     = (SPInt)-1;
 13.1558 +
 13.1559 +        if (pTable != NULL)
 13.1560 +            index = findIndexCore(key, hashValue & pTable->SizeMask);
 13.1561 +
 13.1562 +        if (index >= 0)
 13.1563 +        {            
 13.1564 +            E(index).Value = key;
 13.1565 +        }
 13.1566 +        else
 13.1567 +        {
 13.1568 +            // Entry under key doesn't exist.
 13.1569 +            add(key, hashValue);
 13.1570 +        }
 13.1571 +    }
 13.1572 +
 13.1573 +    template<class CRef>
 13.1574 +    inline void Add(const CRef& key)
 13.1575 +    {
 13.1576 +        UPInt hashValue = HashF()(key);
 13.1577 +        add(key, hashValue);
 13.1578 +    }
 13.1579 +
 13.1580 +    // Remove by alternative key.
 13.1581 +    template<class K>
 13.1582 +    void RemoveAlt(const K& key)
 13.1583 +    {   
 13.1584 +        if (pTable == NULL)
 13.1585 +            return;
 13.1586 +
 13.1587 +        UPInt   hashValue = AltHashF()(key);
 13.1588 +        SPInt   index     = hashValue & pTable->SizeMask;
 13.1589 +
 13.1590 +        Entry*  e = &E(index);
 13.1591 +
 13.1592 +        // If empty node or occupied by collider, we have nothing to remove.
 13.1593 +        if (e->IsEmpty() || (e->GetCachedHash(pTable->SizeMask) != (UPInt)index))
 13.1594 +            return;        
 13.1595 +
 13.1596 +        // Save index
 13.1597 +        SPInt   naturalIndex = index;
 13.1598 +        SPInt   prevIndex    = -1;
 13.1599 +
 13.1600 +        while ((e->GetCachedHash(pTable->SizeMask) != (UPInt)naturalIndex) || !(e->Value == key))
 13.1601 +        {
 13.1602 +            // Keep looking through the chain.
 13.1603 +            prevIndex   = index;
 13.1604 +            index       = e->NextInChain;
 13.1605 +            if (index == -1)
 13.1606 +                return; // End of chain, item not found
 13.1607 +            e = &E(index);
 13.1608 +        }
 13.1609 +
 13.1610 +        // Found it - our item is at index
 13.1611 +        if (naturalIndex == index)
 13.1612 +        {
 13.1613 +            // If we have a follower, move it to us
 13.1614 +            if (!e->IsEndOfChain())
 13.1615 +            {               
 13.1616 +                Entry*  enext = &E(e->NextInChain);
 13.1617 +                e->Clear();
 13.1618 +                new (e) Entry(*enext);
 13.1619 +                // Point us to the follower's cell that will be cleared
 13.1620 +                e = enext;
 13.1621 +            }
 13.1622 +        }
 13.1623 +        else
 13.1624 +        {
 13.1625 +            // We are not at natural index, so deal with the prev items next index
 13.1626 +            E(prevIndex).NextInChain = e->NextInChain;
 13.1627 +        }
 13.1628 +
 13.1629 +        // Clear us, of the follower cell that was moved.
 13.1630 +        e->Clear();
 13.1631 +        pTable->EntryCount --;
 13.1632 +        // Should we check the size to condense hash? ...
 13.1633 +    }
 13.1634 +
 13.1635 +    // Remove by main key.
 13.1636 +    template<class CRef>
 13.1637 +    void Remove(const CRef& key)
 13.1638 +    {
 13.1639 +        RemoveAlt(key);
 13.1640 +    }
 13.1641 +
 13.1642 +    // Retrieve the pointer to a value under the given key.
 13.1643 +    //  - If there's no value under the key, then return NULL.    
 13.1644 +    //  - If there is a value, return the pointer.    
 13.1645 +    template<class K>
 13.1646 +    C* Get(const K& key)
 13.1647 +    {
 13.1648 +        SPInt   index = findIndex(key);
 13.1649 +        if (index >= 0)        
 13.1650 +            return &E(index).Value;        
 13.1651 +        return 0;
 13.1652 +    }   
 13.1653 +
 13.1654 +    template<class K>
 13.1655 +    const C* Get(const K& key) const
 13.1656 +    {
 13.1657 +        SPInt   index = findIndex(key);
 13.1658 +        if (index >= 0)        
 13.1659 +            return &E(index).Value;        
 13.1660 +        return 0;
 13.1661 +    }
 13.1662 +
 13.1663 +    // Alternative key versions of Get. Used by Hash.
 13.1664 +    template<class K>
 13.1665 +    const C* GetAlt(const K& key) const
 13.1666 +    {
 13.1667 +        SPInt   index = findIndexAlt(key);
 13.1668 +        if (index >= 0)        
 13.1669 +            return &E(index).Value;
 13.1670 +        return 0;
 13.1671 +    }
 13.1672 +
 13.1673 +    template<class K>
 13.1674 +    C* GetAlt(const K& key)
 13.1675 +    {
 13.1676 +        SPInt   index = findIndexAlt(key);
 13.1677 +        if (index >= 0)        
 13.1678 +            return &E(index).Value;
 13.1679 +        return 0;
 13.1680 +    }   
 13.1681 +
 13.1682 +    template<class K>
 13.1683 +    bool GetAlt(const K& key, C* pval) const
 13.1684 +    {
 13.1685 +        SPInt   index = findIndexAlt(key);
 13.1686 +        if (index >= 0)
 13.1687 +        {
 13.1688 +            if (pval)
 13.1689 +                *pval = E(index).Value;
 13.1690 +            return true;
 13.1691 +        }
 13.1692 +        return false;
 13.1693 +    }
 13.1694 +
 13.1695 +
 13.1696 +    UPInt GetSize() const
 13.1697 +    {
 13.1698 +        return pTable == NULL ? 0 : (UPInt)pTable->EntryCount;
 13.1699 +    }
 13.1700 +
 13.1701 +
 13.1702 +    // Resize the HashSet table to fit one more Entry.  Often this
 13.1703 +    // doesn't involve any action.
 13.1704 +    void CheckExpand()
 13.1705 +    {
 13.1706 +        if (pTable == NULL)
 13.1707 +        {
 13.1708 +            // Initial creation of table.  Make a minimum-sized table.
 13.1709 +            setRawCapacity(HashMinSize);
 13.1710 +        }
 13.1711 +        else if (pTable->EntryCount * 5 > (pTable->SizeMask + 1) * 4)
 13.1712 +        {
 13.1713 +            // pTable is more than 5/4 ths full.  Expand.
 13.1714 +            setRawCapacity((pTable->SizeMask + 1) * 2);
 13.1715 +        }
 13.1716 +    }
 13.1717 +
 13.1718 +    // Hint the bucket count to >= n.
 13.1719 +    void Resize(UPInt n)    
 13.1720 +    {
 13.1721 +        // Not really sure what this means in relation to
 13.1722 +        // STLport's hash_map... they say they "increase the
 13.1723 +        // bucket count to at least n" -- but does that mean
 13.1724 +        // their real capacity after Resize(n) is more like
 13.1725 +        // n*2 (since they do linked-list chaining within
 13.1726 +        // buckets?).
 13.1727 +        SetCapacity(n);
 13.1728 +    }
 13.1729 +
 13.1730 +    // Size the HashSet so that it can comfortably contain the given
 13.1731 +    // number of elements.  If the HashSet already contains more
 13.1732 +    // elements than newSize, then this may be a no-op.
 13.1733 +    void SetCapacity(UPInt newSize)
 13.1734 +    {
 13.1735 +        UPInt newRawSize = (newSize * 5) / 4;
 13.1736 +        if (newRawSize <= GetSize())
 13.1737 +            return;
 13.1738 +        setRawCapacity(newRawSize);
 13.1739 +    }
 13.1740 +
 13.1741 +    // Disable inappropriate 'operator ->' warning on MSVC6.
 13.1742 +#ifdef OVR_CC_MSVC
 13.1743 +#if (OVR_CC_MSVC < 1300)
 13.1744 +# pragma warning(disable : 4284)
 13.1745 +#endif
 13.1746 +#endif
 13.1747 +
 13.1748 +    // Iterator API, like STL.
 13.1749 +    struct ConstIterator
 13.1750 +    {   
 13.1751 +        const C&    operator * () const
 13.1752 +        {            
 13.1753 +            OVR_ASSERT(Index >= 0 && Index <= (SPInt)pHash->pTable->SizeMask);
 13.1754 +            return pHash->E(Index).Value;
 13.1755 +        }
 13.1756 +
 13.1757 +        const C*    operator -> () const
 13.1758 +        {
 13.1759 +            OVR_ASSERT(Index >= 0 && Index <= (SPInt)pHash->pTable->SizeMask);
 13.1760 +            return &pHash->E(Index).Value;
 13.1761 +        }
 13.1762 +
 13.1763 +        void    operator ++ ()
 13.1764 +        {
 13.1765 +            // Find next non-empty Entry.
 13.1766 +            if (Index <= (SPInt)pHash->pTable->SizeMask)
 13.1767 +            {
 13.1768 +                Index++;
 13.1769 +                while ((UPInt)Index <= pHash->pTable->SizeMask &&
 13.1770 +                    pHash->E(Index).IsEmpty())
 13.1771 +                {
 13.1772 +                    Index++;
 13.1773 +                }
 13.1774 +            }
 13.1775 +        }
 13.1776 +
 13.1777 +        bool    operator == (const ConstIterator& it) const
 13.1778 +        {
 13.1779 +            if (IsEnd() && it.IsEnd())
 13.1780 +            {
 13.1781 +                return true;
 13.1782 +            }
 13.1783 +            else
 13.1784 +            {
 13.1785 +                return (pHash == it.pHash) && (Index == it.Index);
 13.1786 +            }
 13.1787 +        }
 13.1788 +
 13.1789 +        bool    operator != (const ConstIterator& it) const
 13.1790 +        {
 13.1791 +            return ! (*this == it);
 13.1792 +        }
 13.1793 +
 13.1794 +
 13.1795 +        bool    IsEnd() const
 13.1796 +        {
 13.1797 +            return (pHash == NULL) || 
 13.1798 +                (pHash->pTable == NULL) || 
 13.1799 +                (Index > (SPInt)pHash->pTable->SizeMask);
 13.1800 +        }
 13.1801 +
 13.1802 +        ConstIterator()
 13.1803 +            : pHash(NULL), Index(0)
 13.1804 +        { }
 13.1805 +
 13.1806 +    public:
 13.1807 +        // Constructor was intentionally made public to allow create
 13.1808 +        // iterator with arbitrary index.
 13.1809 +        ConstIterator(const SelfType* h, SPInt index)
 13.1810 +            : pHash(h), Index(index)
 13.1811 +        { }
 13.1812 +
 13.1813 +        const SelfType* GetContainer() const
 13.1814 +        {
 13.1815 +            return pHash;
 13.1816 +        }
 13.1817 +        SPInt GetIndex() const
 13.1818 +        {
 13.1819 +            return Index;
 13.1820 +        }
 13.1821 +
 13.1822 +    protected:
 13.1823 +        friend class HashSetBase<C, HashF, AltHashF, Allocator, Entry>;
 13.1824 +
 13.1825 +        const SelfType* pHash;
 13.1826 +        SPInt           Index;
 13.1827 +    };
 13.1828 +
 13.1829 +    friend struct ConstIterator;
 13.1830 +
 13.1831 +
 13.1832 +    // Non-const Iterator; Get most of it from ConstIterator.
 13.1833 +    struct Iterator : public ConstIterator
 13.1834 +    {      
 13.1835 +        // Allow non-const access to entries.
 13.1836 +        C&  operator*() const
 13.1837 +        {            
 13.1838 +            OVR_ASSERT(ConstIterator::Index >= 0 && ConstIterator::Index <= (SPInt)ConstIterator::pHash->pTable->SizeMask);
 13.1839 +            return const_cast<SelfType*>(ConstIterator::pHash)->E(ConstIterator::Index).Value;
 13.1840 +        }    
 13.1841 +
 13.1842 +        C*  operator->() const 
 13.1843 +        {
 13.1844 +            return &(operator*());
 13.1845 +        }
 13.1846 +
 13.1847 +        Iterator()
 13.1848 +            : ConstIterator(NULL, 0)
 13.1849 +        { }
 13.1850 +
 13.1851 +        // Removes current element from Hash
 13.1852 +        void Remove()
 13.1853 +        {
 13.1854 +            RemoveAlt(operator*());
 13.1855 +        }
 13.1856 +
 13.1857 +        template <class K>
 13.1858 +        void RemoveAlt(const K& key)
 13.1859 +        {
 13.1860 +            SelfType*   phash = const_cast<SelfType*>(ConstIterator::pHash);
 13.1861 +            //Entry*      ee = &phash->E(ConstIterator::Index);
 13.1862 +            //const C&    key = ee->Value;
 13.1863 +
 13.1864 +            UPInt       hashValue = AltHashF()(key);
 13.1865 +            SPInt       index     = hashValue & phash->pTable->SizeMask;
 13.1866 +
 13.1867 +            Entry*      e = &phash->E(index);
 13.1868 +
 13.1869 +            // If empty node or occupied by collider, we have nothing to remove.
 13.1870 +            if (e->IsEmpty() || (e->GetCachedHash(phash->pTable->SizeMask) != (UPInt)index))
 13.1871 +                return;        
 13.1872 +
 13.1873 +            // Save index
 13.1874 +            SPInt   naturalIndex = index;
 13.1875 +            SPInt   prevIndex    = -1;
 13.1876 +
 13.1877 +            while ((e->GetCachedHash(phash->pTable->SizeMask) != (UPInt)naturalIndex) || !(e->Value == key))
 13.1878 +            {
 13.1879 +                // Keep looking through the chain.
 13.1880 +                prevIndex   = index;
 13.1881 +                index       = e->NextInChain;
 13.1882 +                if (index == -1)
 13.1883 +                    return; // End of chain, item not found
 13.1884 +                e = &phash->E(index);
 13.1885 +            }
 13.1886 +
 13.1887 +            if (index == (SPInt)ConstIterator::Index)
 13.1888 +            {
 13.1889 +                // Found it - our item is at index
 13.1890 +                if (naturalIndex == index)
 13.1891 +                {
 13.1892 +                    // If we have a follower, move it to us
 13.1893 +                    if (!e->IsEndOfChain())
 13.1894 +                    {               
 13.1895 +                        Entry*  enext = &phash->E(e->NextInChain);
 13.1896 +                        e->Clear();
 13.1897 +                        new (e) Entry(*enext);
 13.1898 +                        // Point us to the follower's cell that will be cleared
 13.1899 +                        e = enext;
 13.1900 +                        --ConstIterator::Index;
 13.1901 +                    }
 13.1902 +                }
 13.1903 +                else
 13.1904 +                {
 13.1905 +                    // We are not at natural index, so deal with the prev items next index
 13.1906 +                    phash->E(prevIndex).NextInChain = e->NextInChain;
 13.1907 +                }
 13.1908 +
 13.1909 +                // Clear us, of the follower cell that was moved.
 13.1910 +                e->Clear();
 13.1911 +                phash->pTable->EntryCount --;
 13.1912 +            }
 13.1913 +            else 
 13.1914 +                OVR_ASSERT(0); //?
 13.1915 +        }
 13.1916 +
 13.1917 +    private:
 13.1918 +        friend class HashSetBase<C, HashF, AltHashF, Allocator, Entry>;
 13.1919 +
 13.1920 +        Iterator(SelfType* h, SPInt i0)
 13.1921 +            : ConstIterator(h, i0)
 13.1922 +        { }
 13.1923 +    };
 13.1924 +
 13.1925 +    friend struct Iterator;
 13.1926 +
 13.1927 +    Iterator    Begin()
 13.1928 +    {
 13.1929 +        if (pTable == 0)
 13.1930 +            return Iterator(NULL, 0);
 13.1931 +
 13.1932 +        // Scan till we hit the First valid Entry.
 13.1933 +        UPInt  i0 = 0;
 13.1934 +        while (i0 <= pTable->SizeMask && E(i0).IsEmpty())
 13.1935 +        {
 13.1936 +            i0++;
 13.1937 +        }
 13.1938 +        return Iterator(this, i0);
 13.1939 +    }
 13.1940 +    Iterator        End()           { return Iterator(NULL, 0); }
 13.1941 +
 13.1942 +    ConstIterator   Begin() const   { return const_cast<SelfType*>(this)->Begin();     }
 13.1943 +    ConstIterator   End() const     { return const_cast<SelfType*>(this)->End();   }
 13.1944 +
 13.1945 +    template<class K>
 13.1946 +    Iterator Find(const K& key)
 13.1947 +    {
 13.1948 +        SPInt index = findIndex(key);
 13.1949 +        if (index >= 0)        
 13.1950 +            return Iterator(this, index);        
 13.1951 +        return Iterator(NULL, 0);
 13.1952 +    }
 13.1953 +
 13.1954 +    template<class K>
 13.1955 +    Iterator FindAlt(const K& key)
 13.1956 +    {
 13.1957 +        SPInt index = findIndexAlt(key);
 13.1958 +        if (index >= 0)        
 13.1959 +            return Iterator(this, index);        
 13.1960 +        return Iterator(NULL, 0);
 13.1961 +    }
 13.1962 +
 13.1963 +    template<class K>
 13.1964 +    ConstIterator Find(const K& key) const       { return const_cast<SelfType*>(this)->Find(key); }
 13.1965 +
 13.1966 +    template<class K>
 13.1967 +    ConstIterator FindAlt(const K& key) const    { return const_cast<SelfType*>(this)->FindAlt(key); }
 13.1968 +
 13.1969 +private:
 13.1970 +    // Find the index of the matching Entry.  If no match, then return -1.
 13.1971 +    template<class K>
 13.1972 +    SPInt findIndex(const K& key) const
 13.1973 +    {
 13.1974 +        if (pTable == NULL)
 13.1975 +            return -1;
 13.1976 +        UPInt hashValue = HashF()(key) & pTable->SizeMask;
 13.1977 +        return findIndexCore(key, hashValue);
 13.1978 +    }
 13.1979 +
 13.1980 +    template<class K>
 13.1981 +    SPInt findIndexAlt(const K& key) const
 13.1982 +    {
 13.1983 +        if (pTable == NULL)
 13.1984 +            return -1;
 13.1985 +        UPInt hashValue = AltHashF()(key) & pTable->SizeMask;
 13.1986 +        return findIndexCore(key, hashValue);
 13.1987 +    }
 13.1988 +
 13.1989 +    // Find the index of the matching Entry.  If no match, then return -1.
 13.1990 +    template<class K>
 13.1991 +    SPInt findIndexCore(const K& key, UPInt hashValue) const
 13.1992 +    {
 13.1993 +        // Table must exist.
 13.1994 +        OVR_ASSERT(pTable != 0);
 13.1995 +        // Hash key must be 'and-ed' by the caller.
 13.1996 +        OVR_ASSERT((hashValue & ~pTable->SizeMask) == 0);
 13.1997 +
 13.1998 +        UPInt           index = hashValue;
 13.1999 +        const Entry*    e     = &E(index);
 13.2000 +
 13.2001 +        // If empty or occupied by a collider, not found.
 13.2002 +        if (e->IsEmpty() || (e->GetCachedHash(pTable->SizeMask) != index))
 13.2003 +            return -1;
 13.2004 +
 13.2005 +        while(1)
 13.2006 +        {
 13.2007 +            OVR_ASSERT(e->GetCachedHash(pTable->SizeMask) == hashValue);
 13.2008 +
 13.2009 +            if (e->GetCachedHash(pTable->SizeMask) == hashValue && e->Value == key)
 13.2010 +            {
 13.2011 +                // Found it.
 13.2012 +                return index;
 13.2013 +            }
 13.2014 +            // Values can not be equal at this point.
 13.2015 +            // That would mean that the hash key for the same value differs.
 13.2016 +            OVR_ASSERT(!(e->Value == key));
 13.2017 +
 13.2018 +            // Keep looking through the chain.
 13.2019 +            index = e->NextInChain;
 13.2020 +            if (index == (UPInt)-1)
 13.2021 +                break; // end of chain
 13.2022 +
 13.2023 +            e = &E(index);
 13.2024 +            OVR_ASSERT(!e->IsEmpty());
 13.2025 +        }
 13.2026 +        return -1;
 13.2027 +    }
 13.2028 +
 13.2029 +
 13.2030 +    // Add a new value to the HashSet table, under the specified key.
 13.2031 +    template<class CRef>
 13.2032 +    void add(const CRef& key, UPInt hashValue)
 13.2033 +    {
 13.2034 +        CheckExpand();
 13.2035 +        hashValue &= pTable->SizeMask;
 13.2036 +
 13.2037 +        pTable->EntryCount++;
 13.2038 +
 13.2039 +        SPInt   index        = hashValue;
 13.2040 +        Entry*  naturalEntry = &(E(index));
 13.2041 +
 13.2042 +        if (naturalEntry->IsEmpty())
 13.2043 +        {
 13.2044 +            // Put the new Entry in.
 13.2045 +            new (naturalEntry) Entry(key, -1);
 13.2046 +        }
 13.2047 +        else
 13.2048 +        {
 13.2049 +            // Find a blank spot.
 13.2050 +            SPInt blankIndex = index;
 13.2051 +            do {
 13.2052 +                blankIndex = (blankIndex + 1) & pTable->SizeMask;
 13.2053 +            } while(!E(blankIndex).IsEmpty());
 13.2054 +
 13.2055 +            Entry*  blankEntry = &E(blankIndex);
 13.2056 +
 13.2057 +            if (naturalEntry->GetCachedHash(pTable->SizeMask) == (UPInt)index)
 13.2058 +            {
 13.2059 +                // Collision.  Link into this chain.
 13.2060 +
 13.2061 +                // Move existing list head.
 13.2062 +                new (blankEntry) Entry(*naturalEntry);    // placement new, copy ctor
 13.2063 +
 13.2064 +                // Put the new info in the natural Entry.
 13.2065 +                naturalEntry->Value       = key;
 13.2066 +                naturalEntry->NextInChain = blankIndex;
 13.2067 +            }
 13.2068 +            else
 13.2069 +            {
 13.2070 +                // Existing Entry does not naturally
 13.2071 +                // belong in this slot.  Existing
 13.2072 +                // Entry must be moved.
 13.2073 +
 13.2074 +                // Find natural location of collided element (i.e. root of chain)
 13.2075 +                SPInt collidedIndex = naturalEntry->GetCachedHash(pTable->SizeMask);
 13.2076 +                OVR_ASSERT(collidedIndex >= 0 && collidedIndex <= (SPInt)pTable->SizeMask);
 13.2077 +                for (;;)
 13.2078 +                {
 13.2079 +                    Entry*  e = &E(collidedIndex);
 13.2080 +                    if (e->NextInChain == index)
 13.2081 +                    {
 13.2082 +                        // Here's where we need to splice.
 13.2083 +                        new (blankEntry) Entry(*naturalEntry);
 13.2084 +                        e->NextInChain = blankIndex;
 13.2085 +                        break;
 13.2086 +                    }
 13.2087 +                    collidedIndex = e->NextInChain;
 13.2088 +                    OVR_ASSERT(collidedIndex >= 0 && collidedIndex <= (SPInt)pTable->SizeMask);
 13.2089 +                }
 13.2090 +
 13.2091 +                // Put the new data in the natural Entry.
 13.2092 +                naturalEntry->Value       = key;
 13.2093 +                naturalEntry->NextInChain = -1;                
 13.2094 +            }            
 13.2095 +        }
 13.2096 +
 13.2097 +        // Record hash value: has effect only if cached node is used.
 13.2098 +        naturalEntry->SetCachedHash(hashValue);
 13.2099 +    }
 13.2100 +
 13.2101 +    // Index access helpers.
 13.2102 +    Entry& E(UPInt index)
 13.2103 +    {
 13.2104 +        // Must have pTable and access needs to be within bounds.
 13.2105 +        OVR_ASSERT(index <= pTable->SizeMask);
 13.2106 +        return *(((Entry*) (pTable + 1)) + index);
 13.2107 +    }
 13.2108 +    const Entry& E(UPInt index) const
 13.2109 +    {        
 13.2110 +        OVR_ASSERT(index <= pTable->SizeMask);
 13.2111 +        return *(((Entry*) (pTable + 1)) + index);
 13.2112 +    }
 13.2113 +
 13.2114 +
 13.2115 +    // Resize the HashSet table to the given size (Rehash the
 13.2116 +    // contents of the current table).  The arg is the number of
 13.2117 +    // HashSet table entries, not the number of elements we should
 13.2118 +    // actually contain (which will be less than this).
 13.2119 +    void    setRawCapacity(UPInt newSize)    
 13.2120 +    {
 13.2121 +        if (newSize == 0)
 13.2122 +        {
 13.2123 +            // Special case.
 13.2124 +            Clear();
 13.2125 +            return;
 13.2126 +        }
 13.2127 +
 13.2128 +        // Minimum size; don't incur rehashing cost when expanding
 13.2129 +        // very small tables. Not that we perform this check before 
 13.2130 +        // 'log2f' call to avoid fp exception with newSize == 1.
 13.2131 +        if (newSize < HashMinSize)        
 13.2132 +            newSize = HashMinSize;       
 13.2133 +        else
 13.2134 +        {
 13.2135 +            // Force newSize to be a power of two.
 13.2136 +            int bits = Alg::UpperBit(newSize-1) + 1; // Chop( Log2f((float)(newSize-1)) + 1);
 13.2137 +            OVR_ASSERT((UPInt(1) << bits) >= newSize);
 13.2138 +            newSize = UPInt(1) << bits;
 13.2139 +        }
 13.2140 +
 13.2141 +        SelfType  newHash;
 13.2142 +        newHash.pTable = (TableType*)
 13.2143 +            Allocator::Alloc(                
 13.2144 +                sizeof(TableType) + sizeof(Entry) * newSize);
 13.2145 +        // Need to do something on alloc failure!
 13.2146 +        OVR_ASSERT(newHash.pTable);
 13.2147 +
 13.2148 +        newHash.pTable->EntryCount = 0;
 13.2149 +        newHash.pTable->SizeMask = newSize - 1;
 13.2150 +        UPInt i, n;
 13.2151 +
 13.2152 +        // Mark all entries as empty.
 13.2153 +        for (i = 0; i < newSize; i++)
 13.2154 +            newHash.E(i).NextInChain = -2;
 13.2155 +
 13.2156 +        // Copy stuff to newHash
 13.2157 +        if (pTable)
 13.2158 +        {            
 13.2159 +            for (i = 0, n = pTable->SizeMask; i <= n; i++)
 13.2160 +            {
 13.2161 +                Entry*  e = &E(i);
 13.2162 +                if (e->IsEmpty() == false)
 13.2163 +                {
 13.2164 +                    // Insert old Entry into new HashSet.
 13.2165 +                    newHash.Add(e->Value);
 13.2166 +                    // placement delete of old element
 13.2167 +                    e->Clear();
 13.2168 +                }
 13.2169 +            }
 13.2170 +
 13.2171 +            // Delete our old data buffer.
 13.2172 +            Allocator::Free(pTable);
 13.2173 +        }
 13.2174 +
 13.2175 +        // Steal newHash's data.
 13.2176 +        pTable = newHash.pTable;
 13.2177 +        newHash.pTable = NULL;
 13.2178 +    }
 13.2179 +
 13.2180 +    struct TableType
 13.2181 +    {
 13.2182 +        UPInt EntryCount;
 13.2183 +        UPInt SizeMask;
 13.2184 +        // Entry array follows this structure
 13.2185 +        // in memory.
 13.2186 +    };
 13.2187 +    TableType*  pTable;
 13.2188 +};
 13.2189 +
 13.2190 +
 13.2191 +
 13.2192 +//-----------------------------------------------------------------------------------
 13.2193 +template<class C, class HashF = FixedSizeHash<C>,
 13.2194 +         class AltHashF = HashF, 
 13.2195 +         class Allocator = ContainerAllocator<C>,
 13.2196 +         class Entry = HashsetCachedEntry<C, HashF> >
 13.2197 +class HashSet : public HashSetBase<C, HashF, AltHashF, Allocator, Entry>
 13.2198 +{
 13.2199 +public:
 13.2200 +    typedef HashSetBase<C, HashF, AltHashF, Allocator, Entry> BaseType;
 13.2201 +    typedef HashSet<C, HashF, AltHashF, Allocator, Entry>     SelfType;
 13.2202 +
 13.2203 +    HashSet()                                      {   }
 13.2204 +    HashSet(int sizeHint) : BaseType(sizeHint)     {   }
 13.2205 +    HashSet(const SelfType& src) : BaseType(src)   {   }
 13.2206 +    ~HashSet()                                     {   }
 13.2207 +
 13.2208 +    void operator = (const SelfType& src)   { BaseType::Assign(src); }
 13.2209 +
 13.2210 +    // Set a new or existing value under the key, to the value.
 13.2211 +    // Pass a different class of 'key' so that assignment reference object
 13.2212 +    // can be passed instead of the actual object.
 13.2213 +    template<class CRef>
 13.2214 +    void Set(const CRef& key)
 13.2215 +    {
 13.2216 +        BaseType::Set(key);
 13.2217 +    }
 13.2218 +
 13.2219 +    template<class CRef>
 13.2220 +    inline void Add(const CRef& key)
 13.2221 +    {
 13.2222 +        BaseType::Add(key);
 13.2223 +    }
 13.2224 +
 13.2225 +    // Hint the bucket count to >= n.
 13.2226 +    void Resize(UPInt n)    
 13.2227 +    {
 13.2228 +        BaseType::SetCapacity(n);
 13.2229 +    }
 13.2230 +
 13.2231 +    // Size the HashSet so that it can comfortably contain the given
 13.2232 +    // number of elements.  If the HashSet already contains more
 13.2233 +    // elements than newSize, then this may be a no-op.
 13.2234 +    void SetCapacity(UPInt newSize)
 13.2235 +    {
 13.2236 +        BaseType::SetCapacity(newSize);
 13.2237 +    }
 13.2238 +
 13.2239 +};
 13.2240 +
 13.2241 +// HashSet with uncached hash code; declared for convenience.
 13.2242 +template<class C, class HashF = FixedSizeHash<C>,
 13.2243 +                  class AltHashF = HashF,
 13.2244 +                  class Allocator = ContainerAllocator<C> >
 13.2245 +class HashSetUncached : public HashSet<C, HashF, AltHashF, Allocator, HashsetEntry<C, HashF> >
 13.2246 +{
 13.2247 +public:
 13.2248 +    
 13.2249 +    typedef HashSetUncached<C, HashF, AltHashF, Allocator>                  SelfType;
 13.2250 +    typedef HashSet<C, HashF, AltHashF, Allocator, HashsetEntry<C, HashF> > BaseType;
 13.2251 +
 13.2252 +    // Delegated constructors.
 13.2253 +    HashSetUncached()                                        { }
 13.2254 +    HashSetUncached(int sizeHint) : BaseType(sizeHint)       { }
 13.2255 +    HashSetUncached(const SelfType& src) : BaseType(src)     { }
 13.2256 +    ~HashSetUncached()                                       { }
 13.2257 +    
 13.2258 +    void    operator = (const SelfType& src)
 13.2259 +    {
 13.2260 +        BaseType::operator = (src);
 13.2261 +    }
 13.2262 +};
 13.2263 +
 13.2264 +
 13.2265 +//-----------------------------------------------------------------------------------
 13.2266 +// ***** Hash hash table implementation
 13.2267 +
 13.2268 +// Node for Hash - necessary so that Hash can delegate its implementation
 13.2269 +// to HashSet.
 13.2270 +template<class C, class U, class HashF>
 13.2271 +struct HashNode
 13.2272 +{
 13.2273 +    typedef HashNode<C, U, HashF>   SelfType;
 13.2274 +    typedef C                       FirstType;
 13.2275 +    typedef U                       SecondType;
 13.2276 +
 13.2277 +    C   First;
 13.2278 +    U   Second;
 13.2279 +
 13.2280 +    // NodeRef is used to allow passing of elements into HashSet
 13.2281 +    // without using a temporary object.
 13.2282 +    struct NodeRef
 13.2283 +    {
 13.2284 +        const C*   pFirst;
 13.2285 +        const U*   pSecond;
 13.2286 +
 13.2287 +        NodeRef(const C& f, const U& s) : pFirst(&f), pSecond(&s) { }
 13.2288 +        NodeRef(const NodeRef& src)     : pFirst(src.pFirst), pSecond(src.pSecond) { }
 13.2289 +
 13.2290 +        // Enable computation of ghash_node_hashf.
 13.2291 +        inline UPInt GetHash() const            { return HashF()(*pFirst); } 
 13.2292 +        // Necessary conversion to allow HashNode::operator == to work.
 13.2293 +        operator const C& () const              { return *pFirst; }
 13.2294 +    };
 13.2295 +
 13.2296 +    // Note: No default constructor is necessary.
 13.2297 +     HashNode(const HashNode& src) : First(src.First), Second(src.Second)    { }
 13.2298 +     HashNode(const NodeRef& src) : First(*src.pFirst), Second(*src.pSecond)  { }
 13.2299 +    void operator = (const NodeRef& src)  { First  = *src.pFirst; Second = *src.pSecond; }
 13.2300 +
 13.2301 +    template<class K>
 13.2302 +    bool operator == (const K& src) const   { return (First == src); }
 13.2303 +
 13.2304 +    template<class K>
 13.2305 +    static UPInt CalcHash(const K& data)   { return HashF()(data); }
 13.2306 +    inline UPInt GetHash() const           { return HashF()(First); }
 13.2307 +
 13.2308 +    // Hash functors used with this node. A separate functor is used for alternative
 13.2309 +    // key lookup so that it does not need to access the '.First' element.    
 13.2310 +    struct NodeHashF
 13.2311 +    {    
 13.2312 +        template<class K>
 13.2313 +        UPInt operator()(const K& data) const { return data.GetHash(); } 
 13.2314 +    };    
 13.2315 +    struct NodeAltHashF
 13.2316 +    {
 13.2317 +        template<class K>
 13.2318 +        UPInt operator()(const K& data) const { return HashNode<C,U,HashF>::CalcHash(data); }
 13.2319 +    };
 13.2320 +};
 13.2321 +
 13.2322 +
 13.2323 +
 13.2324 +// **** Extra hashset_entry types to allow NodeRef construction.
 13.2325 +
 13.2326 +// The big difference between the below types and the ones used in hash_set is that
 13.2327 +// these allow initializing the node with 'typename C::NodeRef& keyRef', which
 13.2328 +// is critical to avoid temporary node allocation on stack when using placement new.
 13.2329 +
 13.2330 +// Compact hash table Entry type that re-computes hash keys during hash traversal.
 13.2331 +// Good to use if the hash function is cheap or the hash value is already cached in C.
 13.2332 +template<class C, class HashF>
 13.2333 +class HashsetNodeEntry
 13.2334 +{
 13.2335 +public:
 13.2336 +    // Internal chaining for collisions.
 13.2337 +    SPInt NextInChain;
 13.2338 +    C     Value;
 13.2339 +
 13.2340 +    HashsetNodeEntry()
 13.2341 +        : NextInChain(-2) { }
 13.2342 +    HashsetNodeEntry(const HashsetNodeEntry& e)
 13.2343 +        : NextInChain(e.NextInChain), Value(e.Value) { }
 13.2344 +    HashsetNodeEntry(const C& key, SPInt next)
 13.2345 +        : NextInChain(next), Value(key) { }    
 13.2346 +    HashsetNodeEntry(const typename C::NodeRef& keyRef, SPInt next)
 13.2347 +        : NextInChain(next), Value(keyRef) { }
 13.2348 +
 13.2349 +    bool    IsEmpty() const             { return NextInChain == -2;  }
 13.2350 +    bool    IsEndOfChain() const        { return NextInChain == -1;  }
 13.2351 +    UPInt   GetCachedHash(UPInt maskValue) const  { return HashF()(Value) & maskValue; }
 13.2352 +    void    SetCachedHash(UPInt hashValue)        { OVR_UNUSED(hashValue); }
 13.2353 +
 13.2354 +    void    Clear()
 13.2355 +    {        
 13.2356 +        Value.~C(); // placement delete
 13.2357 +        NextInChain = -2;
 13.2358 +    }
 13.2359 +    // Free is only used from dtor of hash; Clear is used during regular operations:
 13.2360 +    // assignment, hash reallocations, value reassignments, so on.
 13.2361 +    void    Free() { Clear(); }
 13.2362 +};
 13.2363 +
 13.2364 +// Hash table Entry type that caches the Entry hash value for nodes, so that it
 13.2365 +// does not need to be re-computed during access.
 13.2366 +template<class C, class HashF>
 13.2367 +class HashsetCachedNodeEntry
 13.2368 +{
 13.2369 +public:
 13.2370 +    // Internal chaining for collisions.
 13.2371 +    SPInt NextInChain;
 13.2372 +    UPInt HashValue;
 13.2373 +    C     Value;
 13.2374 +
 13.2375 +    HashsetCachedNodeEntry()
 13.2376 +        : NextInChain(-2) { }
 13.2377 +    HashsetCachedNodeEntry(const HashsetCachedNodeEntry& e)
 13.2378 +        : NextInChain(e.NextInChain), HashValue(e.HashValue), Value(e.Value) { }
 13.2379 +    HashsetCachedNodeEntry(const C& key, SPInt next)
 13.2380 +        : NextInChain(next), Value(key) { }
 13.2381 +    HashsetCachedNodeEntry(const typename C::NodeRef& keyRef, SPInt next)
 13.2382 +        : NextInChain(next), Value(keyRef) { }
 13.2383 +
 13.2384 +    bool    IsEmpty() const            { return NextInChain == -2;  }
 13.2385 +    bool    IsEndOfChain() const       { return NextInChain == -1;  }
 13.2386 +    UPInt   GetCachedHash(UPInt maskValue) const  { OVR_UNUSED(maskValue); return HashValue; }
 13.2387 +    void    SetCachedHash(UPInt hashValue)        { HashValue = hashValue; }
 13.2388 +
 13.2389 +    void    Clear()
 13.2390 +    {
 13.2391 +        Value.~C();
 13.2392 +        NextInChain = -2;
 13.2393 +    }
 13.2394 +    // Free is only used from dtor of hash; Clear is used during regular operations:
 13.2395 +    // assignment, hash reallocations, value reassignments, so on.
 13.2396 +    void    Free() { Clear(); }
 13.2397 +};
 13.2398 +
 13.2399 +
 13.2400 +//-----------------------------------------------------------------------------------
 13.2401 +template<class C, class U,
 13.2402 +         class HashF = FixedSizeHash<C>,
 13.2403 +         class Allocator = ContainerAllocator<C>,
 13.2404 +         class HashNode = OVR::HashNode<C,U,HashF>,
 13.2405 +         class Entry = HashsetCachedNodeEntry<HashNode, typename HashNode::NodeHashF>,
 13.2406 +         class Container =  HashSet<HashNode, typename HashNode::NodeHashF,
 13.2407 +             typename HashNode::NodeAltHashF, Allocator,
 13.2408 +             Entry> >
 13.2409 +class Hash
 13.2410 +{
 13.2411 +public:
 13.2412 +    OVR_MEMORY_REDEFINE_NEW(Hash)
 13.2413 +
 13.2414 +    // Types used for hash_set.
 13.2415 +    typedef U                                                           ValueType;
 13.2416 +    typedef Hash<C, U, HashF, Allocator, HashNode, Entry, Container>    SelfType;
 13.2417 +
 13.2418 +    // Actual hash table itself, implemented as hash_set.
 13.2419 +    Container   mHash;
 13.2420 +
 13.2421 +public:
 13.2422 +    Hash()     {  }
 13.2423 +    Hash(int sizeHint) : mHash(sizeHint)                        { }
 13.2424 +    Hash(const SelfType& src) : mHash(src.mHash)                { }
 13.2425 +    ~Hash()                                                     { }
 13.2426 +
 13.2427 +    void    operator = (const SelfType& src)    { mHash = src.mHash; }
 13.2428 +
 13.2429 +    // Remove all entries from the Hash table.
 13.2430 +    inline void    Clear() { mHash.Clear(); }
 13.2431 +    // Returns true if the Hash is empty.
 13.2432 +    inline bool    IsEmpty() const { return mHash.IsEmpty(); }
 13.2433 +
 13.2434 +    // Access (set).
 13.2435 +    inline void    Set(const C& key, const U& value)
 13.2436 +    {
 13.2437 +        typename HashNode::NodeRef e(key, value);
 13.2438 +        mHash.Set(e);
 13.2439 +    }
 13.2440 +    inline void    Add(const C& key, const U& value)
 13.2441 +    {
 13.2442 +        typename HashNode::NodeRef e(key, value);
 13.2443 +        mHash.Add(e);
 13.2444 +    }
 13.2445 +
 13.2446 +    // Removes an element by clearing its Entry.
 13.2447 +    inline void     Remove(const C& key)
 13.2448 +    {   
 13.2449 +        mHash.RemoveAlt(key);
 13.2450 +    }
 13.2451 +    template<class K>
 13.2452 +    inline void     RemoveAlt(const K& key)
 13.2453 +    {   
 13.2454 +        mHash.RemoveAlt(key);
 13.2455 +    }
 13.2456 +
 13.2457 +    // Retrieve the value under the given key.    
 13.2458 +    //  - If there's no value under the key, then return false and leave *pvalue alone.
 13.2459 +    //  - If there is a value, return true, and Set *Pvalue to the Entry's value.
 13.2460 +    //  - If value == NULL, return true or false according to the presence of the key.    
 13.2461 +    bool    Get(const C& key, U* pvalue) const   
 13.2462 +    {
 13.2463 +        const HashNode* p = mHash.GetAlt(key);
 13.2464 +        if (p)
 13.2465 +        {
 13.2466 +            if (pvalue)
 13.2467 +                *pvalue = p->Second;
 13.2468 +            return true;
 13.2469 +        }
 13.2470 +        return false;
 13.2471 +    }
 13.2472 +
 13.2473 +    template<class K>
 13.2474 +    bool    GetAlt(const K& key, U* pvalue) const   
 13.2475 +    {
 13.2476 +        const HashNode* p = mHash.GetAlt(key);
 13.2477 +        if (p)
 13.2478 +        {
 13.2479 +            if (pvalue)
 13.2480 +                *pvalue = p->Second;
 13.2481 +            return true;
 13.2482 +        }
 13.2483 +        return false;
 13.2484 +    }
 13.2485 +
 13.2486 +    // Retrieve the pointer to a value under the given key.    
 13.2487 +    //  - If there's no value under the key, then return NULL.    
 13.2488 +    //  - If there is a value, return the pointer.    
 13.2489 +    inline U*  Get(const C& key)
 13.2490 +    {
 13.2491 +        HashNode* p = mHash.GetAlt(key);
 13.2492 +        return p ? &p->Second : 0;
 13.2493 +    }
 13.2494 +    inline const U* Get(const C& key) const
 13.2495 +    {
 13.2496 +        const HashNode* p = mHash.GetAlt(key);
 13.2497 +        return p ? &p->Second : 0;
 13.2498 +    }
 13.2499 +
 13.2500 +    template<class K>
 13.2501 +    inline U*  GetAlt(const K& key)
 13.2502 +    {
 13.2503 +        HashNode* p = mHash.GetAlt(key);
 13.2504 +        return p ? &p->Second : 0;
 13.2505 +    }
 13.2506 +    template<class K>
 13.2507 +    inline const U* GetAlt(const K& key) const
 13.2508 +    {
 13.2509 +        const HashNode* p = mHash.GetAlt(key);
 13.2510 +        return p ? &p->Second : 0;
 13.2511 +    }
 13.2512 +
 13.2513 +    // Sizing methods - delegate to Hash.
 13.2514 +    inline UPInt   GetSize() const              { return mHash.GetSize(); }    
 13.2515 +    inline void    Resize(UPInt n)              { mHash.Resize(n); }
 13.2516 +    inline void    SetCapacity(UPInt newSize)   { mHash.SetCapacity(newSize); }
 13.2517 +
 13.2518 +    // Iterator API, like STL.
 13.2519 +    typedef typename Container::ConstIterator   ConstIterator;
 13.2520 +    typedef typename Container::Iterator        Iterator;
 13.2521 +
 13.2522 +    inline Iterator        Begin()              { return mHash.Begin(); }
 13.2523 +    inline Iterator        End()                { return mHash.End(); }
 13.2524 +    inline ConstIterator   Begin() const        { return mHash.Begin(); }
 13.2525 +    inline ConstIterator   End() const          { return mHash.End();   }
 13.2526 +
 13.2527 +    Iterator        Find(const C& key)          { return mHash.FindAlt(key);  }
 13.2528 +    ConstIterator   Find(const C& key) const    { return mHash.FindAlt(key);  }
 13.2529 +
 13.2530 +    template<class K>
 13.2531 +    Iterator        FindAlt(const K& key)       { return mHash.FindAlt(key);  }
 13.2532 +    template<class K>
 13.2533 +    ConstIterator   FindAlt(const K& key) const { return mHash.FindAlt(key);  }
 13.2534 +};
 13.2535 +
 13.2536 +
 13.2537 +
 13.2538 +// Hash with uncached hash code; declared for convenience.
 13.2539 +template<class C, class U, class HashF = FixedSizeHash<C>, class Allocator = ContainerAllocator<C> >
 13.2540 +class HashUncached
 13.2541 +    : public Hash<C, U, HashF, Allocator, HashNode<C,U,HashF>,
 13.2542 +                   HashsetNodeEntry<HashNode<C,U,HashF>, typename HashNode<C,U,HashF>::NodeHashF> >
 13.2543 +{
 13.2544 +public:
 13.2545 +    typedef HashUncached<C, U, HashF, Allocator>                SelfType;
 13.2546 +    typedef Hash<C, U, HashF, Allocator, HashNode<C,U,HashF>,
 13.2547 +                 HashsetNodeEntry<HashNode<C,U,HashF>,
 13.2548 +                 typename HashNode<C,U,HashF>::NodeHashF> >     BaseType;
 13.2549 +
 13.2550 +    // Delegated constructors.
 13.2551 +    HashUncached()                                        { }
 13.2552 +    HashUncached(int sizeHint) : BaseType(sizeHint)       { }
 13.2553 +    HashUncached(const SelfType& src) : BaseType(src)     { }
 13.2554 +    ~HashUncached()                                       { }
 13.2555 +    void operator = (const SelfType& src)                 { BaseType::operator = (src); }
 13.2556 +};
 13.2557 +
 13.2558 +
 13.2559 +
 13.2560 +// And identity hash in which keys serve as hash value. Can be uncached,
 13.2561 +// since hash computation is assumed cheap.
 13.2562 +template<class C, class U, class Allocator = ContainerAllocator<C>, class HashF = IdentityHash<C> >
 13.2563 +class HashIdentity
 13.2564 +    : public HashUncached<C, U, HashF, Allocator>
 13.2565 +{
 13.2566 +public:
 13.2567 +    typedef HashIdentity<C, U, Allocator, HashF> SelfType;
 13.2568 +    typedef HashUncached<C, U, HashF, Allocator> BaseType;
 13.2569 +
 13.2570 +    // Delegated constructors.
 13.2571 +    HashIdentity()                                        { }
 13.2572 +    HashIdentity(int sizeHint) : BaseType(sizeHint)       { }
 13.2573 +    HashIdentity(const SelfType& src) : BaseType(src)     { }
 13.2574 +    ~HashIdentity()                                       { }
 13.2575 +    void operator = (const SelfType& src)                 { BaseType::operator = (src); }
 13.2576 +};
 13.2577 +
 13.2578 +
 13.2579 +} // OVR
 13.2580 +
 13.2581 +
 13.2582 +#ifdef OVR_DEFINE_NEW
 13.2583 +#define new OVR_DEFINE_NEW
 13.2584 +#endif
 13.2585 +
 13.2586 +#endif
    14.1 --- a/libovr/Src/Kernel/OVR_KeyCodes.h	Sat Sep 14 17:51:03 2013 +0300
    14.2 +++ b/libovr/Src/Kernel/OVR_KeyCodes.h	Sun Sep 15 04:10:05 2013 +0300
    14.3 @@ -1,1 +1,240 @@
    14.4 -/************************************************************************************
    14.5 
    14.6 PublicHeader:   OVR.h
    14.7 Filename    :   OVR_KeyCodes.h
    14.8 Content     :   Common keyboard constants
    14.9 Created     :   September 19, 2012
   14.10 
   14.11 Copyright   :   Copyright 2012 Oculus VR, Inc. All Rights reserved.
   14.12 
   14.13 Use of this software is subject to the terms of the Oculus license
   14.14 agreement provided at the time of installation or download, or which
   14.15 otherwise accompanies this software in either electronic or hard copy form.
   14.16 
   14.17 ************************************************************************************/
   14.18 
   14.19 #ifndef OVR_KeyCodes_h
   14.20 #define OVR_KeyCodes_h
   14.21 
   14.22 namespace OVR {
   14.23 
   14.24 //-----------------------------------------------------------------------------------
   14.25 // ***** KeyCode
   14.26 
   14.27 // KeyCode enumeration defines platform-independent keyboard key constants.
   14.28 // Note that Key_A through Key_Z are mapped to capital ascii constants.
   14.29 
   14.30 enum KeyCode
   14.31 {
   14.32     // Key_None indicates that no key was specified.
   14.33     Key_None            = 0, 
   14.34 
   14.35     // A through Z and numbers 0 through 9.
   14.36     Key_A               = 65,
   14.37     Key_B,
   14.38     Key_C,
   14.39     Key_D,
   14.40     Key_E,
   14.41     Key_F,
   14.42     Key_G,
   14.43     Key_H,
   14.44     Key_I,
   14.45     Key_J,
   14.46     Key_K,
   14.47     Key_L,
   14.48     Key_M,
   14.49     Key_N,
   14.50     Key_O,
   14.51     Key_P,
   14.52     Key_Q,
   14.53     Key_R,
   14.54     Key_S,
   14.55     Key_T,
   14.56     Key_U,
   14.57     Key_V,
   14.58     Key_W,
   14.59     Key_X,
   14.60     Key_Y,
   14.61     Key_Z,
   14.62     Key_Num0            = 48,
   14.63     Key_Num1,
   14.64     Key_Num2,
   14.65     Key_Num3,
   14.66     Key_Num4,
   14.67     Key_Num5,
   14.68     Key_Num6,
   14.69     Key_Num7,
   14.70     Key_Num8,
   14.71     Key_Num9,
   14.72 
   14.73     // Numeric keypad.
   14.74     Key_KP_0            = 0xa0,
   14.75     Key_KP_1,
   14.76     Key_KP_2,
   14.77     Key_KP_3,
   14.78     Key_KP_4,
   14.79     Key_KP_5,
   14.80     Key_KP_6,
   14.81     Key_KP_7,
   14.82     Key_KP_8,
   14.83     Key_KP_9,
   14.84     Key_KP_Multiply,
   14.85     Key_KP_Add,
   14.86     Key_KP_Enter,
   14.87     Key_KP_Subtract,
   14.88     Key_KP_Decimal,
   14.89     Key_KP_Divide,
   14.90     
   14.91     // Function keys.
   14.92     Key_F1              = 0xb0,
   14.93     Key_F2,
   14.94     Key_F3,
   14.95     Key_F4,
   14.96     Key_F5,
   14.97     Key_F6,
   14.98     Key_F7,
   14.99     Key_F8,
  14.100     Key_F9,
  14.101     Key_F10,
  14.102     Key_F11,
  14.103     Key_F12,
  14.104     Key_F13,
  14.105     Key_F14,
  14.106     Key_F15,
  14.107     
  14.108     // Other keys.
  14.109     Key_Backspace       = 8,
  14.110     Key_Tab,
  14.111     Key_Clear           = 12,
  14.112     Key_Return,
  14.113     Key_Shift           = 16,
  14.114     Key_Control,
  14.115     Key_Alt,
  14.116     Key_Pause,
  14.117     Key_CapsLock        = 20, // Toggle
  14.118     Key_Escape          = 27,
  14.119     Key_Space           = 32,
  14.120     Key_Quote           = 39,
  14.121     Key_PageUp          = 0xc0,
  14.122     Key_PageDown,
  14.123     Key_End,
  14.124     Key_Home,
  14.125     Key_Left,
  14.126     Key_Up,
  14.127     Key_Right,
  14.128     Key_Down,
  14.129     Key_Insert,
  14.130     Key_Delete,
  14.131     Key_Help,
  14.132     
  14.133     Key_Comma           = 44,
  14.134     Key_Minus,
  14.135     Key_Slash           = 47,
  14.136     Key_Period,
  14.137     Key_NumLock         = 144, // Toggle
  14.138     Key_ScrollLock      = 145, // Toggle
  14.139     
  14.140     Key_Semicolon       = 59,
  14.141     Key_Equal           = 61,
  14.142     Key_Bar             = 192,
  14.143     Key_BracketLeft     = 91,
  14.144     Key_Backslash,
  14.145     Key_BracketRight,
  14.146 
  14.147     Key_OEM_AX          = 0xE1,  //  'AX' key on Japanese AX keyboard
  14.148     Key_OEM_102         = 0xE2,  //  "<>" or "\|" on RT 102-key keyboard.
  14.149     Key_ICO_HELP        = 0xE3,  //  Help key on ICO
  14.150     Key_ICO_00          = 0xE4,  //  00 key on ICO
  14.151 
  14.152     Key_Meta,
  14.153 
  14.154     // Total number of keys.
  14.155     Key_CodeCount
  14.156 };
  14.157 
  14.158 
  14.159 //-----------------------------------------------------------------------------------
  14.160 
  14.161 class KeyModifiers 
  14.162 {
  14.163 public:
  14.164     enum
  14.165     {
  14.166         Key_ShiftPressed    = 0x01,
  14.167         Key_CtrlPressed     = 0x02,
  14.168         Key_AltPressed      = 0x04,
  14.169         Key_MetaPressed     = 0x08,
  14.170         Key_CapsToggled     = 0x10,
  14.171         Key_NumToggled      = 0x20,
  14.172         Key_ScrollToggled   = 0x40,
  14.173 
  14.174         Initialized_Bit     = 0x80,
  14.175         Initialized_Mask    = 0xFF
  14.176     };
  14.177     unsigned char States;
  14.178 
  14.179     KeyModifiers() : States(0) { }
  14.180         KeyModifiers(unsigned char st) : States((unsigned char)(st | Initialized_Bit)) { }
  14.181 
  14.182     void Reset() { States = 0; }
  14.183 
  14.184     bool IsShiftPressed() const { return (States & Key_ShiftPressed) != 0; }
  14.185     bool IsCtrlPressed() const  { return (States & Key_CtrlPressed) != 0; }
  14.186     bool IsAltPressed() const   { return (States & Key_AltPressed) != 0; }
  14.187     bool IsMetaPressed() const  { return (States & Key_MetaPressed) != 0; }
  14.188     bool IsCapsToggled() const  { return (States & Key_CapsToggled) != 0; }
  14.189     bool IsNumToggled() const   { return (States & Key_NumToggled) != 0; }
  14.190     bool IsScrollToggled() const{ return (States & Key_ScrollToggled) != 0; }
  14.191 
  14.192     void SetShiftPressed(bool v = true)  { (v) ? States |= Key_ShiftPressed : States &= ~Key_ShiftPressed; }
  14.193     void SetCtrlPressed(bool v = true)   { (v) ? States |= Key_CtrlPressed  : States &= ~Key_CtrlPressed; }
  14.194     void SetAltPressed(bool v = true)    { (v) ? States |= Key_AltPressed   : States &= ~Key_AltPressed; }
  14.195     void SetMetaPressed(bool v = true)   { (v) ? States |= Key_MetaPressed  : States &= ~Key_MetaPressed; }
  14.196     void SetCapsToggled(bool v = true)   { (v) ? States |= Key_CapsToggled  : States &= ~Key_CapsToggled; }
  14.197     void SetNumToggled(bool v = true)    { (v) ? States |= Key_NumToggled   : States &= ~Key_NumToggled; }
  14.198     void SetScrollToggled(bool v = true) { (v) ? States |= Key_ScrollToggled: States &= ~Key_ScrollToggled; }
  14.199 
  14.200     bool IsInitialized() const { return (States & Initialized_Mask) != 0; }
  14.201 };
  14.202 
  14.203 
  14.204 //-----------------------------------------------------------------------------------
  14.205 
  14.206 /*
  14.207 enum PadKeyCode
  14.208 {
  14.209     Pad_None, // Indicates absence of key code.
  14.210     Pad_Back,
  14.211     Pad_Start,
  14.212     Pad_A,
  14.213     Pad_B,
  14.214     Pad_X,
  14.215     Pad_Y,
  14.216     Pad_R1,  // RightShoulder;
  14.217     Pad_L1,  // LeftShoulder;
  14.218     Pad_R2,  // RightTrigger;
  14.219     Pad_L2,  // LeftTrigger;
  14.220     Pad_Up,
  14.221     Pad_Down,
  14.222     Pad_Right,
  14.223     Pad_Left,
  14.224     Pad_Plus,
  14.225     Pad_Minus,
  14.226     Pad_1,
  14.227     Pad_2,
  14.228     Pad_H,
  14.229     Pad_C,
  14.230     Pad_Z,
  14.231     Pad_O,
  14.232     Pad_T,
  14.233     Pad_S,
  14.234     Pad_Select,
  14.235     Pad_Home,
  14.236     Pad_RT,  // RightThumb;
  14.237     Pad_LT   // LeftThumb;
  14.238 };
  14.239 */
  14.240 
  14.241 } // OVR
  14.242 
  14.243 #endif
  14.244 \ No newline at end of file
  14.245 +/************************************************************************************
  14.246 +
  14.247 +PublicHeader:   OVR.h
  14.248 +Filename    :   OVR_KeyCodes.h
  14.249 +Content     :   Common keyboard constants
  14.250 +Created     :   September 19, 2012
  14.251 +
  14.252 +Copyright   :   Copyright 2012 Oculus VR, Inc. All Rights reserved.
  14.253 +
  14.254 +Use of this software is subject to the terms of the Oculus license
  14.255 +agreement provided at the time of installation or download, or which
  14.256 +otherwise accompanies this software in either electronic or hard copy form.
  14.257 +
  14.258 +************************************************************************************/
  14.259 +
  14.260 +#ifndef OVR_KeyCodes_h
  14.261 +#define OVR_KeyCodes_h
  14.262 +
  14.263 +namespace OVR {
  14.264 +
  14.265 +//-----------------------------------------------------------------------------------
  14.266 +// ***** KeyCode
  14.267 +
  14.268 +// KeyCode enumeration defines platform-independent keyboard key constants.
  14.269 +// Note that Key_A through Key_Z are mapped to capital ascii constants.
  14.270 +
  14.271 +enum KeyCode
  14.272 +{
  14.273 +    // Key_None indicates that no key was specified.
  14.274 +    Key_None            = 0, 
  14.275 +
  14.276 +    // A through Z and numbers 0 through 9.
  14.277 +    Key_A               = 65,
  14.278 +    Key_B,
  14.279 +    Key_C,
  14.280 +    Key_D,
  14.281 +    Key_E,
  14.282 +    Key_F,
  14.283 +    Key_G,
  14.284 +    Key_H,
  14.285 +    Key_I,
  14.286 +    Key_J,
  14.287 +    Key_K,
  14.288 +    Key_L,
  14.289 +    Key_M,
  14.290 +    Key_N,
  14.291 +    Key_O,
  14.292 +    Key_P,
  14.293 +    Key_Q,
  14.294 +    Key_R,
  14.295 +    Key_S,
  14.296 +    Key_T,
  14.297 +    Key_U,
  14.298 +    Key_V,
  14.299 +    Key_W,
  14.300 +    Key_X,
  14.301 +    Key_Y,
  14.302 +    Key_Z,
  14.303 +    Key_Num0            = 48,
  14.304 +    Key_Num1,
  14.305 +    Key_Num2,
  14.306 +    Key_Num3,
  14.307 +    Key_Num4,
  14.308 +    Key_Num5,
  14.309 +    Key_Num6,
  14.310 +    Key_Num7,
  14.311 +    Key_Num8,
  14.312 +    Key_Num9,
  14.313 +
  14.314 +    // Numeric keypad.
  14.315 +    Key_KP_0            = 0xa0,
  14.316 +    Key_KP_1,
  14.317 +    Key_KP_2,
  14.318 +    Key_KP_3,
  14.319 +    Key_KP_4,
  14.320 +    Key_KP_5,
  14.321 +    Key_KP_6,
  14.322 +    Key_KP_7,
  14.323 +    Key_KP_8,
  14.324 +    Key_KP_9,
  14.325 +    Key_KP_Multiply,
  14.326 +    Key_KP_Add,
  14.327 +    Key_KP_Enter,
  14.328 +    Key_KP_Subtract,
  14.329 +    Key_KP_Decimal,
  14.330 +    Key_KP_Divide,
  14.331 +    
  14.332 +    // Function keys.
  14.333 +    Key_F1              = 0xb0,
  14.334 +    Key_F2,
  14.335 +    Key_F3,
  14.336 +    Key_F4,
  14.337 +    Key_F5,
  14.338 +    Key_F6,
  14.339 +    Key_F7,
  14.340 +    Key_F8,
  14.341 +    Key_F9,
  14.342 +    Key_F10,
  14.343 +    Key_F11,
  14.344 +    Key_F12,
  14.345 +    Key_F13,
  14.346 +    Key_F14,
  14.347 +    Key_F15,
  14.348 +    
  14.349 +    // Other keys.
  14.350 +    Key_Backspace       = 8,
  14.351 +    Key_Tab,
  14.352 +    Key_Clear           = 12,
  14.353 +    Key_Return,
  14.354 +    Key_Shift           = 16,
  14.355 +    Key_Control,
  14.356 +    Key_Alt,
  14.357 +    Key_Pause,
  14.358 +    Key_CapsLock        = 20, // Toggle
  14.359 +    Key_Escape          = 27,
  14.360 +    Key_Space           = 32,
  14.361 +    Key_Quote           = 39,
  14.362 +    Key_PageUp          = 0xc0,
  14.363 +    Key_PageDown,
  14.364 +    Key_End,
  14.365 +    Key_Home,
  14.366 +    Key_Left,
  14.367 +    Key_Up,
  14.368 +    Key_Right,
  14.369 +    Key_Down,
  14.370 +    Key_Insert,
  14.371 +    Key_Delete,
  14.372 +    Key_Help,
  14.373 +    
  14.374 +    Key_Comma           = 44,
  14.375 +    Key_Minus,
  14.376 +    Key_Slash           = 47,
  14.377 +    Key_Period,
  14.378 +    Key_NumLock         = 144, // Toggle
  14.379 +    Key_ScrollLock      = 145, // Toggle
  14.380 +    
  14.381 +    Key_Semicolon       = 59,
  14.382 +    Key_Equal           = 61,
  14.383 +    Key_Bar             = 192,
  14.384 +    Key_BracketLeft     = 91,
  14.385 +    Key_Backslash,
  14.386 +    Key_BracketRight,
  14.387 +
  14.388 +    Key_OEM_AX          = 0xE1,  //  'AX' key on Japanese AX keyboard
  14.389 +    Key_OEM_102         = 0xE2,  //  "<>" or "\|" on RT 102-key keyboard.
  14.390 +    Key_ICO_HELP        = 0xE3,  //  Help key on ICO
  14.391 +    Key_ICO_00          = 0xE4,  //  00 key on ICO
  14.392 +
  14.393 +    Key_Meta,
  14.394 +
  14.395 +    // Total number of keys.
  14.396 +    Key_CodeCount
  14.397 +};
  14.398 +
  14.399 +
  14.400 +//-----------------------------------------------------------------------------------
  14.401 +
  14.402 +class KeyModifiers 
  14.403 +{
  14.404 +public:
  14.405 +    enum
  14.406 +    {
  14.407 +        Key_ShiftPressed    = 0x01,
  14.408 +        Key_CtrlPressed     = 0x02,
  14.409 +        Key_AltPressed      = 0x04,
  14.410 +        Key_MetaPressed     = 0x08,
  14.411 +        Key_CapsToggled     = 0x10,
  14.412 +        Key_NumToggled      = 0x20,
  14.413 +        Key_ScrollToggled   = 0x40,
  14.414 +
  14.415 +        Initialized_Bit     = 0x80,
  14.416 +        Initialized_Mask    = 0xFF
  14.417 +    };
  14.418 +    unsigned char States;
  14.419 +
  14.420 +    KeyModifiers() : States(0) { }
  14.421 +        KeyModifiers(unsigned char st) : States((unsigned char)(st | Initialized_Bit)) { }
  14.422 +
  14.423 +    void Reset() { States = 0; }
  14.424 +
  14.425 +    bool IsShiftPressed() const { return (States & Key_ShiftPressed) != 0; }
  14.426 +    bool IsCtrlPressed() const  { return (States & Key_CtrlPressed) != 0; }
  14.427 +    bool IsAltPressed() const   { return (States & Key_AltPressed) != 0; }
  14.428 +    bool IsMetaPressed() const  { return (States & Key_MetaPressed) != 0; }
  14.429 +    bool IsCapsToggled() const  { return (States & Key_CapsToggled) != 0; }
  14.430 +    bool IsNumToggled() const   { return (States & Key_NumToggled) != 0; }
  14.431 +    bool IsScrollToggled() const{ return (States & Key_ScrollToggled) != 0; }
  14.432 +
  14.433 +    void SetShiftPressed(bool v = true)  { (v) ? States |= Key_ShiftPressed : States &= ~Key_ShiftPressed; }
  14.434 +    void SetCtrlPressed(bool v = true)   { (v) ? States |= Key_CtrlPressed  : States &= ~Key_CtrlPressed; }
  14.435 +    void SetAltPressed(bool v = true)    { (v) ? States |= Key_AltPressed   : States &= ~Key_AltPressed; }
  14.436 +    void SetMetaPressed(bool v = true)   { (v) ? States |= Key_MetaPressed  : States &= ~Key_MetaPressed; }
  14.437 +    void SetCapsToggled(bool v = true)   { (v) ? States |= Key_CapsToggled  : States &= ~Key_CapsToggled; }
  14.438 +    void SetNumToggled(bool v = true)    { (v) ? States |= Key_NumToggled   : States &= ~Key_NumToggled; }
  14.439 +    void SetScrollToggled(bool v = true) { (v) ? States |= Key_ScrollToggled: States &= ~Key_ScrollToggled; }
  14.440 +
  14.441 +    bool IsInitialized() const { return (States & Initialized_Mask) != 0; }
  14.442 +};
  14.443 +
  14.444 +
  14.445 +//-----------------------------------------------------------------------------------
  14.446 +
  14.447 +/*
  14.448 +enum PadKeyCode
  14.449 +{
  14.450 +    Pad_None, // Indicates absence of key code.
  14.451 +    Pad_Back,
  14.452 +    Pad_Start,
  14.453 +    Pad_A,
  14.454 +    Pad_B,
  14.455 +    Pad_X,
  14.456 +    Pad_Y,
  14.457 +    Pad_R1,  // RightShoulder;
  14.458 +    Pad_L1,  // LeftShoulder;
  14.459 +    Pad_R2,  // RightTrigger;
  14.460 +    Pad_L2,  // LeftTrigger;
  14.461 +    Pad_Up,
  14.462 +    Pad_Down,
  14.463 +    Pad_Right,
  14.464 +    Pad_Left,
  14.465 +    Pad_Plus,
  14.466 +    Pad_Minus,
  14.467 +    Pad_1,
  14.468 +    Pad_2,
  14.469 +    Pad_H,
  14.470 +    Pad_C,
  14.471 +    Pad_Z,
  14.472 +    Pad_O,
  14.473 +    Pad_T,
  14.474 +    Pad_S,
  14.475 +    Pad_Select,
  14.476 +    Pad_Home,
  14.477 +    Pad_RT,  // RightThumb;
  14.478 +    Pad_LT   // LeftThumb;
  14.479 +};
  14.480 +*/
  14.481 +
  14.482 +} // OVR
  14.483 +
  14.484 +#endif
    15.1 --- a/libovr/Src/Kernel/OVR_List.h	Sat Sep 14 17:51:03 2013 +0300
    15.2 +++ b/libovr/Src/Kernel/OVR_List.h	Sun Sep 15 04:10:05 2013 +0300
    15.3 @@ -1,1 +1,325 @@
    15.4 -/************************************************************************************
    15.5 
    15.6 PublicHeader:   OVR
    15.7 Filename    :   OVR_List.h
    15.8 Content     :   Template implementation for doubly-connected linked List
    15.9 Created     :   September 19, 2012
   15.10 Notes       : 
   15.11 
   15.12 Copyright   :   Copyright 2012 Oculus VR, Inc. All Rights reserved.
   15.13 
   15.14 Use of this software is subject to the terms of the Oculus license
   15.15 agreement provided at the time of installation or download, or which
   15.16 otherwise accompanies this software in either electronic or hard copy form.
   15.17 
   15.18 ************************************************************************************/
   15.19 
   15.20 #ifndef OVR_List_h
   15.21 #define OVR_List_h
   15.22 
   15.23 #include "OVR_Types.h"
   15.24 
   15.25 namespace OVR {
   15.26 
   15.27 //-----------------------------------------------------------------------------------
   15.28 // ***** ListNode
   15.29 //
   15.30 // Base class for the elements of the intrusive linked list.
   15.31 // To store elements in the List do:
   15.32 //
   15.33 // struct MyData : ListNode<MyData>
   15.34 // {
   15.35 //     . . .
   15.36 // };
   15.37 
   15.38 template<class T>
   15.39 struct ListNode
   15.40 {
   15.41     union {
   15.42         T*    pPrev;
   15.43         void* pVoidPrev;
   15.44     };
   15.45     union {
   15.46         T*    pNext;
   15.47         void* pVoidNext;
   15.48     };
   15.49 
   15.50     void    RemoveNode()
   15.51     {
   15.52         pPrev->pNext = pNext;
   15.53         pNext->pPrev = pPrev;
   15.54     }
   15.55 
   15.56     // Removes us from the list and inserts pnew there instead.
   15.57     void    ReplaceNodeWith(T* pnew)
   15.58     {
   15.59         pPrev->pNext = pnew;
   15.60         pNext->pPrev = pnew;
   15.61         pnew->pPrev = pPrev;
   15.62         pnew->pNext = pNext;
   15.63     }
   15.64        
   15.65     // Inserts the argument linked list node after us in the list.
   15.66     void    InsertNodeAfter(T* p)
   15.67     {
   15.68         p->pPrev          = pNext->pPrev; // this
   15.69         p->pNext          = pNext;
   15.70         pNext->pPrev      = p;
   15.71         pNext             = p;
   15.72     }
   15.73     // Inserts the argument linked list node before us in the list.
   15.74     void    InsertNodeBefore(T* p)
   15.75     {
   15.76         p->pNext          = pNext->pPrev; // this
   15.77         p->pPrev          = pPrev;
   15.78         pPrev->pNext      = p;
   15.79         pPrev             = p;
   15.80     }
   15.81 
   15.82     void    Alloc_MoveTo(ListNode<T>* pdest)
   15.83     {
   15.84         pdest->pNext = pNext;
   15.85         pdest->pPrev = pPrev;
   15.86         pPrev->pNext = (T*)pdest;
   15.87         pNext->pPrev = (T*)pdest;
   15.88     }
   15.89 };
   15.90 
   15.91 
   15.92 //------------------------------------------------------------------------
   15.93 // ***** List
   15.94 //
   15.95 // Doubly linked intrusive list. 
   15.96 // The data type must be derived from ListNode.
   15.97 // 
   15.98 // Adding:   PushFront(), PushBack().
   15.99 // Removing: Remove() - the element must be in the list!
  15.100 // Moving:   BringToFront(), SendToBack() - the element must be in the list!
  15.101 //
  15.102 // Iterating:
  15.103 //    MyData* data = MyList.GetFirst();
  15.104 //    while (!MyList.IsNull(data))
  15.105 //    {
  15.106 //        . . .
  15.107 //        data = MyList.GetNext(data);
  15.108 //    }
  15.109 //
  15.110 // Removing:
  15.111 //    MyData* data = MyList.GetFirst();
  15.112 //    while (!MyList.IsNull(data))
  15.113 //    {
  15.114 //        MyData* next = MyList.GetNext(data);
  15.115 //        if (ToBeRemoved(data))
  15.116 //             MyList.Remove(data);
  15.117 //        data = next;
  15.118 //    }
  15.119 //
  15.120 
  15.121 // List<> represents a doubly-linked list of T, where each T must derive
  15.122 // from ListNode<B>. B specifies the base class that was directly
  15.123 // derived from ListNode, and is only necessary if there is an intermediate
  15.124 // inheritance chain.
  15.125 
  15.126 template<class T, class B = T> class List
  15.127 {
  15.128 public:
  15.129     typedef T ValueType;
  15.130 
  15.131     List()
  15.132     {
  15.133         Root.pNext = Root.pPrev = (ValueType*)&Root;
  15.134     }
  15.135 
  15.136     void Clear()
  15.137     {
  15.138         Root.pNext = Root.pPrev = (ValueType*)&Root;
  15.139     }
  15.140 
  15.141     const ValueType* GetFirst() const { return (const ValueType*)Root.pNext; }
  15.142     const ValueType* GetLast () const { return (const ValueType*)Root.pPrev; }
  15.143           ValueType* GetFirst()       { return (ValueType*)Root.pNext; }
  15.144           ValueType* GetLast ()       { return (ValueType*)Root.pPrev; }
  15.145 
  15.146     // Determine if list is empty (i.e.) points to itself.
  15.147     // Go through void* access to avoid issues with strict-aliasing optimizing out the
  15.148     // access after RemoveNode(), etc.
  15.149     bool IsEmpty()                   const { return Root.pVoidNext == (const T*)(const B*)&Root; }
  15.150     bool IsFirst(const ValueType* p) const { return p == Root.pNext; }
  15.151     bool IsLast (const ValueType* p) const { return p == Root.pPrev; }
  15.152     bool IsNull (const ValueType* p) const { return p == (const T*)(const B*)&Root; }
  15.153 
  15.154     inline static const ValueType* GetPrev(const ValueType* p) { return (const ValueType*)p->pPrev; }
  15.155     inline static const ValueType* GetNext(const ValueType* p) { return (const ValueType*)p->pNext; }
  15.156     inline static       ValueType* GetPrev(      ValueType* p) { return (ValueType*)p->pPrev; }
  15.157     inline static       ValueType* GetNext(      ValueType* p) { return (ValueType*)p->pNext; }
  15.158 
  15.159     void PushFront(ValueType* p)
  15.160     {
  15.161         p->pNext          =  Root.pNext;
  15.162         p->pPrev          = (ValueType*)&Root;
  15.163         Root.pNext->pPrev =  p;
  15.164         Root.pNext        =  p;
  15.165     }
  15.166 
  15.167     void PushBack(ValueType* p)
  15.168     {
  15.169         p->pPrev          =  Root.pPrev;
  15.170         p->pNext          = (ValueType*)&Root;
  15.171         Root.pPrev->pNext =  p;
  15.172         Root.pPrev        =  p;
  15.173     }
  15.174 
  15.175     static void Remove(ValueType* p)
  15.176     {
  15.177         p->pPrev->pNext = p->pNext;
  15.178         p->pNext->pPrev = p->pPrev;
  15.179     }
  15.180 
  15.181     void BringToFront(ValueType* p)
  15.182     {
  15.183         Remove(p);
  15.184         PushFront(p);
  15.185     }
  15.186 
  15.187     void SendToBack(ValueType* p)
  15.188     {
  15.189         Remove(p);
  15.190         PushBack(p);
  15.191     }
  15.192 
  15.193     // Appends the contents of the argument list to the front of this list;
  15.194     // items are removed from the argument list.
  15.195     void PushListToFront(List<T>& src)
  15.196     {
  15.197         if (!src.IsEmpty())
  15.198         {
  15.199             ValueType* pfirst = src.GetFirst();
  15.200             ValueType* plast  = src.GetLast();
  15.201             src.Clear();
  15.202             plast->pNext   = Root.pNext;
  15.203             pfirst->pPrev  = (ValueType*)&Root;
  15.204             Root.pNext->pPrev = plast;
  15.205             Root.pNext        = pfirst;
  15.206         }
  15.207     }
  15.208 
  15.209     void PushListToBack(List<T>& src)
  15.210     {
  15.211         if (!src.IsEmpty())
  15.212         {
  15.213             ValueType* pfirst = src.GetFirst();
  15.214             ValueType* plast  = src.GetLast();
  15.215             src.Clear();
  15.216             plast->pNext   = (ValueType*)&Root;
  15.217             pfirst->pPrev  = Root.pPrev;
  15.218             Root.pPrev->pNext = pfirst;
  15.219             Root.pPrev        = plast;
  15.220         }
  15.221     }
  15.222 
  15.223     // Removes all source list items after (and including) the 'pfirst' node from the 
  15.224     // source list and adds them to out list.
  15.225     void    PushFollowingListItemsToFront(List<T>& src, ValueType *pfirst)
  15.226     {
  15.227         if (pfirst != &src.Root)
  15.228         {
  15.229             ValueType *plast = src.Root.pPrev;
  15.230 
  15.231             // Remove list remainder from source.
  15.232             pfirst->pPrev->pNext = (ValueType*)&src.Root;
  15.233             src.Root.pPrev      = pfirst->pPrev;
  15.234             // Add the rest of the items to list.
  15.235             plast->pNext      = Root.pNext;
  15.236             pfirst->pPrev     = (ValueType*)&Root;
  15.237             Root.pNext->pPrev = plast;
  15.238             Root.pNext        = pfirst;
  15.239         }
  15.240     }
  15.241 
  15.242     // Removes all source list items up to but NOT including the 'pend' node from the 
  15.243     // source list and adds them to out list.
  15.244     void    PushPrecedingListItemsToFront(List<T>& src, ValueType *ptail)
  15.245     {
  15.246         if (src.GetFirst() != ptail)
  15.247         {
  15.248             ValueType *pfirst = src.Root.pNext;
  15.249             ValueType *plast  = ptail->pPrev;
  15.250 
  15.251             // Remove list remainder from source.
  15.252             ptail->pPrev      = (ValueType*)&src.Root;
  15.253             src.Root.pNext    = ptail;            
  15.254 
  15.255             // Add the rest of the items to list.
  15.256             plast->pNext      = Root.pNext;
  15.257             pfirst->pPrev     = (ValueType*)&Root;
  15.258             Root.pNext->pPrev = plast;
  15.259             Root.pNext        = pfirst;
  15.260         }
  15.261     }
  15.262 
  15.263 
  15.264     // Removes a range of source list items starting at 'pfirst' and up to, but not including 'pend',
  15.265     // and adds them to out list. Note that source items MUST already be in the list.
  15.266     void    PushListItemsToFront(ValueType *pfirst, ValueType *pend)
  15.267     {
  15.268         if (pfirst != pend)
  15.269         {
  15.270             ValueType *plast = pend->pPrev;
  15.271 
  15.272             // Remove list remainder from source.
  15.273             pfirst->pPrev->pNext = pend;
  15.274             pend->pPrev          = pfirst->pPrev;
  15.275             // Add the rest of the items to list.
  15.276             plast->pNext      = Root.pNext;
  15.277             pfirst->pPrev     = (ValueType*)&Root;
  15.278             Root.pNext->pPrev = plast;
  15.279             Root.pNext        = pfirst;
  15.280         }
  15.281     }
  15.282 
  15.283 
  15.284     void    Alloc_MoveTo(List<T>* pdest)
  15.285     {
  15.286         if (IsEmpty())
  15.287             pdest->Clear();
  15.288         else
  15.289         {
  15.290             pdest->Root.pNext = Root.pNext;
  15.291             pdest->Root.pPrev = Root.pPrev;
  15.292 
  15.293             Root.pNext->pPrev = (ValueType*)&pdest->Root;
  15.294             Root.pPrev->pNext = (ValueType*)&pdest->Root;
  15.295         }        
  15.296     }
  15.297 
  15.298 
  15.299 private:
  15.300     // Copying is prohibited
  15.301     List(const List<T>&);
  15.302     const List<T>& operator = (const List<T>&);
  15.303 
  15.304     ListNode<B> Root;
  15.305 };
  15.306 
  15.307 
  15.308 //------------------------------------------------------------------------
  15.309 // ***** FreeListElements
  15.310 //
  15.311 // Remove all elements in the list and free them in the allocator
  15.312 
  15.313 template<class List, class Allocator>
  15.314 void FreeListElements(List& list, Allocator& allocator)
  15.315 {
  15.316     typename List::ValueType* self = list.GetFirst();
  15.317     while(!list.IsNull(self))
  15.318     {
  15.319         typename List::ValueType* next = list.GetNext(self);
  15.320         allocator.Free(self);
  15.321         self = next;
  15.322     }
  15.323     list.Clear();
  15.324 }
  15.325 
  15.326 } // OVR
  15.327 
  15.328 #endif
  15.329 \ No newline at end of file
  15.330 +/************************************************************************************
  15.331 +
  15.332 +PublicHeader:   OVR
  15.333 +Filename    :   OVR_List.h
  15.334 +Content     :   Template implementation for doubly-connected linked List
  15.335 +Created     :   September 19, 2012
  15.336 +Notes       : 
  15.337 +
  15.338 +Copyright   :   Copyright 2012 Oculus VR, Inc. All Rights reserved.
  15.339 +
  15.340 +Use of this software is subject to the terms of the Oculus license
  15.341 +agreement provided at the time of installation or download, or which
  15.342 +otherwise accompanies this software in either electronic or hard copy form.
  15.343 +
  15.344 +************************************************************************************/
  15.345 +
  15.346 +#ifndef OVR_List_h
  15.347 +#define OVR_List_h
  15.348 +
  15.349 +#include "OVR_Types.h"
  15.350 +
  15.351 +namespace OVR {
  15.352 +
  15.353 +//-----------------------------------------------------------------------------------
  15.354 +// ***** ListNode
  15.355 +//
  15.356 +// Base class for the elements of the intrusive linked list.
  15.357 +// To store elements in the List do:
  15.358 +//
  15.359 +// struct MyData : ListNode<MyData>
  15.360 +// {
  15.361 +//     . . .
  15.362 +// };
  15.363 +
  15.364 +template<class T>
  15.365 +struct ListNode
  15.366 +{
  15.367 +    union {
  15.368 +        T*    pPrev;
  15.369 +        void* pVoidPrev;
  15.370 +    };
  15.371 +    union {
  15.372 +        T*    pNext;
  15.373 +        void* pVoidNext;
  15.374 +    };
  15.375 +
  15.376 +    void    RemoveNode()
  15.377 +    {
  15.378 +        pPrev->pNext = pNext;
  15.379 +        pNext->pPrev = pPrev;
  15.380 +    }
  15.381 +
  15.382 +    // Removes us from the list and inserts pnew there instead.
  15.383 +    void    ReplaceNodeWith(T* pnew)
  15.384 +    {
  15.385 +        pPrev->pNext = pnew;
  15.386 +        pNext->pPrev = pnew;
  15.387 +        pnew->pPrev = pPrev;
  15.388 +        pnew->pNext = pNext;
  15.389 +    }
  15.390 +       
  15.391 +    // Inserts the argument linked list node after us in the list.
  15.392 +    void    InsertNodeAfter(T* p)
  15.393 +    {
  15.394 +        p->pPrev          = pNext->pPrev; // this
  15.395 +        p->pNext          = pNext;
  15.396 +        pNext->pPrev      = p;
  15.397 +        pNext             = p;
  15.398 +    }
  15.399 +    // Inserts the argument linked list node before us in the list.
  15.400 +    void    InsertNodeBefore(T* p)
  15.401 +    {
  15.402 +        p->pNext          = pNext->pPrev; // this
  15.403 +        p->pPrev          = pPrev;
  15.404 +        pPrev->pNext      = p;
  15.405 +        pPrev             = p;
  15.406 +    }
  15.407 +
  15.408 +    void    Alloc_MoveTo(ListNode<T>* pdest)
  15.409 +    {
  15.410 +        pdest->pNext = pNext;
  15.411 +        pdest->pPrev = pPrev;
  15.412 +        pPrev->pNext = (T*)pdest;
  15.413 +        pNext->pPrev = (T*)pdest;
  15.414 +    }
  15.415 +};
  15.416 +
  15.417 +
  15.418 +//------------------------------------------------------------------------
  15.419 +// ***** List
  15.420 +//
  15.421 +// Doubly linked intrusive list. 
  15.422 +// The data type must be derived from ListNode.
  15.423 +// 
  15.424 +// Adding:   PushFront(), PushBack().
  15.425 +// Removing: Remove() - the element must be in the list!
  15.426 +// Moving:   BringToFront(), SendToBack() - the element must be in the list!
  15.427 +//
  15.428 +// Iterating:
  15.429 +//    MyData* data = MyList.GetFirst();
  15.430 +//    while (!MyList.IsNull(data))
  15.431 +//    {
  15.432 +//        . . .
  15.433 +//        data = MyList.GetNext(data);
  15.434 +//    }
  15.435 +//
  15.436 +// Removing:
  15.437 +//    MyData* data = MyList.GetFirst();
  15.438 +//    while (!MyList.IsNull(data))
  15.439 +//    {
  15.440 +//        MyData* next = MyList.GetNext(data);
  15.441 +//        if (ToBeRemoved(data))
  15.442 +//             MyList.Remove(data);
  15.443 +//        data = next;
  15.444 +//    }
  15.445 +//
  15.446 +
  15.447 +// List<> represents a doubly-linked list of T, where each T must derive
  15.448 +// from ListNode<B>. B specifies the base class that was directly
  15.449 +// derived from ListNode, and is only necessary if there is an intermediate
  15.450 +// inheritance chain.
  15.451 +
  15.452 +template<class T, class B = T> class List
  15.453 +{
  15.454 +public:
  15.455 +    typedef T ValueType;
  15.456 +
  15.457 +    List()
  15.458 +    {
  15.459 +        Root.pNext = Root.pPrev = (ValueType*)&Root;
  15.460 +    }
  15.461 +
  15.462 +    void Clear()
  15.463 +    {
  15.464 +        Root.pNext = Root.pPrev = (ValueType*)&Root;
  15.465 +    }
  15.466 +
  15.467 +    const ValueType* GetFirst() const { return (const ValueType*)Root.pNext; }
  15.468 +    const ValueType* GetLast () const { return (const ValueType*)Root.pPrev; }
  15.469 +          ValueType* GetFirst()       { return (ValueType*)Root.pNext; }
  15.470 +          ValueType* GetLast ()       { return (ValueType*)Root.pPrev; }
  15.471 +
  15.472 +    // Determine if list is empty (i.e.) points to itself.
  15.473 +    // Go through void* access to avoid issues with strict-aliasing optimizing out the
  15.474 +    // access after RemoveNode(), etc.
  15.475 +    bool IsEmpty()                   const { return Root.pVoidNext == (const T*)(const B*)&Root; }
  15.476 +    bool IsFirst(const ValueType* p) const { return p == Root.pNext; }
  15.477 +    bool IsLast (const ValueType* p) const { return p == Root.pPrev; }
  15.478 +    bool IsNull (const ValueType* p) const { return p == (const T*)(const B*)&Root; }
  15.479 +
  15.480 +    inline static const ValueType* GetPrev(const ValueType* p) { return (const ValueType*)p->pPrev; }
  15.481 +    inline static const ValueType* GetNext(const ValueType* p) { return (const ValueType*)p->pNext; }
  15.482 +    inline static       ValueType* GetPrev(      ValueType* p) { return (ValueType*)p->pPrev; }
  15.483 +    inline static       ValueType* GetNext(      ValueType* p) { return (ValueType*)p->pNext; }
  15.484 +
  15.485 +    void PushFront(ValueType* p)
  15.486 +    {
  15.487 +        p->pNext          =  Root.pNext;
  15.488 +        p->pPrev          = (ValueType*)&Root;
  15.489 +        Root.pNext->pPrev =  p;
  15.490 +        Root.pNext        =  p;
  15.491 +    }
  15.492 +
  15.493 +    void PushBack(ValueType* p)
  15.494 +    {
  15.495 +        p->pPrev          =  Root.pPrev;
  15.496 +        p->pNext          = (ValueType*)&Root;
  15.497 +        Root.pPrev->pNext =  p;
  15.498 +        Root.pPrev        =  p;
  15.499 +    }
  15.500 +
  15.501 +    static void Remove(ValueType* p)
  15.502 +    {
  15.503 +        p->pPrev->pNext = p->pNext;
  15.504 +        p->pNext->pPrev = p->pPrev;
  15.505 +    }
  15.506 +
  15.507 +    void BringToFront(ValueType* p)
  15.508 +    {
  15.509 +        Remove(p);
  15.510 +        PushFront(p);
  15.511 +    }
  15.512 +
  15.513 +    void SendToBack(ValueType* p)
  15.514 +    {
  15.515 +        Remove(p);
  15.516 +        PushBack(p);
  15.517 +    }
  15.518 +
  15.519 +    // Appends the contents of the argument list to the front of this list;
  15.520 +    // items are removed from the argument list.
  15.521 +    void PushListToFront(List<T>& src)
  15.522 +    {
  15.523 +        if (!src.IsEmpty())
  15.524 +        {
  15.525 +            ValueType* pfirst = src.GetFirst();
  15.526 +            ValueType* plast  = src.GetLast();
  15.527 +            src.Clear();
  15.528 +            plast->pNext   = Root.pNext;
  15.529 +            pfirst->pPrev  = (ValueType*)&Root;
  15.530 +            Root.pNext->pPrev = plast;
  15.531 +            Root.pNext        = pfirst;
  15.532 +        }
  15.533 +    }
  15.534 +
  15.535 +    void PushListToBack(List<T>& src)
  15.536 +    {
  15.537 +        if (!src.IsEmpty())
  15.538 +        {
  15.539 +            ValueType* pfirst = src.GetFirst();
  15.540 +            ValueType* plast  = src.GetLast();
  15.541 +            src.Clear();
  15.542 +            plast->pNext   = (ValueType*)&Root;
  15.543 +            pfirst->pPrev  = Root.pPrev;
  15.544 +            Root.pPrev->pNext = pfirst;
  15.545 +            Root.pPrev        = plast;
  15.546 +        }
  15.547 +    }
  15.548 +
  15.549 +    // Removes all source list items after (and including) the 'pfirst' node from the 
  15.550 +    // source list and adds them to out list.
  15.551 +    void    PushFollowingListItemsToFront(List<T>& src, ValueType *pfirst)
  15.552 +    {
  15.553 +        if (pfirst != &src.Root)
  15.554 +        {
  15.555 +            ValueType *plast = src.Root.pPrev;
  15.556 +
  15.557 +            // Remove list remainder from source.
  15.558 +            pfirst->pPrev->pNext = (ValueType*)&src.Root;
  15.559 +            src.Root.pPrev      = pfirst->pPrev;
  15.560 +            // Add the rest of the items to list.
  15.561 +            plast->pNext      = Root.pNext;
  15.562 +            pfirst->pPrev     = (ValueType*)&Root;
  15.563 +            Root.pNext->pPrev = plast;
  15.564 +            Root.pNext        = pfirst;
  15.565 +        }
  15.566 +    }
  15.567 +
  15.568 +    // Removes all source list items up to but NOT including the 'pend' node from the 
  15.569 +    // source list and adds them to out list.
  15.570 +    void    PushPrecedingListItemsToFront(List<T>& src, ValueType *ptail)
  15.571 +    {
  15.572 +        if (src.GetFirst() != ptail)
  15.573 +        {
  15.574 +            ValueType *pfirst = src.Root.pNext;
  15.575 +            ValueType *plast  = ptail->pPrev;
  15.576 +
  15.577 +            // Remove list remainder from source.
  15.578 +            ptail->pPrev      = (ValueType*)&src.Root;
  15.579 +            src.Root.pNext    = ptail;            
  15.580 +
  15.581 +            // Add the rest of the items to list.
  15.582 +            plast->pNext      = Root.pNext;
  15.583 +            pfirst->pPrev     = (ValueType*)&Root;
  15.584 +            Root.pNext->pPrev = plast;
  15.585 +            Root.pNext        = pfirst;
  15.586 +        }
  15.587 +    }
  15.588 +
  15.589 +
  15.590 +    // Removes a range of source list items starting at 'pfirst' and up to, but not including 'pend',
  15.591 +    // and adds them to out list. Note that source items MUST already be in the list.
  15.592 +    void    PushListItemsToFront(ValueType *pfirst, ValueType *pend)
  15.593 +    {
  15.594 +        if (pfirst != pend)
  15.595 +        {
  15.596 +            ValueType *plast = pend->pPrev;
  15.597 +
  15.598 +            // Remove list remainder from source.
  15.599 +            pfirst->pPrev->pNext = pend;
  15.600 +            pend->pPrev          = pfirst->pPrev;
  15.601 +            // Add the rest of the items to list.
  15.602 +            plast->pNext      = Root.pNext;
  15.603 +            pfirst->pPrev     = (ValueType*)&Root;
  15.604 +            Root.pNext->pPrev = plast;
  15.605 +            Root.pNext        = pfirst;
  15.606 +        }
  15.607 +    }
  15.608 +
  15.609 +
  15.610 +    void    Alloc_MoveTo(List<T>* pdest)
  15.611 +    {
  15.612 +        if (IsEmpty())
  15.613 +            pdest->Clear();
  15.614 +        else
  15.615 +        {
  15.616 +            pdest->Root.pNext = Root.pNext;
  15.617 +            pdest->Root.pPrev = Root.pPrev;
  15.618 +
  15.619 +            Root.pNext->pPrev = (ValueType*)&pdest->Root;
  15.620 +            Root.pPrev->pNext = (ValueType*)&pdest->Root;
  15.621 +        }        
  15.622 +    }
  15.623 +
  15.624 +
  15.625 +private:
  15.626 +    // Copying is prohibited
  15.627 +    List(const List<T>&);
  15.628 +    const List<T>& operator = (const List<T>&);
  15.629 +
  15.630 +    ListNode<B> Root;
  15.631 +};
  15.632 +
  15.633 +
  15.634 +//------------------------------------------------------------------------
  15.635 +// ***** FreeListElements
  15.636 +//
  15.637 +// Remove all elements in the list and free them in the allocator
  15.638 +
  15.639 +template<class List, class Allocator>
  15.640 +void FreeListElements(List& list, Allocator& allocator)
  15.641 +{
  15.642 +    typename List::ValueType* self = list.GetFirst();
  15.643 +    while(!list.IsNull(self))
  15.644 +    {
  15.645 +        typename List::ValueType* next = list.GetNext(self);
  15.646 +        allocator.Free(self);
  15.647 +        self = next;
  15.648 +    }
  15.649 +    list.Clear();
  15.650 +}
  15.651 +
  15.652 +} // OVR
  15.653 +
  15.654 +#endif
    16.1 --- a/libovr/Src/Kernel/OVR_Log.cpp	Sat Sep 14 17:51:03 2013 +0300
    16.2 +++ b/libovr/Src/Kernel/OVR_Log.cpp	Sun Sep 15 04:10:05 2013 +0300
    16.3 @@ -1,1 +1,173 @@
    16.4 -/************************************************************************************
    16.5 
    16.6 Filename    :   OVR_Log.cpp
    16.7 Content     :   Logging support
    16.8 Created     :   September 19, 2012
    16.9 Notes       : 
   16.10 
   16.11 Copyright   :   Copyright 2012 Oculus VR, Inc. All Rights reserved.
   16.12 
   16.13 Use of this software is subject to the terms of the Oculus license
   16.14 agreement provided at the time of installation or download, or which
   16.15 otherwise accompanies this software in either electronic or hard copy form.
   16.16 
   16.17 ************************************************************************************/
   16.18 
   16.19 #include "OVR_Log.h"
   16.20 #include "OVR_Std.h"
   16.21 #include <stdarg.h>
   16.22 #include <stdio.h>
   16.23 
   16.24 #if defined(OVR_OS_WIN32)
   16.25 #include <windows.h>
   16.26 #elif defined(OVR_OS_ANDROID)
   16.27 #include <android/log.h>
   16.28 #endif
   16.29 
   16.30 namespace OVR {
   16.31 
   16.32 // Global Log pointer.
   16.33 Log* volatile OVR_GlobalLog = 0;
   16.34 
   16.35 //-----------------------------------------------------------------------------------
   16.36 // ***** Log Implementation
   16.37 
   16.38 Log::~Log()
   16.39 {
   16.40     // Clear out global log
   16.41     if (this == OVR_GlobalLog)
   16.42     {
   16.43         // TBD: perhaps we should ASSERT if this happens before system shutdown?
   16.44         OVR_GlobalLog = 0;
   16.45     }
   16.46 }
   16.47 
   16.48 void Log::LogMessageVarg(LogMessageType messageType, const char* fmt, va_list argList)
   16.49 {
   16.50     if ((messageType & LoggingMask) == 0)
   16.51         return;
   16.52 #ifndef OVR_BUILD_DEBUG
   16.53     if (IsDebugMessage(messageType))
   16.54         return;
   16.55 #endif
   16.56 
   16.57     char buffer[MaxLogBufferMessageSize];
   16.58     FormatLog(buffer, MaxLogBufferMessageSize, messageType, fmt, argList);
   16.59     DefaultLogOutput(buffer, IsDebugMessage(messageType));
   16.60 }
   16.61 
   16.62 void OVR::Log::LogMessage(LogMessageType messageType, const char* pfmt, ...)
   16.63 {
   16.64     va_list argList;
   16.65     va_start(argList, pfmt);
   16.66     LogMessageVarg(messageType, pfmt, argList);
   16.67     va_end(argList);
   16.68 }
   16.69 
   16.70 
   16.71 void Log::FormatLog(char* buffer, unsigned bufferSize, LogMessageType messageType,
   16.72                     const char* fmt, va_list argList)
   16.73 {    
   16.74     bool addNewline = true;
   16.75 
   16.76     switch(messageType)
   16.77     {
   16.78     case Log_Error:         OVR_strcpy(buffer, bufferSize, "Error: ");     break;
   16.79     case Log_Debug:         OVR_strcpy(buffer, bufferSize, "Debug: ");     break;
   16.80     case Log_Assert:        OVR_strcpy(buffer, bufferSize, "Assert: ");    break;
   16.81     case Log_Text:       buffer[0] = 0; addNewline = false; break;
   16.82     case Log_DebugText:  buffer[0] = 0; addNewline = false; break;
   16.83     default:        
   16.84         buffer[0] = 0;
   16.85         addNewline = false;
   16.86         break;
   16.87     }
   16.88 
   16.89     UPInt prefixLength = OVR_strlen(buffer);
   16.90     char *buffer2      = buffer + prefixLength;
   16.91     OVR_vsprintf(buffer2, bufferSize - prefixLength, fmt, argList);
   16.92 
   16.93     if (addNewline)
   16.94         OVR_strcat(buffer, bufferSize, "\n");
   16.95 }
   16.96 
   16.97 
   16.98 void Log::DefaultLogOutput(const char* formattedText, bool debug)
   16.99 {
  16.100 
  16.101 #if defined(OVR_OS_WIN32)
  16.102     // Under Win32, output regular messages to console if it exists; debug window otherwise.
  16.103     static DWORD dummyMode;
  16.104     static bool  hasConsole = (GetStdHandle(STD_OUTPUT_HANDLE) != INVALID_HANDLE_VALUE) &&
  16.105                               (GetConsoleMode(GetStdHandle(STD_OUTPUT_HANDLE), &dummyMode));
  16.106 
  16.107     if (!hasConsole || debug)
  16.108     {
  16.109         ::OutputDebugStringA(formattedText);
  16.110     }
  16.111     else
  16.112     {
  16.113          fputs(formattedText, stdout);
  16.114     }    
  16.115 
  16.116 #elif defined(OVR_OS_ANDROID)
  16.117     __android_log_write(ANDROID_LOG_INFO, "OVR", formattedText);
  16.118 
  16.119 #else
  16.120     fputs(formattedText, stdout);
  16.121 
  16.122 #endif
  16.123 
  16.124     // Just in case.
  16.125     OVR_UNUSED2(formattedText, debug);
  16.126 }
  16.127 
  16.128 
  16.129 //static
  16.130 void Log::SetGlobalLog(Log *log)
  16.131 {
  16.132     OVR_GlobalLog = log;
  16.133 }
  16.134 //static
  16.135 Log* Log::GetGlobalLog()
  16.136 {
  16.137 // No global log by default?
  16.138 //    if (!OVR_GlobalLog)
  16.139 //        OVR_GlobalLog = GetDefaultLog();
  16.140     return OVR_GlobalLog;
  16.141 }
  16.142 
  16.143 //static
  16.144 Log* Log::GetDefaultLog()
  16.145 {
  16.146     // Create default log pointer statically so that it can be used
  16.147     // even during startup.
  16.148     static Log defaultLog;
  16.149     return &defaultLog;
  16.150 }
  16.151 
  16.152 
  16.153 //-----------------------------------------------------------------------------------
  16.154 // ***** Global Logging functions
  16.155 
  16.156 #define OVR_LOG_FUNCTION_IMPL(Name)  \
  16.157     void Log##Name(const char* fmt, ...) \
  16.158     {                                                                    \
  16.159         if (OVR_GlobalLog)                                               \
  16.160         {                                                                \
  16.161             va_list argList; va_start(argList, fmt);                     \
  16.162             OVR_GlobalLog->LogMessageVarg(Log_##Name, fmt, argList);  \
  16.163             va_end(argList);                                             \
  16.164         }                                                                \
  16.165     }
  16.166 
  16.167 OVR_LOG_FUNCTION_IMPL(Text)
  16.168 OVR_LOG_FUNCTION_IMPL(Error)
  16.169 
  16.170 #ifdef OVR_BUILD_DEBUG
  16.171 OVR_LOG_FUNCTION_IMPL(DebugText)
  16.172 OVR_LOG_FUNCTION_IMPL(Debug)
  16.173 OVR_LOG_FUNCTION_IMPL(Assert)
  16.174 #endif
  16.175 
  16.176 } // OVR
  16.177 \ No newline at end of file
  16.178 +/************************************************************************************
  16.179 +
  16.180 +Filename    :   OVR_Log.cpp
  16.181 +Content     :   Logging support
  16.182 +Created     :   September 19, 2012
  16.183 +Notes       : 
  16.184 +
  16.185 +Copyright   :   Copyright 2012 Oculus VR, Inc. All Rights reserved.
  16.186 +
  16.187 +Use of this software is subject to the terms of the Oculus license
  16.188 +agreement provided at the time of installation or download, or which
  16.189 +otherwise accompanies this software in either electronic or hard copy form.
  16.190 +
  16.191 +************************************************************************************/
  16.192 +
  16.193 +#include "OVR_Log.h"
  16.194 +#include "OVR_Std.h"
  16.195 +#include <stdarg.h>
  16.196 +#include <stdio.h>
  16.197 +
  16.198 +#if defined(OVR_OS_WIN32)
  16.199 +#include <windows.h>
  16.200 +#elif defined(OVR_OS_ANDROID)
  16.201 +#include <android/log.h>
  16.202 +#endif
  16.203 +
  16.204 +namespace OVR {
  16.205 +
  16.206 +// Global Log pointer.
  16.207 +Log* volatile OVR_GlobalLog = 0;
  16.208 +
  16.209 +//-----------------------------------------------------------------------------------
  16.210 +// ***** Log Implementation
  16.211 +
  16.212 +Log::~Log()
  16.213 +{
  16.214 +    // Clear out global log
  16.215 +    if (this == OVR_GlobalLog)
  16.216 +    {
  16.217 +        // TBD: perhaps we should ASSERT if this happens before system shutdown?
  16.218 +        OVR_GlobalLog = 0;
  16.219 +    }
  16.220 +}
  16.221 +
  16.222 +void Log::LogMessageVarg(LogMessageType messageType, const char* fmt, va_list argList)
  16.223 +{
  16.224 +    if ((messageType & LoggingMask) == 0)
  16.225 +        return;
  16.226 +#ifndef OVR_BUILD_DEBUG
  16.227 +    if (IsDebugMessage(messageType))
  16.228 +        return;
  16.229 +#endif
  16.230 +
  16.231 +    char buffer[MaxLogBufferMessageSize];
  16.232 +    FormatLog(buffer, MaxLogBufferMessageSize, messageType, fmt, argList);
  16.233 +    DefaultLogOutput(buffer, IsDebugMessage(messageType));
  16.234 +}
  16.235 +
  16.236 +void OVR::Log::LogMessage(LogMessageType messageType, const char* pfmt, ...)
  16.237 +{
  16.238 +    va_list argList;
  16.239 +    va_start(argList, pfmt);
  16.240 +    LogMessageVarg(messageType, pfmt, argList);
  16.241 +    va_end(argList);
  16.242 +}
  16.243 +
  16.244 +
  16.245 +void Log::FormatLog(char* buffer, unsigned bufferSize, LogMessageType messageType,
  16.246 +                    const char* fmt, va_list argList)
  16.247 +{    
  16.248 +    bool addNewline = true;
  16.249 +
  16.250 +    switch(messageType)
  16.251 +    {
  16.252 +    case Log_Error:         OVR_strcpy(buffer, bufferSize, "Error: ");     break;
  16.253 +    case Log_Debug:         OVR_strcpy(buffer, bufferSize, "Debug: ");     break;
  16.254 +    case Log_Assert:        OVR_strcpy(buffer, bufferSize, "Assert: ");    break;
  16.255 +    case Log_Text:       buffer[0] = 0; addNewline = false; break;
  16.256 +    case Log_DebugText:  buffer[0] = 0; addNewline = false; break;
  16.257 +    default:        
  16.258 +        buffer[0] = 0;
  16.259 +        addNewline = false;
  16.260 +        break;
  16.261 +    }
  16.262 +
  16.263 +    UPInt prefixLength = OVR_strlen(buffer);
  16.264 +    char *buffer2      = buffer + prefixLength;
  16.265 +    OVR_vsprintf(buffer2, bufferSize - prefixLength, fmt, argList);
  16.266 +
  16.267 +    if (addNewline)
  16.268 +        OVR_strcat(buffer, bufferSize, "\n");
  16.269 +}
  16.270 +
  16.271 +
  16.272 +void Log::DefaultLogOutput(const char* formattedText, bool debug)
  16.273 +{
  16.274 +
  16.275 +#if defined(OVR_OS_WIN32)
  16.276 +    // Under Win32, output regular messages to console if it exists; debug window otherwise.
  16.277 +    static DWORD dummyMode;
  16.278 +    static bool  hasConsole = (GetStdHandle(STD_OUTPUT_HANDLE) != INVALID_HANDLE_VALUE) &&
  16.279 +                              (GetConsoleMode(GetStdHandle(STD_OUTPUT_HANDLE), &dummyMode));
  16.280 +
  16.281 +    if (!hasConsole || debug)
  16.282 +    {
  16.283 +        ::OutputDebugStringA(formattedText);
  16.284 +    }
  16.285 +    else
  16.286 +    {
  16.287 +         fputs(formattedText, stdout);
  16.288 +    }    
  16.289 +
  16.290 +#elif defined(OVR_OS_ANDROID)
  16.291 +    __android_log_write(ANDROID_LOG_INFO, "OVR", formattedText);
  16.292 +
  16.293 +#else
  16.294 +    fputs(formattedText, stdout);
  16.295 +
  16.296 +#endif
  16.297 +
  16.298 +    // Just in case.
  16.299 +    OVR_UNUSED2(formattedText, debug);
  16.300 +}
  16.301 +
  16.302 +
  16.303 +//static
  16.304 +void Log::SetGlobalLog(Log *log)
  16.305 +{
  16.306 +    OVR_GlobalLog = log;
  16.307 +}
  16.308 +//static
  16.309 +Log* Log::GetGlobalLog()
  16.310 +{
  16.311 +// No global log by default?
  16.312 +//    if (!OVR_GlobalLog)
  16.313 +//        OVR_GlobalLog = GetDefaultLog();
  16.314 +    return OVR_GlobalLog;
  16.315 +}
  16.316 +
  16.317 +//static
  16.318 +Log* Log::GetDefaultLog()
  16.319 +{
  16.320 +    // Create default log pointer statically so that it can be used
  16.321 +    // even during startup.
  16.322 +    static Log defaultLog;
  16.323 +    return &defaultLog;
  16.324 +}
  16.325 +
  16.326 +
  16.327 +//-----------------------------------------------------------------------------------
  16.328 +// ***** Global Logging functions
  16.329 +
  16.330 +#define OVR_LOG_FUNCTION_IMPL(Name)  \
  16.331 +    void Log##Name(const char* fmt, ...) \
  16.332 +    {                                                                    \
  16.333 +        if (OVR_GlobalLog)                                               \
  16.334 +        {                                                                \
  16.335 +            va_list argList; va_start(argList, fmt);                     \
  16.336 +            OVR_GlobalLog->LogMessageVarg(Log_##Name, fmt, argList);  \
  16.337 +            va_end(argList);                                             \
  16.338 +        }                                                                \
  16.339 +    }
  16.340 +
  16.341 +OVR_LOG_FUNCTION_IMPL(Text)
  16.342 +OVR_LOG_FUNCTION_IMPL(Error)
  16.343 +
  16.344 +#ifdef OVR_BUILD_DEBUG
  16.345 +OVR_LOG_FUNCTION_IMPL(DebugText)
  16.346 +OVR_LOG_FUNCTION_IMPL(Debug)
  16.347 +OVR_LOG_FUNCTION_IMPL(Assert)
  16.348 +#endif
  16.349 +
  16.350 +} // OVR
    17.1 --- a/libovr/Src/Kernel/OVR_Log.h	Sat Sep 14 17:51:03 2013 +0300
    17.2 +++ b/libovr/Src/Kernel/OVR_Log.h	Sun Sep 15 04:10:05 2013 +0300
    17.3 @@ -1,1 +1,193 @@
    17.4 -/************************************************************************************
    17.5 
    17.6 PublicHeader:   OVR
    17.7 Filename    :   OVR_Log.h
    17.8 Content     :   Logging support
    17.9 Created     :   September 19, 2012
   17.10 Notes       : 
   17.11 
   17.12 Copyright   :   Copyright 2012 Oculus VR, Inc. All Rights reserved.
   17.13 
   17.14 Use of this software is subject to the terms of the Oculus license
   17.15 agreement provided at the time of installation or download, or which
   17.16 otherwise accompanies this software in either electronic or hard copy form.
   17.17 
   17.18 ************************************************************************************/
   17.19 
   17.20 #ifndef OVR_Log_h
   17.21 #define OVR_Log_h
   17.22 
   17.23 #include "OVR_Types.h"
   17.24 #include <stdarg.h>
   17.25 
   17.26 namespace OVR {
   17.27 
   17.28 //-----------------------------------------------------------------------------------
   17.29 // ***** Logging Constants
   17.30 
   17.31 // LogMaskConstants defined bit mask constants that describe what log messages
   17.32 // should be displayed.
   17.33 enum LogMaskConstants
   17.34 {
   17.35     LogMask_Regular = 0x100,
   17.36     LogMask_Debug   = 0x200,
   17.37     LogMask_None    = 0,
   17.38     LogMask_All     = LogMask_Regular|LogMask_Debug
   17.39 };
   17.40 
   17.41 
   17.42 // LogMessageType describes the type of the log message, controls when it is
   17.43 // displayed and what prefix/suffix is given to it. Messages are subdivided into
   17.44 // regular and debug logging types. Debug logging is only generated in debug builds.
   17.45 //
   17.46 // Log_Text         - General output text displayed without prefix or new-line.
   17.47 //                    Used in OVR libraries for general log flow messages
   17.48 //                    such as "Device Initialized".
   17.49 //
   17.50 // Log_Error        - Error message output with "Error: %s\n", intended for
   17.51 //                    application/sample-level use only, in cases where an expected
   17.52 //                    operation failed. OVR libraries should not use this internally,
   17.53 //                    reporting status codes instead.
   17.54 //
   17.55 // Log_DebugText    - Message without prefix or new lines; output in Debug build only.
   17.56 //
   17.57 // Log_Debug        - Debug-build only message, formatted with "Debug: %s\n".
   17.58 //                    Intended to comment on incorrect API usage that doesn't lead
   17.59 //                    to crashes but can be avoided with proper use.
   17.60 //                    There is no Debug Error on purpose, since real errors should
   17.61 //                    be handled by API user.
   17.62 //
   17.63 // Log_Assert      -  Debug-build only message, formatted with "Assert: %s\n".
   17.64 //                    Intended for severe unrecoverable conditions in library
   17.65 //                    source code. Generated though OVR_ASSERT_MSG(c, "Text").
   17.66 
   17.67 enum LogMessageType
   17.68 {    
   17.69     // General Logging
   17.70     Log_Text        = LogMask_Regular | 0,    
   17.71     Log_Error       = LogMask_Regular | 1, // "Error: %s\n".
   17.72     
   17.73     // Debug-only messages (not generated in release build)
   17.74     Log_DebugText   = LogMask_Debug | 0,
   17.75     Log_Debug       = LogMask_Debug | 1,   // "Debug: %s\n".
   17.76     Log_Assert      = LogMask_Debug | 2,   // "Assert: %s\n".
   17.77 };
   17.78 
   17.79 
   17.80 // LOG_VAARG_ATTRIBUTE macro, enforces printf-style fromatting for message types
   17.81 #ifdef __GNUC__
   17.82 #  define OVR_LOG_VAARG_ATTRIBUTE(a,b) __attribute__((format (printf, a, b)))
   17.83 #else
   17.84 #  define OVR_LOG_VAARG_ATTRIBUTE(a,b)
   17.85 #endif
   17.86 
   17.87 
   17.88 //-----------------------------------------------------------------------------------
   17.89 // ***** Log
   17.90 
   17.91 // Log defines a base class interface that can be implemented to catch both
   17.92 // debug and runtime messages.
   17.93 // Debug logging can be overridden by calling Log::SetGlobalLog.
   17.94 
   17.95 class Log
   17.96 {
   17.97     friend class System;
   17.98 public: 
   17.99     Log(unsigned logMask = LogMask_Debug) : LoggingMask(logMask) { }
  17.100     virtual ~Log();
  17.101 
  17.102     // Log formating buffer size used by default LogMessageVarg. Longer strings are truncated.
  17.103     enum { MaxLogBufferMessageSize = 2048 };
  17.104 
  17.105     unsigned        GetLoggingMask() const            { return LoggingMask; }
  17.106     void            SetLoggingMask(unsigned logMask)  { LoggingMask = logMask; }
  17.107 
  17.108     // This virtual function receives all the messages,
  17.109     // developers should override this function in order to do custom logging
  17.110     virtual void    LogMessageVarg(LogMessageType messageType, const char* fmt, va_list argList);
  17.111 
  17.112     // Call the logging function with specific message type, with no type filtering.
  17.113     void            LogMessage(LogMessageType messageType,
  17.114                                const char* fmt, ...) OVR_LOG_VAARG_ATTRIBUTE(3,4);
  17.115 
  17.116 
  17.117     // Helper used by LogMessageVarg to format the log message, writing the resulting
  17.118     // string into buffer. It formats text based on fmt and appends prefix/new line
  17.119     // based on LogMessageType.
  17.120     static void     FormatLog(char* buffer, unsigned bufferSize, LogMessageType messageType,
  17.121                               const char* fmt, va_list argList);
  17.122 
  17.123     // Default log output implementation used by by LogMessageVarg.
  17.124     // Debug flag may be used to re-direct output on some platforms, but doesn't
  17.125     // necessarily disable it in release builds; that is the job of the called.    
  17.126     static void     DefaultLogOutput(const char* textBuffer, bool debug);
  17.127 
  17.128     // Determines if the specified message type is for debugging only.
  17.129     static bool     IsDebugMessage(LogMessageType messageType)
  17.130     {
  17.131         return (messageType & LogMask_Debug) != 0;
  17.132     }
  17.133 
  17.134     // *** Global APIs
  17.135 
  17.136     // Global Log registration APIs.
  17.137     //  - Global log is used for OVR_DEBUG messages. Set global log to null (0)
  17.138     //    to disable all logging.
  17.139     static void     SetGlobalLog(Log *log);
  17.140     static Log*     GetGlobalLog();
  17.141 
  17.142     // Returns default log singleton instance.
  17.143     static Log*     GetDefaultLog();
  17.144 
  17.145     // Applies logMask to the default log and returns a pointer to it.
  17.146     // By default, only Debug logging is enabled, so to avoid SDK generating console
  17.147     // messages in user app (those are always disabled in release build,
  17.148     // even if the flag is set). This function is useful in System constructor.
  17.149     static Log*     ConfigureDefaultLog(unsigned logMask = LogMask_Debug)
  17.150     {
  17.151         Log* log = GetDefaultLog();
  17.152         log->SetLoggingMask(logMask);
  17.153         return log;
  17.154     }
  17.155 
  17.156 private:
  17.157     // Logging mask described by LogMaskConstants.
  17.158     unsigned    LoggingMask;
  17.159 };
  17.160 
  17.161 
  17.162 //-----------------------------------------------------------------------------------
  17.163 // ***** Global Logging Functions and Debug Macros
  17.164 
  17.165 // These functions will output text to global log with semantics described by
  17.166 // their LogMessageType.
  17.167 void LogText(const char* fmt, ...) OVR_LOG_VAARG_ATTRIBUTE(1,2);
  17.168 void LogError(const char* fmt, ...) OVR_LOG_VAARG_ATTRIBUTE(1,2);
  17.169 
  17.170 #ifdef OVR_BUILD_DEBUG
  17.171 
  17.172     // Debug build only logging.
  17.173     void LogDebugText(const char* fmt, ...) OVR_LOG_VAARG_ATTRIBUTE(1,2);
  17.174     void LogDebug(const char* fmt, ...) OVR_LOG_VAARG_ATTRIBUTE(1,2);
  17.175     void LogAssert(const char* fmt, ...) OVR_LOG_VAARG_ATTRIBUTE(1,2);
  17.176 
  17.177     // Macro to do debug logging, printf-style.
  17.178     // An extra set of set of parenthesis must be used around arguments,
  17.179     // as in: OVR_LOG_DEBUG(("Value %d", 2)).
  17.180     #define OVR_DEBUG_LOG(args)       do { OVR::LogDebug args; } while(0)
  17.181     #define OVR_DEBUG_LOG_TEXT(args)  do { OVR::LogDebugText args; } while(0)
  17.182 
  17.183     #define OVR_ASSERT_LOG(c, args)   do { if (!(c)) { OVR::LogAssert args; OVR_DEBUG_BREAK; } } while(0)
  17.184 
  17.185 #else
  17.186 
  17.187     // If not in debug build, macros do nothing.
  17.188     #define OVR_DEBUG_LOG(args)         ((void)0)
  17.189     #define OVR_DEBUG_LOG_TEXT(args)    ((void)0)
  17.190     #define OVR_ASSERT_LOG(c, args)     ((void)0)
  17.191 
  17.192 #endif
  17.193 
  17.194 } // OVR 
  17.195 
  17.196 #endif
  17.197 \ No newline at end of file
  17.198 +/************************************************************************************
  17.199 +
  17.200 +PublicHeader:   OVR
  17.201 +Filename    :   OVR_Log.h
  17.202 +Content     :   Logging support
  17.203 +Created     :   September 19, 2012
  17.204 +Notes       : 
  17.205 +
  17.206 +Copyright   :   Copyright 2012 Oculus VR, Inc. All Rights reserved.
  17.207 +
  17.208 +Use of this software is subject to the terms of the Oculus license
  17.209 +agreement provided at the time of installation or download, or which
  17.210 +otherwise accompanies this software in either electronic or hard copy form.
  17.211 +
  17.212 +************************************************************************************/
  17.213 +
  17.214 +#ifndef OVR_Log_h
  17.215 +#define OVR_Log_h
  17.216 +
  17.217 +#include "OVR_Types.h"
  17.218 +#include <stdarg.h>
  17.219 +
  17.220 +namespace OVR {
  17.221 +
  17.222 +//-----------------------------------------------------------------------------------
  17.223 +// ***** Logging Constants
  17.224 +
  17.225 +// LogMaskConstants defined bit mask constants that describe what log messages
  17.226 +// should be displayed.
  17.227 +enum LogMaskConstants
  17.228 +{
  17.229 +    LogMask_Regular = 0x100,
  17.230 +    LogMask_Debug   = 0x200,
  17.231 +    LogMask_None    = 0,
  17.232 +    LogMask_All     = LogMask_Regular|LogMask_Debug
  17.233 +};
  17.234 +
  17.235 +
  17.236 +// LogMessageType describes the type of the log message, controls when it is
  17.237 +// displayed and what prefix/suffix is given to it. Messages are subdivided into
  17.238 +// regular and debug logging types. Debug logging is only generated in debug builds.
  17.239 +//
  17.240 +// Log_Text         - General output text displayed without prefix or new-line.
  17.241 +//                    Used in OVR libraries for general log flow messages
  17.242 +//                    such as "Device Initialized".
  17.243 +//
  17.244 +// Log_Error        - Error message output with "Error: %s\n", intended for
  17.245 +//                    application/sample-level use only, in cases where an expected
  17.246 +//                    operation failed. OVR libraries should not use this internally,
  17.247 +//                    reporting status codes instead.
  17.248 +//
  17.249 +// Log_DebugText    - Message without prefix or new lines; output in Debug build only.
  17.250 +//
  17.251 +// Log_Debug        - Debug-build only message, formatted with "Debug: %s\n".
  17.252 +//                    Intended to comment on incorrect API usage that doesn't lead
  17.253 +//                    to crashes but can be avoided with proper use.
  17.254 +//                    There is no Debug Error on purpose, since real errors should
  17.255 +//                    be handled by API user.
  17.256 +//
  17.257 +// Log_Assert      -  Debug-build only message, formatted with "Assert: %s\n".
  17.258 +//                    Intended for severe unrecoverable conditions in library
  17.259 +//                    source code. Generated though OVR_ASSERT_MSG(c, "Text").
  17.260 +
  17.261 +enum LogMessageType
  17.262 +{    
  17.263 +    // General Logging
  17.264 +    Log_Text        = LogMask_Regular | 0,    
  17.265 +    Log_Error       = LogMask_Regular | 1, // "Error: %s\n".
  17.266 +    
  17.267 +    // Debug-only messages (not generated in release build)
  17.268 +    Log_DebugText   = LogMask_Debug | 0,
  17.269 +    Log_Debug       = LogMask_Debug | 1,   // "Debug: %s\n".
  17.270 +    Log_Assert      = LogMask_Debug | 2,   // "Assert: %s\n".
  17.271 +};
  17.272 +
  17.273 +
  17.274 +// LOG_VAARG_ATTRIBUTE macro, enforces printf-style fromatting for message types
  17.275 +#ifdef __GNUC__
  17.276 +#  define OVR_LOG_VAARG_ATTRIBUTE(a,b) __attribute__((format (printf, a, b)))
  17.277 +#else
  17.278 +#  define OVR_LOG_VAARG_ATTRIBUTE(a,b)
  17.279 +#endif
  17.280 +
  17.281 +
  17.282 +//-----------------------------------------------------------------------------------
  17.283 +// ***** Log
  17.284 +
  17.285 +// Log defines a base class interface that can be implemented to catch both
  17.286 +// debug and runtime messages.
  17.287 +// Debug logging can be overridden by calling Log::SetGlobalLog.
  17.288 +
  17.289 +class Log
  17.290 +{
  17.291 +    friend class System;
  17.292 +public: 
  17.293 +    Log(unsigned logMask = LogMask_Debug) : LoggingMask(logMask) { }
  17.294 +    virtual ~Log();
  17.295 +
  17.296 +    // Log formating buffer size used by default LogMessageVarg. Longer strings are truncated.
  17.297 +    enum { MaxLogBufferMessageSize = 2048 };
  17.298 +
  17.299 +    unsigned        GetLoggingMask() const            { return LoggingMask; }
  17.300 +    void            SetLoggingMask(unsigned logMask)  { LoggingMask = logMask; }
  17.301 +
  17.302 +    // This virtual function receives all the messages,
  17.303 +    // developers should override this function in order to do custom logging
  17.304 +    virtual void    LogMessageVarg(LogMessageType messageType, const char* fmt, va_list argList);
  17.305 +
  17.306 +    // Call the logging function with specific message type, with no type filtering.
  17.307 +    void            LogMessage(LogMessageType messageType,
  17.308 +                               const char* fmt, ...) OVR_LOG_VAARG_ATTRIBUTE(3,4);
  17.309 +
  17.310 +
  17.311 +    // Helper used by LogMessageVarg to format the log message, writing the resulting
  17.312 +    // string into buffer. It formats text based on fmt and appends prefix/new line
  17.313 +    // based on LogMessageType.
  17.314 +    static void     FormatLog(char* buffer, unsigned bufferSize, LogMessageType messageType,
  17.315 +                              const char* fmt, va_list argList);
  17.316 +
  17.317 +    // Default log output implementation used by by LogMessageVarg.
  17.318 +    // Debug flag may be used to re-direct output on some platforms, but doesn't
  17.319 +    // necessarily disable it in release builds; that is the job of the called.    
  17.320 +    static void     DefaultLogOutput(const char* textBuffer, bool debug);
  17.321 +
  17.322 +    // Determines if the specified message type is for debugging only.
  17.323 +    static bool     IsDebugMessage(LogMessageType messageType)
  17.324 +    {
  17.325 +        return (messageType & LogMask_Debug) != 0;
  17.326 +    }
  17.327 +
  17.328 +    // *** Global APIs
  17.329 +
  17.330 +    // Global Log registration APIs.
  17.331 +    //  - Global log is used for OVR_DEBUG messages. Set global log to null (0)
  17.332 +    //    to disable all logging.
  17.333 +    static void     SetGlobalLog(Log *log);
  17.334 +    static Log*     GetGlobalLog();
  17.335 +
  17.336 +    // Returns default log singleton instance.
  17.337 +    static Log*     GetDefaultLog();
  17.338 +
  17.339 +    // Applies logMask to the default log and returns a pointer to it.
  17.340 +    // By default, only Debug logging is enabled, so to avoid SDK generating console
  17.341 +    // messages in user app (those are always disabled in release build,
  17.342 +    // even if the flag is set). This function is useful in System constructor.
  17.343 +    static Log*     ConfigureDefaultLog(unsigned logMask = LogMask_Debug)
  17.344 +    {
  17.345 +        Log* log = GetDefaultLog();
  17.346 +        log->SetLoggingMask(logMask);
  17.347 +        return log;
  17.348 +    }
  17.349 +
  17.350 +private:
  17.351 +    // Logging mask described by LogMaskConstants.
  17.352 +    unsigned    LoggingMask;
  17.353 +};
  17.354 +
  17.355 +
  17.356 +//-----------------------------------------------------------------------------------
  17.357 +// ***** Global Logging Functions and Debug Macros
  17.358 +
  17.359 +// These functions will output text to global log with semantics described by
  17.360 +// their LogMessageType.
  17.361 +void LogText(const char* fmt, ...) OVR_LOG_VAARG_ATTRIBUTE(1,2);
  17.362 +void LogError(const char* fmt, ...) OVR_LOG_VAARG_ATTRIBUTE(1,2);
  17.363 +
  17.364 +#ifdef OVR_BUILD_DEBUG
  17.365 +
  17.366 +    // Debug build only logging.
  17.367 +    void LogDebugText(const char* fmt, ...) OVR_LOG_VAARG_ATTRIBUTE(1,2);
  17.368 +    void LogDebug(const char* fmt, ...) OVR_LOG_VAARG_ATTRIBUTE(1,2);
  17.369 +    void LogAssert(const char* fmt, ...) OVR_LOG_VAARG_ATTRIBUTE(1,2);
  17.370 +
  17.371 +    // Macro to do debug logging, printf-style.
  17.372 +    // An extra set of set of parenthesis must be used around arguments,
  17.373 +    // as in: OVR_LOG_DEBUG(("Value %d", 2)).
  17.374 +    #define OVR_DEBUG_LOG(args)       do { OVR::LogDebug args; } while(0)
  17.375 +    #define OVR_DEBUG_LOG_TEXT(args)  do { OVR::LogDebugText args; } while(0)
  17.376 +
  17.377 +    #define OVR_ASSERT_LOG(c, args)   do { if (!(c)) { OVR::LogAssert args; OVR_DEBUG_BREAK; } } while(0)
  17.378 +
  17.379 +#else
  17.380 +
  17.381 +    // If not in debug build, macros do nothing.
  17.382 +    #define OVR_DEBUG_LOG(args)         ((void)0)
  17.383 +    #define OVR_DEBUG_LOG_TEXT(args)    ((void)0)
  17.384 +    #define OVR_ASSERT_LOG(c, args)     ((void)0)
  17.385 +
  17.386 +#endif
  17.387 +
  17.388 +} // OVR 
  17.389 +
  17.390 +#endif
    18.1 --- a/libovr/Src/Kernel/OVR_Math.cpp	Sat Sep 14 17:51:03 2013 +0300
    18.2 +++ b/libovr/Src/Kernel/OVR_Math.cpp	Sun Sep 15 04:10:05 2013 +0300
    18.3 @@ -1,1 +1,153 @@
    18.4 -/************************************************************************************
    18.5 
    18.6 Filename    :   OVR_Math.h
    18.7 Content     :   Implementation of 3D primitives such as vectors, matrices.
    18.8 Created     :   September 4, 2012
    18.9 Authors     :   Andrew Reisse, Michael Antonov
   18.10 
   18.11 Copyright   :   Copyright 2012 Oculus VR, Inc. All Rights reserved.
   18.12 
   18.13 Use of this software is subject to the terms of the Oculus license
   18.14 agreement provided at the time of installation or download, or which
   18.15 otherwise accompanies this software in either electronic or hard copy form.
   18.16 
   18.17 *************************************************************************************/
   18.18 
   18.19 #include "OVR_Math.h"
   18.20 
   18.21 #include <float.h>
   18.22 
   18.23 namespace OVR {
   18.24 
   18.25 
   18.26 //-------------------------------------------------------------------------------------
   18.27 // ***** Math
   18.28 
   18.29 
   18.30 // Single-precision Math constants class.
   18.31 const float Math<float>::Pi      = 3.1415926f;
   18.32 const float Math<float>::TwoPi   = 3.1415926f * 2;
   18.33 const float Math<float>::PiOver2 = 3.1415926f / 2.0f;
   18.34 const float Math<float>::PiOver4 = 3.1415926f / 4.0f;
   18.35 const float Math<float>::E       = 2.7182818f;
   18.36 
   18.37 const float Math<float>::MaxValue = FLT_MAX;
   18.38 const float Math<float>::MinPositiveValue = FLT_MIN;
   18.39 
   18.40 const float Math<float>::RadToDegreeFactor = 360.0f / Math<float>::TwoPi;
   18.41 const float Math<float>::DegreeToRadFactor = Math<float>::TwoPi / 360.0f;
   18.42 
   18.43 const float Math<float>::Tolerance = 0.00001f;
   18.44 const float Math<float>::SingularityRadius = 0.0000001f; // Use for Gimbal lock numerical problems
   18.45 
   18.46 
   18.47 // Double-precision Math constants class.
   18.48 const double Math<double>::Pi      = 3.14159265358979;
   18.49 const double Math<double>::TwoPi   = 3.14159265358979 * 2;
   18.50 const double Math<double>::PiOver2 = 3.14159265358979 / 2.0;
   18.51 const double Math<double>::PiOver4 = 3.14159265358979 / 4.0;
   18.52 const double Math<double>::E       = 2.71828182845905;
   18.53 
   18.54 const double Math<double>::MaxValue = DBL_MAX;
   18.55 const double Math<double>::MinPositiveValue = DBL_MIN;
   18.56 
   18.57 const double Math<double>::RadToDegreeFactor = 360.0 / Math<double>::TwoPi;
   18.58 const double Math<double>::DegreeToRadFactor = Math<double>::TwoPi / 360.0;
   18.59 
   18.60 const double Math<double>::Tolerance = 0.00001;
   18.61 const double Math<double>::SingularityRadius = 0.000000000001; // Use for Gimbal lock numerical problems
   18.62 
   18.63 
   18.64 
   18.65 //-------------------------------------------------------------------------------------
   18.66 // ***** Matrix4f
   18.67 
   18.68 
   18.69 Matrix4f Matrix4f::LookAtRH(const Vector3f& eye, const Vector3f& at, const Vector3f& up)
   18.70 {
   18.71     Vector3f z = (eye - at).Normalized();  // Forward
   18.72     Vector3f x = up.Cross(z).Normalized(); // Right
   18.73     Vector3f y = z.Cross(x);
   18.74 
   18.75     Matrix4f m(x.x,  x.y,  x.z,  -(x * eye),
   18.76                y.x,  y.y,  y.z,  -(y * eye),
   18.77                z.x,  z.y,  z.z,  -(z * eye),
   18.78                0,    0,    0,    1 );
   18.79     return m;
   18.80 }
   18.81 
   18.82 Matrix4f Matrix4f::LookAtLH(const Vector3f& eye, const Vector3f& at, const Vector3f& up)
   18.83 {
   18.84     Vector3f z = (at - eye).Normalized();  // Forward
   18.85     Vector3f x = up.Cross(z).Normalized(); // Right
   18.86     Vector3f y = z.Cross(x);
   18.87 
   18.88     Matrix4f m(x.x,  x.y,  x.z,  -(x * eye),
   18.89                y.x,  y.y,  y.z,  -(y * eye),
   18.90                z.x,  z.y,  z.z,  -(z * eye),
   18.91                0,    0,    0,    1 ); 
   18.92     return m;
   18.93 }
   18.94 
   18.95 
   18.96 Matrix4f Matrix4f::PerspectiveLH(float yfov, float aspect, float znear, float zfar)
   18.97 {
   18.98     Matrix4f m;
   18.99     float    tanHalfFov = tan(yfov * 0.5f);
  18.100 
  18.101     m.M[0][0] = 1.0f / (aspect * tanHalfFov);
  18.102     m.M[1][1] = 1.0f / tanHalfFov;
  18.103     m.M[2][2] = zfar / (zfar - znear);
  18.104     m.M[3][2] = 1.0f;
  18.105     m.M[2][3] = (zfar * znear) / (znear - zfar);
  18.106     m.M[3][3] = 0.0f;
  18.107 
  18.108     // Note: Post-projection matrix result assumes Left-Handed coordinate system,
  18.109     //       with Y up, X right and Z forward. This supports positive z-buffer values.
  18.110     return m;
  18.111 }
  18.112 
  18.113 
  18.114 Matrix4f Matrix4f::PerspectiveRH(float yfov, float aspect, float znear, float zfar)
  18.115 {
  18.116     Matrix4f m;
  18.117     float    tanHalfFov = tan(yfov * 0.5f);
  18.118   
  18.119     m.M[0][0] = 1.0f / (aspect * tanHalfFov);
  18.120     m.M[1][1] = 1.0f / tanHalfFov;
  18.121     m.M[2][2] = zfar / (znear - zfar);
  18.122    // m.M[2][2] = zfar / (zfar - znear);
  18.123     m.M[3][2] = -1.0f;
  18.124     m.M[2][3] = (zfar * znear) / (znear - zfar);
  18.125     m.M[3][3] = 0.0f;
  18.126 
  18.127     // Note: Post-projection matrix result assumes Left-Handed coordinate system,    
  18.128     //       with Y up, X right and Z forward. This supports positive z-buffer values.
  18.129     // This is the case even for RHS cooridnate input.       
  18.130     return m;
  18.131 }
  18.132 
  18.133 
  18.134 /*
  18.135 OffCenterLH
  18.136 
  18.137 2*zn/(r-l)   0            0              0
  18.138 0            2*zn/(t-b)   0              0
  18.139 (l+r)/(l-r)  (t+b)/(b-t)  zf/(zf-zn)     1
  18.140 0            0            zn*zf/(zn-zf)  0
  18.141 
  18.142 */
  18.143 
  18.144 
  18.145 Matrix4f Matrix4f::Ortho2D(float w, float h)
  18.146 {
  18.147     Matrix4f m;
  18.148     m.M[0][0] = 2.0f/w;
  18.149     m.M[1][1] = -2.0f/h;
  18.150     m.M[0][3] = -1.0;
  18.151     m.M[1][3] = 1.0;
  18.152     m.M[2][2] = 0;
  18.153     return m;
  18.154 }
  18.155 
  18.156 }
  18.157 \ No newline at end of file
  18.158 +/************************************************************************************
  18.159 +
  18.160 +Filename    :   OVR_Math.h
  18.161 +Content     :   Implementation of 3D primitives such as vectors, matrices.
  18.162 +Created     :   September 4, 2012
  18.163 +Authors     :   Andrew Reisse, Michael Antonov
  18.164 +
  18.165 +Copyright   :   Copyright 2012 Oculus VR, Inc. All Rights reserved.
  18.166 +
  18.167 +Use of this software is subject to the terms of the Oculus license
  18.168 +agreement provided at the time of installation or download, or which
  18.169 +otherwise accompanies this software in either electronic or hard copy form.
  18.170 +
  18.171 +*************************************************************************************/
  18.172 +
  18.173 +#include "OVR_Math.h"
  18.174 +
  18.175 +#include <float.h>
  18.176 +
  18.177 +namespace OVR {
  18.178 +
  18.179 +
  18.180 +//-------------------------------------------------------------------------------------
  18.181 +// ***** Math
  18.182 +
  18.183 +
  18.184 +// Single-precision Math constants class.
  18.185 +const float Math<float>::Pi      = 3.1415926f;
  18.186 +const float Math<float>::TwoPi   = 3.1415926f * 2;
  18.187 +const float Math<float>::PiOver2 = 3.1415926f / 2.0f;
  18.188 +const float Math<float>::PiOver4 = 3.1415926f / 4.0f;
  18.189 +const float Math<float>::E       = 2.7182818f;
  18.190 +
  18.191 +const float Math<float>::MaxValue = FLT_MAX;
  18.192 +const float Math<float>::MinPositiveValue = FLT_MIN;
  18.193 +
  18.194 +const float Math<float>::RadToDegreeFactor = 360.0f / Math<float>::TwoPi;
  18.195 +const float Math<float>::DegreeToRadFactor = Math<float>::TwoPi / 360.0f;
  18.196 +
  18.197 +const float Math<float>::Tolerance = 0.00001f;
  18.198 +const float Math<float>::SingularityRadius = 0.0000001f; // Use for Gimbal lock numerical problems
  18.199 +
  18.200 +
  18.201 +// Double-precision Math constants class.
  18.202 +const double Math<double>::Pi      = 3.14159265358979;
  18.203 +const double Math<double>::TwoPi   = 3.14159265358979 * 2;
  18.204 +const double Math<double>::PiOver2 = 3.14159265358979 / 2.0;
  18.205 +const double Math<double>::PiOver4 = 3.14159265358979 / 4.0;
  18.206 +const double Math<double>::E       = 2.71828182845905;
  18.207 +
  18.208 +const double Math<double>::MaxValue = DBL_MAX;
  18.209 +const double Math<double>::MinPositiveValue = DBL_MIN;
  18.210 +
  18.211 +const double Math<double>::RadToDegreeFactor = 360.0 / Math<double>::TwoPi;
  18.212 +const double Math<double>::DegreeToRadFactor = Math<double>::TwoPi / 360.0;
  18.213 +
  18.214 +const double Math<double>::Tolerance = 0.00001;
  18.215 +const double Math<double>::SingularityRadius = 0.000000000001; // Use for Gimbal lock numerical problems
  18.216 +
  18.217 +
  18.218 +
  18.219 +//-------------------------------------------------------------------------------------
  18.220 +// ***** Matrix4f
  18.221 +
  18.222 +
  18.223 +Matrix4f Matrix4f::LookAtRH(const Vector3f& eye, const Vector3f& at, const Vector3f& up)
  18.224 +{
  18.225 +    Vector3f z = (eye - at).Normalized();  // Forward
  18.226 +    Vector3f x = up.Cross(z).Normalized(); // Right
  18.227 +    Vector3f y = z.Cross(x);
  18.228 +
  18.229 +    Matrix4f m(x.x,  x.y,  x.z,  -(x * eye),
  18.230 +               y.x,  y.y,  y.z,  -(y * eye),
  18.231 +               z.x,  z.y,  z.z,  -(z * eye),
  18.232 +               0,    0,    0,    1 );
  18.233 +    return m;
  18.234 +}
  18.235 +
  18.236 +Matrix4f Matrix4f::LookAtLH(const Vector3f& eye, const Vector3f& at, const Vector3f& up)
  18.237 +{
  18.238 +    Vector3f z = (at - eye).Normalized();  // Forward
  18.239 +    Vector3f x = up.Cross(z).Normalized(); // Right
  18.240 +    Vector3f y = z.Cross(x);
  18.241 +
  18.242 +    Matrix4f m(x.x,  x.y,  x.z,  -(x * eye),
  18.243 +               y.x,  y.y,  y.z,  -(y * eye),
  18.244 +               z.x,  z.y,  z.z,  -(z * eye),
  18.245 +               0,    0,    0,    1 ); 
  18.246 +    return m;
  18.247 +}
  18.248 +
  18.249 +
  18.250 +Matrix4f Matrix4f::PerspectiveLH(float yfov, float aspect, float znear, float zfar)
  18.251 +{
  18.252 +    Matrix4f m;
  18.253 +    float    tanHalfFov = tan(yfov * 0.5f);
  18.254 +
  18.255 +    m.M[0][0] = 1.0f / (aspect * tanHalfFov);
  18.256 +    m.M[1][1] = 1.0f / tanHalfFov;
  18.257 +    m.M[2][2] = zfar / (zfar - znear);
  18.258 +    m.M[3][2] = 1.0f;
  18.259 +    m.M[2][3] = (zfar * znear) / (znear - zfar);
  18.260 +    m.M[3][3] = 0.0f;
  18.261 +
  18.262 +    // Note: Post-projection matrix result assumes Left-Handed coordinate system,
  18.263 +    //       with Y up, X right and Z forward. This supports positive z-buffer values.
  18.264 +    return m;
  18.265 +}
  18.266 +
  18.267 +
  18.268 +Matrix4f Matrix4f::PerspectiveRH(float yfov, float aspect, float znear, float zfar)
  18.269 +{
  18.270 +    Matrix4f m;
  18.271 +    float    tanHalfFov = tan(yfov * 0.5f);
  18.272 +  
  18.273 +    m.M[0][0] = 1.0f / (aspect * tanHalfFov);
  18.274 +    m.M[1][1] = 1.0f / tanHalfFov;
  18.275 +    m.M[2][2] = zfar / (znear - zfar);
  18.276 +   // m.M[2][2] = zfar / (zfar - znear);
  18.277 +    m.M[3][2] = -1.0f;
  18.278 +    m.M[2][3] = (zfar * znear) / (znear - zfar);
  18.279 +    m.M[3][3] = 0.0f;
  18.280 +
  18.281 +    // Note: Post-projection matrix result assumes Left-Handed coordinate system,    
  18.282 +    //       with Y up, X right and Z forward. This supports positive z-buffer values.
  18.283 +    // This is the case even for RHS cooridnate input.       
  18.284 +    return m;
  18.285 +}
  18.286 +
  18.287 +
  18.288 +/*
  18.289 +OffCenterLH
  18.290 +
  18.291 +2*zn/(r-l)   0            0              0
  18.292 +0            2*zn/(t-b)   0              0
  18.293 +(l+r)/(l-r)  (t+b)/(b-t)  zf/(zf-zn)     1
  18.294 +0            0            zn*zf/(zn-zf)  0
  18.295 +
  18.296 +*/
  18.297 +
  18.298 +
  18.299 +Matrix4f Matrix4f::Ortho2D(float w, float h)
  18.300 +{
  18.301 +    Matrix4f m;
  18.302 +    m.M[0][0] = 2.0f/w;
  18.303 +    m.M[1][1] = -2.0f/h;
  18.304 +    m.M[0][3] = -1.0;
  18.305 +    m.M[1][3] = 1.0;
  18.306 +    m.M[2][2] = 0;
  18.307 +    return m;
  18.308 +}
  18.309 +
  18.310 +}
    19.1 --- a/libovr/Src/Kernel/OVR_Math.h	Sat Sep 14 17:51:03 2013 +0300
    19.2 +++ b/libovr/Src/Kernel/OVR_Math.h	Sun Sep 15 04:10:05 2013 +0300
    19.3 @@ -1,1 +1,1149 @@
    19.4 -/************************************************************************************
    19.5 
    19.6 PublicHeader:   OVR.h
    19.7 Filename    :   OVR_Math.h
    19.8 Content     :   Implementation of 3D primitives such as vectors, matrices.
    19.9 Created     :   September 4, 2012
   19.10 Authors     :   Andrew Reisse, Michael Antonov, Steve LaValle, Anna Yershova
   19.11 
   19.12 Copyright   :   Copyright 2012 Oculus VR, Inc. All Rights reserved.
   19.13 
   19.14 Use of this software is subject to the terms of the Oculus license
   19.15 agreement provided at the time of installation or download, or which
   19.16 otherwise accompanies this software in either electronic or hard copy form.
   19.17 
   19.18 *************************************************************************************/
   19.19 
   19.20 #ifndef OVR_Math_h
   19.21 #define OVR_Math_h
   19.22 
   19.23 #include <assert.h>
   19.24 #include <stdlib.h>
   19.25 #include <math.h>
   19.26 
   19.27 #include "OVR_Types.h"
   19.28 #include "OVR_RefCount.h"
   19.29 
   19.30 namespace OVR {
   19.31 
   19.32 //-------------------------------------------------------------------------------------
   19.33 // Constants for 3D world/axis definitions.
   19.34 
   19.35 // Definitions of axes for coordinate and rotation conversions.
   19.36 enum Axis
   19.37 {
   19.38     Axis_X = 0, Axis_Y = 1, Axis_Z = 2
   19.39 };
   19.40 
   19.41 // RotateDirection describes the rotation direction around an axis, interpreted as follows:
   19.42 //  CW  - Clockwise while looking "down" from positive axis towards the origin.
   19.43 //  CCW - Counter-clockwise while looking from the positive axis towards the origin,
   19.44 //        which is in the negative axis direction.
   19.45 //  CCW is the default for the RHS coordinate system. Oculus standard RHS coordinate
   19.46 //  system defines Y up, X right, and Z back (pointing out from the screen). In this
   19.47 //  system Rotate_CCW around Z will specifies counter-clockwise rotation in XY plane.
   19.48 enum RotateDirection
   19.49 {
   19.50     Rotate_CCW = 1,
   19.51     Rotate_CW  = -1 
   19.52 };
   19.53 
   19.54 enum HandedSystem
   19.55 {
   19.56     Handed_R = 1, Handed_L = -1
   19.57 };
   19.58 
   19.59 // AxisDirection describes which way the axis points. Used by WorldAxes.
   19.60 enum AxisDirection
   19.61 {
   19.62     Axis_Up    =  2,
   19.63     Axis_Down  = -2,
   19.64     Axis_Right =  1,
   19.65     Axis_Left  = -1,
   19.66     Axis_In    =  3,
   19.67     Axis_Out   = -3
   19.68 };
   19.69 
   19.70 struct WorldAxes
   19.71 {
   19.72     AxisDirection XAxis, YAxis, ZAxis;
   19.73 
   19.74     WorldAxes(AxisDirection x, AxisDirection y, AxisDirection z)
   19.75         : XAxis(x), YAxis(y), ZAxis(z) 
   19.76     { OVR_ASSERT(abs(x) != abs(y) && abs(y) != abs(z) && abs(z) != abs(x));}
   19.77 };
   19.78 
   19.79 
   19.80 //-------------------------------------------------------------------------------------
   19.81 // ***** Math
   19.82 
   19.83 // Math class contains constants and functions. This class is a template specialized
   19.84 // per type, with Math<float> and Math<double> being distinct.
   19.85 template<class Type>
   19.86 class Math
   19.87 {  
   19.88 };
   19.89 
   19.90 // Single-precision Math constants class.
   19.91 template<>
   19.92 class Math<float>
   19.93 {
   19.94 public:
   19.95     static const float Pi;
   19.96     static const float TwoPi;
   19.97     static const float PiOver2;
   19.98     static const float PiOver4;
   19.99     static const float E;
  19.100 
  19.101     static const float MaxValue;          // Largest positive float Value
  19.102     static const float MinPositiveValue;  // Smallest possible positive value
  19.103 
  19.104     static const float RadToDegreeFactor;
  19.105     static const float DegreeToRadFactor;
  19.106 
  19.107     static const float Tolerance; //  0.00001f;
  19.108     static const float SingularityRadius; //0.00000000001f for Gimbal lock numerical problems
  19.109 };
  19.110 
  19.111 // Double-precision Math constants class.
  19.112 template<>
  19.113 class Math<double>
  19.114 {
  19.115 public:
  19.116     static const double Pi;
  19.117     static const double TwoPi;
  19.118     static const double PiOver2;
  19.119     static const double PiOver4;
  19.120     static const double E;
  19.121 
  19.122     static const double MaxValue;          // Largest positive double Value
  19.123     static const double MinPositiveValue;  // Smallest possible positive value
  19.124 
  19.125     static const double RadToDegreeFactor;
  19.126     static const double DegreeToRadFactor;
  19.127 
  19.128     static const double Tolerance; //  0.00001f;
  19.129     static const double SingularityRadius; //0.00000000001 for Gimbal lock numerical problems
  19.130 };
  19.131 
  19.132 typedef Math<float>  Mathf;
  19.133 typedef Math<double> Mathd;
  19.134 
  19.135 // Conversion functions between degrees and radians
  19.136 template<class FT>
  19.137 FT RadToDegree(FT rads) { return rads * Math<FT>::RadToDegreeFactor; }
  19.138 template<class FT>
  19.139 FT DegreeToRad(FT rads) { return rads * Math<FT>::DegreeToRadFactor; }
  19.140 
  19.141 template<class T>
  19.142 class Quat;
  19.143 
  19.144 //-------------------------------------------------------------------------------------
  19.145 // ***** Vector2f - 2D Vector2f
  19.146 
  19.147 // Vector2f represents a 2-dimensional vector or point in space,
  19.148 // consisting of coordinates x and y,
  19.149 
  19.150 template<class T>
  19.151 class Vector2
  19.152 {
  19.153 public:
  19.154     T x, y;
  19.155 
  19.156     Vector2() : x(0), y(0) { }
  19.157     Vector2(T x_, T y_) : x(x_), y(y_) { }
  19.158     explicit Vector2(T s) : x(s), y(s) { }
  19.159 
  19.160     bool     operator== (const Vector2& b) const  { return x == b.x && y == b.y; }
  19.161     bool     operator!= (const Vector2& b) const  { return x != b.x || y != b.y; }
  19.162              
  19.163     Vector2  operator+  (const Vector2& b) const  { return Vector2(x + b.x, y + b.y); }
  19.164     Vector2& operator+= (const Vector2& b)        { x += b.x; y += b.y; return *this; }
  19.165     Vector2  operator-  (const Vector2& b) const  { return Vector2(x - b.x, y - b.y); }
  19.166     Vector2& operator-= (const Vector2& b)        { x -= b.x; y -= b.y; return *this; }
  19.167     Vector2  operator- () const                   { return Vector2(-x, -y); }
  19.168 
  19.169     // Scalar multiplication/division scales vector.
  19.170     Vector2  operator*  (T s) const               { return Vector2(x*s, y*s); }
  19.171     Vector2& operator*= (T s)                     { x *= s; y *= s; return *this; }
  19.172 
  19.173     Vector2  operator/  (T s) const               { T rcp = T(1)/s;
  19.174                                                     return Vector2(x*rcp, y*rcp); }
  19.175     Vector2& operator/= (T s)                     { T rcp = T(1)/s;
  19.176                                                     x *= rcp; y *= rcp;
  19.177                                                     return *this; }
  19.178 
  19.179     // Compare two vectors for equality with tolerance. Returns true if vectors match withing tolerance.
  19.180     bool      Compare(const Vector2&b, T tolerance = Mathf::Tolerance)
  19.181     {
  19.182         return (fabs(b.x-x) < tolerance) && (fabs(b.y-y) < tolerance);
  19.183     }
  19.184     
  19.185     // Dot product overload.
  19.186     // Used to calculate angle q between two vectors among other things,
  19.187     // as (A dot B) = |a||b|cos(q).
  19.188     T     operator*  (const Vector2& b) const    { return x*b.x + y*b.y; }
  19.189 
  19.190     // Returns the angle from this vector to b, in radians.
  19.191     T       Angle(const Vector2& b) const        { return acos((*this * b)/(Length()*b.Length())); }
  19.192 
  19.193     // Return Length of the vector squared.
  19.194     T       LengthSq() const                     { return (x * x + y * y); }
  19.195     // Return vector length.
  19.196     T       Length() const                       { return sqrt(LengthSq()); }
  19.197 
  19.198     // Returns distance between two points represented by vectors.
  19.199     T       Distance(Vector2& b) const           { return (*this - b).Length(); }
  19.200     
  19.201     // Determine if this a unit vector.
  19.202     bool    IsNormalized() const                 { return fabs(LengthSq() - T(1)) < Math<T>::Tolerance; }
  19.203     // Normalize, convention vector length to 1.    
  19.204     void    Normalize()                          { *this /= Length(); }
  19.205     // Returns normalized (unit) version of the vector without modifying itself.
  19.206     Vector2 Normalized() const                   { return *this / Length(); }
  19.207 
  19.208     // Linearly interpolates from this vector to another.
  19.209     // Factor should be between 0.0 and 1.0, with 0 giving full value to this.
  19.210     Vector2 Lerp(const Vector2& b, T f) const    { return *this*(T(1) - f) + b*f; }
  19.211 
  19.212     // Projects this vector onto the argument; in other words,
  19.213     // A.Project(B) returns projection of vector A onto B.
  19.214     Vector2 ProjectTo(const Vector2& b) const    { return b * ((*this * b) / b.LengthSq()); }
  19.215 };
  19.216 
  19.217 
  19.218 typedef Vector2<float>  Vector2f;
  19.219 typedef Vector2<double> Vector2d;
  19.220 
  19.221 //-------------------------------------------------------------------------------------
  19.222 // ***** Vector3f - 3D Vector3f
  19.223 
  19.224 // Vector3f represents a 3-dimensional vector or point in space,
  19.225 // consisting of coordinates x, y and z.
  19.226 
  19.227 template<class T>
  19.228 class Vector3
  19.229 {
  19.230 public:
  19.231     T x, y, z;
  19.232 
  19.233     Vector3() : x(0), y(0), z(0) { }
  19.234     Vector3(T x_, T y_, T z_ = 0) : x(x_), y(y_), z(z_) { }
  19.235     explicit Vector3(T s) : x(s), y(s), z(s) { }
  19.236 
  19.237     bool     operator== (const Vector3& b) const  { return x == b.x && y == b.y && z == b.z; }
  19.238     bool     operator!= (const Vector3& b) const  { return x != b.x || y != b.y || z != b.z; }
  19.239              
  19.240     Vector3  operator+  (const Vector3& b) const  { return Vector3(x + b.x, y + b.y, z + b.z); }
  19.241     Vector3& operator+= (const Vector3& b)        { x += b.x; y += b.y; z += b.z; return *this; }
  19.242     Vector3  operator-  (const Vector3& b) const  { return Vector3(x - b.x, y - b.y, z - b.z); }
  19.243     Vector3& operator-= (const Vector3& b)        { x -= b.x; y -= b.y; z -= b.z; return *this; }
  19.244     Vector3  operator- () const                   { return Vector3(-x, -y, -z); }
  19.245 
  19.246     // Scalar multiplication/division scales vector.
  19.247     Vector3  operator*  (T s) const               { return Vector3(x*s, y*s, z*s); }
  19.248     Vector3& operator*= (T s)                     { x *= s; y *= s; z *= s; return *this; }
  19.249 
  19.250     Vector3  operator/  (T s) const               { T rcp = T(1)/s;
  19.251                                                     return Vector3(x*rcp, y*rcp, z*rcp); }
  19.252     Vector3& operator/= (T s)                     { T rcp = T(1)/s;
  19.253                                                     x *= rcp; y *= rcp; z *= rcp;
  19.254                                                     return *this; }
  19.255 
  19.256     // Compare two vectors for equality with tolerance. Returns true if vectors match withing tolerance.
  19.257     bool      Compare(const Vector3&b, T tolerance = Mathf::Tolerance)
  19.258     {
  19.259         return (fabs(b.x-x) < tolerance) && (fabs(b.y-y) < tolerance) && (fabs(b.z-z) < tolerance);
  19.260     }
  19.261     
  19.262     // Dot product overload.
  19.263     // Used to calculate angle q between two vectors among other things,
  19.264     // as (A dot B) = |a||b|cos(q).
  19.265     T     operator*  (const Vector3& b) const    { return x*b.x + y*b.y + z*b.z; }
  19.266 
  19.267     // Compute cross product, which generates a normal vector.
  19.268     // Direction vector can be determined by right-hand rule: Pointing index finder in
  19.269     // direction a and middle finger in direction b, thumb will point in a.Cross(b).
  19.270     Vector3 Cross(const Vector3& b) const        { return Vector3(y*b.z - z*b.y,
  19.271                                                                   z*b.x - x*b.z,
  19.272                                                                   x*b.y - y*b.x); }
  19.273 
  19.274     // Returns the angle from this vector to b, in radians.
  19.275     T       Angle(const Vector3& b) const        { return acos((*this * b)/(Length()*b.Length())); }
  19.276 
  19.277     // Return Length of the vector squared.
  19.278     T       LengthSq() const                     { return (x * x + y * y + z * z); }
  19.279     // Return vector length.
  19.280     T       Length() const                       { return sqrt(LengthSq()); }
  19.281 
  19.282     // Returns distance between two points represented by vectors.
  19.283     T       Distance(Vector3& b) const           { return (*this - b).Length(); }
  19.284     
  19.285     // Determine if this a unit vector.
  19.286     bool    IsNormalized() const                 { return fabs(LengthSq() - T(1)) < Math<T>::Tolerance; }
  19.287     // Normalize, convention vector length to 1.    
  19.288     void    Normalize()                          { *this /= Length(); }
  19.289     // Returns normalized (unit) version of the vector without modifying itself.
  19.290     Vector3 Normalized() const                   { return *this / Length(); }
  19.291 
  19.292     // Linearly interpolates from this vector to another.
  19.293     // Factor should be between 0.0 and 1.0, with 0 giving full value to this.
  19.294     Vector3 Lerp(const Vector3& b, T f) const    { return *this*(T(1) - f) + b*f; }
  19.295 
  19.296     // Projects this vector onto the argument; in other words,
  19.297     // A.Project(B) returns projection of vector A onto B.
  19.298     Vector3 ProjectTo(const Vector3& b) const    { return b * ((*this * b) / b.LengthSq()); }
  19.299 };
  19.300 
  19.301 
  19.302 typedef Vector3<float>  Vector3f;
  19.303 typedef Vector3<double> Vector3d;
  19.304 
  19.305 
  19.306 //-------------------------------------------------------------------------------------
  19.307 // ***** Matrix4f 
  19.308 
  19.309 // Matrix4f is a 4x4 matrix used for 3d transformations and projections.
  19.310 // Translation stored in the last column.
  19.311 // The matrix is stored in row-major order in memory, meaning that values
  19.312 // of the first row are stored before the next one.
  19.313 //
  19.314 // The arrangement of the matrix is chosen to be in Right-Handed 
  19.315 // coordinate system and counterclockwise rotations when looking down
  19.316 // the axis
  19.317 //
  19.318 // Transformation Order:
  19.319 //   - Transformations are applied from right to left, so the expression
  19.320 //     M1 * M2 * M3 * V means that the vector V is transformed by M3 first,
  19.321 //     followed by M2 and M1. 
  19.322 //
  19.323 // Coordinate system: Right Handed
  19.324 //
  19.325 // Rotations: Counterclockwise when looking down the axis. All angles are in radians.
  19.326 //    
  19.327 //  | sx   01   02   tx |    // First column  (sx, 10, 20): Axis X basis vector.
  19.328 //  | 10   sy   12   ty |    // Second column (01, sy, 21): Axis Y basis vector.
  19.329 //  | 20   21   sz   tz |    // Third columnt (02, 12, sz): Axis Z basis vector.
  19.330 //  | 30   31   32   33 |
  19.331 //
  19.332 //  The basis vectors are first three columns.
  19.333 
  19.334 class Matrix4f
  19.335 {
  19.336     static Matrix4f IdentityValue;
  19.337 
  19.338 public:
  19.339     float M[4][4];    
  19.340 
  19.341     enum NoInitType { NoInit };
  19.342 
  19.343     // Construct with no memory initialization.
  19.344     Matrix4f(NoInitType) { }
  19.345 
  19.346     // By default, we construct identity matrix.
  19.347     Matrix4f()
  19.348     {
  19.349         SetIdentity();        
  19.350     }
  19.351 
  19.352     Matrix4f(float m11, float m12, float m13, float m14,
  19.353              float m21, float m22, float m23, float m24,
  19.354              float m31, float m32, float m33, float m34,
  19.355              float m41, float m42, float m43, float m44)
  19.356     {
  19.357         M[0][0] = m11; M[0][1] = m12; M[0][2] = m13; M[0][3] = m14;
  19.358         M[1][0] = m21; M[1][1] = m22; M[1][2] = m23; M[1][3] = m24;
  19.359         M[2][0] = m31; M[2][1] = m32; M[2][2] = m33; M[2][3] = m34;
  19.360         M[3][0] = m41; M[3][1] = m42; M[3][2] = m43; M[3][3] = m44;
  19.361     }
  19.362 
  19.363     Matrix4f(float m11, float m12, float m13,
  19.364              float m21, float m22, float m23,
  19.365              float m31, float m32, float m33)
  19.366     {
  19.367         M[0][0] = m11; M[0][1] = m12; M[0][2] = m13; M[0][3] = 0;
  19.368         M[1][0] = m21; M[1][1] = m22; M[1][2] = m23; M[1][3] = 0;
  19.369         M[2][0] = m31; M[2][1] = m32; M[2][2] = m33; M[2][3] = 0;
  19.370         M[3][0] = 0;   M[3][1] = 0;   M[3][2] = 0;   M[3][3] = 1;
  19.371     }
  19.372 
  19.373     static const Matrix4f& Identity()  { return IdentityValue; }
  19.374 
  19.375     void SetIdentity()
  19.376     {
  19.377         M[0][0] = M[1][1] = M[2][2] = M[3][3] = 1;
  19.378         M[0][1] = M[1][0] = M[2][3] = M[3][1] = 0;
  19.379         M[0][2] = M[1][2] = M[2][0] = M[3][2] = 0;
  19.380         M[0][3] = M[1][3] = M[2][1] = M[3][0] = 0;
  19.381     }
  19.382 
  19.383     // Multiplies two matrices into destination with minimum copying.
  19.384     static Matrix4f& Multiply(Matrix4f* d, const Matrix4f& a, const Matrix4f& b)
  19.385     {
  19.386         OVR_ASSERT((d != &a) && (d != &b));
  19.387         int i = 0;
  19.388         do {
  19.389             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];
  19.390             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];
  19.391             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];
  19.392             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];
  19.393         } while((++i) < 4);
  19.394 
  19.395         return *d;
  19.396     }
  19.397 
  19.398     Matrix4f operator* (const Matrix4f& b) const
  19.399     {
  19.400         Matrix4f result(Matrix4f::NoInit);
  19.401         Multiply(&result, *this, b);
  19.402         return result;
  19.403     }
  19.404 
  19.405     Matrix4f& operator*= (const Matrix4f& b)
  19.406     {
  19.407         return Multiply(this, Matrix4f(*this), b);
  19.408     }
  19.409 
  19.410     Matrix4f operator* (float s) const
  19.411     {
  19.412         return Matrix4f(M[0][0] * s, M[0][1] * s, M[0][2] * s, M[0][3] * s,
  19.413                         M[1][0] * s, M[1][1] * s, M[1][2] * s, M[1][3] * s,
  19.414                         M[2][0] * s, M[2][1] * s, M[2][2] * s, M[2][3] * s,
  19.415                         M[3][0] * s, M[3][1] * s, M[3][2] * s, M[3][3] * s);
  19.416     }
  19.417 
  19.418     Matrix4f& operator*= (float s)
  19.419     {
  19.420         M[0][0] *= s; M[0][1] *= s; M[0][2] *= s; M[0][3] *= s;
  19.421         M[1][0] *= s; M[1][1] *= s; M[1][2] *= s; M[1][3] *= s;
  19.422         M[2][0] *= s; M[2][1] *= s; M[2][2] *= s; M[2][3] *= s;
  19.423         M[3][0] *= s; M[3][1] *= s; M[3][2] *= s; M[3][3] *= s;
  19.424         return *this;
  19.425     }
  19.426 
  19.427     Vector3f Transform(const Vector3f& v) const
  19.428     {
  19.429         return Vector3f(M[0][0] * v.x + M[0][1] * v.y + M[0][2] * v.z + M[0][3],
  19.430                         M[1][0] * v.x + M[1][1] * v.y + M[1][2] * v.z + M[1][3],
  19.431                         M[2][0] * v.x + M[2][1] * v.y + M[2][2] * v.z + M[2][3]);
  19.432     }
  19.433 
  19.434     Matrix4f Transposed() const
  19.435     {
  19.436         return Matrix4f(M[0][0], M[1][0], M[2][0], M[3][0],
  19.437                         M[0][1], M[1][1], M[2][1], M[3][1],
  19.438                         M[0][2], M[1][2], M[2][2], M[3][2],
  19.439                         M[0][3], M[1][3], M[2][3], M[3][3]);
  19.440     }
  19.441 
  19.442     void     Transpose()
  19.443     {
  19.444         *this = Transposed();
  19.445     }
  19.446 
  19.447 
  19.448     float SubDet (const int* rows, const int* cols) const
  19.449     {
  19.450         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]])
  19.451              - 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]])
  19.452              + 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]]);
  19.453     }
  19.454 
  19.455     float Cofactor(int I, int J) const
  19.456     {
  19.457         const int indices[4][3] = {{1,2,3},{0,2,3},{0,1,3},{0,1,2}};
  19.458         return ((I+J)&1) ? -SubDet(indices[I],indices[J]) : SubDet(indices[I],indices[J]);
  19.459     }
  19.460 
  19.461     float    Determinant() const
  19.462     {
  19.463         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);
  19.464     }
  19.465 
  19.466     Matrix4f Adjugated() const
  19.467     {
  19.468         return Matrix4f(Cofactor(0,0), Cofactor(1,0), Cofactor(2,0), Cofactor(3,0), 
  19.469                         Cofactor(0,1), Cofactor(1,1), Cofactor(2,1), Cofactor(3,1), 
  19.470                         Cofactor(0,2), Cofactor(1,2), Cofactor(2,2), Cofactor(3,2),
  19.471                         Cofactor(0,3), Cofactor(1,3), Cofactor(2,3), Cofactor(3,3));
  19.472     }
  19.473 
  19.474     Matrix4f Inverted() const
  19.475     {
  19.476         float det = Determinant();
  19.477         assert(det != 0);
  19.478         return Adjugated() * (1.0f/det);
  19.479     }
  19.480 
  19.481     void Invert()
  19.482     {
  19.483         *this = Inverted();
  19.484     }
  19.485 
  19.486     //AnnaSteve:
  19.487     // a,b,c, are the YawPitchRoll angles to be returned
  19.488     // rotation a around axis A1
  19.489     // is followed by rotation b around axis A2
  19.490     // is followed by rotation c around axis A3
  19.491     // rotations are CCW or CW (D) in LH or RH coordinate system (S)
  19.492     template <Axis A1, Axis A2, Axis A3, RotateDirection D, HandedSystem S>
  19.493     void ToEulerAngles(float *a, float *b, float *c)
  19.494     {
  19.495         OVR_COMPILER_ASSERT((A1 != A2) && (A2 != A3) && (A1 != A3));
  19.496 
  19.497         float psign = -1.0f;
  19.498         if (((A1 + 1) % 3 == A2) && ((A2 + 1) % 3 == A3)) // Determine whether even permutation
  19.499         psign = 1.0f;
  19.500         
  19.501         float pm = psign*M[A1][A3];
  19.502         if (pm < -1.0f + Math<float>::SingularityRadius)
  19.503         { // South pole singularity
  19.504             *a = 0.0f;
  19.505             *b = -S*D*Math<float>::PiOver2;
  19.506             *c = S*D*atan2( psign*M[A2][A1], M[A2][A2] );
  19.507         }
  19.508         else if (pm > 1.0 - Math<float>::SingularityRadius)
  19.509         { // North pole singularity
  19.510             *a = 0.0f;
  19.511             *b = S*D*Math<float>::PiOver2;
  19.512             *c = S*D*atan2( psign*M[A2][A1], M[A2][A2] );
  19.513         }
  19.514         else
  19.515         { // Normal case (nonsingular)
  19.516             *a = S*D*atan2( -psign*M[A2][A3], M[A3][A3] );
  19.517             *b = S*D*asin(pm);
  19.518             *c = S*D*atan2( -psign*M[A1][A2], M[A1][A1] );
  19.519         }
  19.520 
  19.521         return;
  19.522     }
  19.523 
  19.524     //AnnaSteve:
  19.525     // a,b,c, are the YawPitchRoll angles to be returned
  19.526     // rotation a around axis A1
  19.527     // is followed by rotation b around axis A2
  19.528     // is followed by rotation c around axis A1
  19.529     // rotations are CCW or CW (D) in LH or RH coordinate system (S)
  19.530     template <Axis A1, Axis A2, RotateDirection D, HandedSystem S>
  19.531     void ToEulerAnglesABA(float *a, float *b, float *c)
  19.532     {        
  19.533          OVR_COMPILER_ASSERT(A1 != A2);
  19.534   
  19.535         // Determine the axis that was not supplied
  19.536         int m = 3 - A1 - A2;
  19.537 
  19.538         float psign = -1.0f;
  19.539         if ((A1 + 1) % 3 == A2) // Determine whether even permutation
  19.540             psign = 1.0f;
  19.541 
  19.542         float c2 = M[A1][A1];
  19.543         if (c2 < -1.0 + Math<float>::SingularityRadius)
  19.544         { // South pole singularity
  19.545             *a = 0.0f;
  19.546             *b = S*D*Math<float>::Pi;
  19.547             *c = S*D*atan2( -psign*M[A2][m],M[A2][A2]);
  19.548         }
  19.549         else if (c2 > 1.0 - Math<float>::SingularityRadius)
  19.550         { // North pole singularity
  19.551             *a = 0.0f;
  19.552             *b = 0.0f;
  19.553             *c = S*D*atan2( -psign*M[A2][m],M[A2][A2]);
  19.554         }
  19.555         else
  19.556         { // Normal case (nonsingular)
  19.557             *a = S*D*atan2( M[A2][A1],-psign*M[m][A1]);
  19.558             *b = S*D*acos(c2);
  19.559             *c = S*D*atan2( M[A1][A2],psign*M[A1][m]);
  19.560         }
  19.561         return;
  19.562     }
  19.563   
  19.564     // Creates a matrix that converts the vertices from one coordinate system
  19.565     // to another.
  19.566     // 
  19.567     static Matrix4f AxisConversion(const WorldAxes& to, const WorldAxes& from)
  19.568     {        
  19.569         // Holds axis values from the 'to' structure
  19.570         int toArray[3] = { to.XAxis, to.YAxis, to.ZAxis };
  19.571 
  19.572         // The inverse of the toArray
  19.573         int inv[4]; 
  19.574         inv[0] = inv[abs(to.XAxis)] = 0;
  19.575         inv[abs(to.YAxis)] = 1;
  19.576         inv[abs(to.ZAxis)] = 2;
  19.577 
  19.578         Matrix4f m(0,  0,  0, 
  19.579                    0,  0,  0,
  19.580                    0,  0,  0);
  19.581 
  19.582         // Only three values in the matrix need to be changed to 1 or -1.
  19.583         m.M[inv[abs(from.XAxis)]][0] = float(from.XAxis/toArray[inv[abs(from.XAxis)]]);
  19.584         m.M[inv[abs(from.YAxis)]][1] = float(from.YAxis/toArray[inv[abs(from.YAxis)]]);
  19.585         m.M[inv[abs(from.ZAxis)]][2] = float(from.ZAxis/toArray[inv[abs(from.ZAxis)]]);
  19.586         return m;
  19.587     } 
  19.588 
  19.589 
  19.590 
  19.591     static Matrix4f Translation(const Vector3f& v)
  19.592     {
  19.593         Matrix4f t;
  19.594         t.M[0][3] = v.x;
  19.595         t.M[1][3] = v.y;
  19.596         t.M[2][3] = v.z;
  19.597         return t;
  19.598     }
  19.599 
  19.600     static Matrix4f Translation(float x, float y, float z = 0.0f)
  19.601     {
  19.602         Matrix4f t;
  19.603         t.M[0][3] = x;
  19.604         t.M[1][3] = y;
  19.605         t.M[2][3] = z;
  19.606         return t;
  19.607     }
  19.608 
  19.609     static Matrix4f Scaling(const Vector3f& v)
  19.610     {
  19.611         Matrix4f t;
  19.612         t.M[0][0] = v.x;
  19.613         t.M[1][1] = v.y;
  19.614         t.M[2][2] = v.z;
  19.615         return t;
  19.616     }
  19.617 
  19.618     static Matrix4f Scaling(float x, float y, float z)
  19.619     {
  19.620         Matrix4f t;
  19.621         t.M[0][0] = x;
  19.622         t.M[1][1] = y;
  19.623         t.M[2][2] = z;
  19.624         return t;
  19.625     }
  19.626 
  19.627     static Matrix4f Scaling(float s)
  19.628     {
  19.629         Matrix4f t;
  19.630         t.M[0][0] = s;
  19.631         t.M[1][1] = s;
  19.632         t.M[2][2] = s;
  19.633         return t;
  19.634     }
  19.635 
  19.636   
  19.637 
  19.638     //AnnaSteve : Just for quick testing.  Not for final API.  Need to remove case.
  19.639     static Matrix4f RotationAxis(Axis A, float angle, RotateDirection d, HandedSystem s)
  19.640     {
  19.641         float sina = s * d *sin(angle);
  19.642         float cosa = cos(angle);
  19.643         
  19.644         switch(A)
  19.645         {
  19.646         case Axis_X:
  19.647             return Matrix4f(1,  0,     0, 
  19.648                             0,  cosa,  -sina,
  19.649                             0,  sina,  cosa);
  19.650         case Axis_Y:
  19.651             return Matrix4f(cosa,  0,   sina, 
  19.652                             0,     1,   0,
  19.653                             -sina, 0,   cosa);
  19.654         case Axis_Z:
  19.655             return Matrix4f(cosa,  -sina,  0, 
  19.656                             sina,  cosa,   0,
  19.657                             0,     0,      1);
  19.658         }
  19.659     }
  19.660 
  19.661 
  19.662     // Creates a rotation matrix rotating around the X axis by 'angle' radians.
  19.663     // Rotation direction is depends on the coordinate system:
  19.664     //  RHS (Oculus default): Positive angle values rotate Counter-clockwise (CCW),
  19.665     //                        while looking in the negative axis direction. This is the
  19.666     //                        same as looking down from positive axis values towards origin.
  19.667     //  LHS: Positive angle values rotate clock-wise (CW), while looking in the
  19.668     //       negative axis direction.
  19.669     static Matrix4f RotationX(float angle)
  19.670     {
  19.671         float sina = sin(angle);
  19.672         float cosa = cos(angle);
  19.673         return Matrix4f(1,  0,     0, 
  19.674                         0,  cosa,  -sina,
  19.675                         0,  sina,  cosa);
  19.676     }
  19.677 
  19.678     // Creates a rotation matrix rotating around the Y axis by 'angle' radians.
  19.679     // Rotation direction is depends on the coordinate system:
  19.680     //  RHS (Oculus default): Positive angle values rotate Counter-clockwise (CCW),
  19.681     //                        while looking in the negative axis direction. This is the
  19.682     //                        same as looking down from positive axis values towards origin.
  19.683     //  LHS: Positive angle values rotate clock-wise (CW), while looking in the
  19.684     //       negative axis direction.
  19.685     static Matrix4f RotationY(float angle)
  19.686     {
  19.687         float sina = sin(angle);
  19.688         float cosa = cos(angle);
  19.689         return Matrix4f(cosa,  0,   sina, 
  19.690                         0,     1,   0,
  19.691                         -sina, 0,   cosa);
  19.692     }
  19.693 
  19.694     // Creates a rotation matrix rotating around the Z axis by 'angle' radians.
  19.695     // Rotation direction is depends on the coordinate system:
  19.696     //  RHS (Oculus default): Positive angle values rotate Counter-clockwise (CCW),
  19.697     //                        while looking in the negative axis direction. This is the
  19.698     //                        same as looking down from positive axis values towards origin.
  19.699     //  LHS: Positive angle values rotate clock-wise (CW), while looking in the
  19.700     //       negative axis direction.
  19.701     static Matrix4f RotationZ(float angle)
  19.702     {
  19.703         float sina = sin(angle);
  19.704         float cosa = cos(angle);
  19.705         return Matrix4f(cosa,  -sina,  0, 
  19.706                         sina,  cosa,   0,
  19.707                         0,     0,      1);
  19.708     }
  19.709 
  19.710 
  19.711     // LookAtRH creates a View transformation matrix for right-handed coordinate system.
  19.712     // The resulting matrix points camera from 'eye' towards 'at' direction, with 'up'
  19.713     // specifying the up vector. The resulting matrix should be used with PerspectiveRH
  19.714     // projection.
  19.715     static Matrix4f LookAtRH(const Vector3f& eye, const Vector3f& at, const Vector3f& up);
  19.716 
  19.717     // LookAtLH creates a View transformation matrix for left-handed coordinate system.
  19.718     // The resulting matrix points camera from 'eye' towards 'at' direction, with 'up'
  19.719     // specifying the up vector. 
  19.720     static Matrix4f LookAtLH(const Vector3f& eye, const Vector3f& at, const Vector3f& up);
  19.721     
  19.722     
  19.723     // PerspectiveRH creates a right-handed perspective projection matrix that can be
  19.724     // used with the Oculus sample renderer. 
  19.725     //  yfov   - Specifies vertical field of view in radians.
  19.726     //  aspect - Screen aspect ration, which is usually width/height for square pixels.
  19.727     //           Note that xfov = yfov * aspect.
  19.728     //  znear  - Absolute value of near Z clipping clipping range.
  19.729     //  zfar   - Absolute value of far  Z clipping clipping range (larger then near).
  19.730     // Even though RHS usually looks in the direction of negative Z, positive values
  19.731     // are expected for znear and zfar.
  19.732     static Matrix4f PerspectiveRH(float yfov, float aspect, float znear, float zfar);
  19.733     
  19.734     
  19.735     // PerspectiveRH creates a left-handed perspective projection matrix that can be
  19.736     // used with the Oculus sample renderer. 
  19.737     //  yfov   - Specifies vertical field of view in radians.
  19.738     //  aspect - Screen aspect ration, which is usually width/height for square pixels.
  19.739     //           Note that xfov = yfov * aspect.
  19.740     //  znear  - Absolute value of near Z clipping clipping range.
  19.741     //  zfar   - Absolute value of far  Z clipping clipping range (larger then near).
  19.742     static Matrix4f PerspectiveLH(float yfov, float aspect, float znear, float zfar);
  19.743 
  19.744 
  19.745     static Matrix4f Ortho2D(float w, float h);
  19.746 };
  19.747 
  19.748 
  19.749 //-------------------------------------------------------------------------------------
  19.750 // ***** Quat
  19.751 
  19.752 // Quatf represents a quaternion class used for rotations.
  19.753 // 
  19.754 // Quaternion multiplications are done in right-to-left order, to match the
  19.755 // behavior of matrices.
  19.756 
  19.757 
  19.758 template<class T>
  19.759 class Quat
  19.760 {
  19.761 public:
  19.762     // w + Xi + Yj + Zk
  19.763     T x, y, z, w;    
  19.764 
  19.765     Quat() : x(0), y(0), z(0), w(1) {}
  19.766     Quat(T x_, T y_, T z_, T w_) : x(x_), y(y_), z(z_), w(w_) {}
  19.767 
  19.768 
  19.769     // Constructs rotation quaternion around the axis.
  19.770     Quat(const Vector3<T>& axis, T angle)
  19.771     {
  19.772         Vector3<T> unitAxis = axis.Normalized();
  19.773         T          sinHalfAngle = sin(angle * T(0.5));
  19.774 
  19.775         w = cos(angle * T(0.5));
  19.776         x = unitAxis.x * sinHalfAngle;
  19.777         y = unitAxis.y * sinHalfAngle;
  19.778         z = unitAxis.z * sinHalfAngle;
  19.779     }
  19.780 
  19.781     //AnnaSteve:
  19.782     void AxisAngle(Axis A, T angle, RotateDirection d, HandedSystem s)
  19.783     {
  19.784         T sinHalfAngle = s * d *sin(angle * (T)0.5);
  19.785         T v[3];
  19.786         v[0] = v[1] = v[2] = (T)0;
  19.787         v[A] = sinHalfAngle;
  19.788         //return Quat(v[0], v[1], v[2], cos(angle * (T)0.5));
  19.789         w = cos(angle * (T)0.5);
  19.790         x = v[0];
  19.791         y = v[1];
  19.792         z = v[2];
  19.793     }
  19.794 
  19.795 
  19.796     void GetAxisAngle(Vector3<T>* axis, T* angle) const
  19.797     {
  19.798         if (LengthSq() > Math<T>::Tolerance * Math<T>::Tolerance)
  19.799         {
  19.800             *axis  = Vector3<T>(x, y, z).Normalized();
  19.801             *angle = 2 * acos(w);
  19.802         }
  19.803         else
  19.804         {
  19.805             *axis = Vector3<T>(1, 0, 0);
  19.806             *angle= 0;
  19.807         }
  19.808     }
  19.809 
  19.810     bool operator== (const Quat& b) const   { return x == b.x && y == b.y && z == b.z && w == b.w; }
  19.811     bool operator!= (const Quat& b) const   { return x != b.x || y != b.y || z != b.z || w != b.w; }
  19.812 
  19.813     Quat  operator+  (const Quat& b) const  { return Quat(x + b.x, y + b.y, z + b.z, w + b.w); }
  19.814     Quat& operator+= (const Quat& b)        { w += b.w; x += b.x; y += b.y; z += b.z; return *this; }
  19.815     Quat  operator-  (const Quat& b) const  { return Quat(x - b.x, y - b.y, z - b.z, w - b.w); }
  19.816     Quat& operator-= (const Quat& b)        { w -= b.w; x -= b.x; y -= b.y; z -= b.z; return *this; }
  19.817 
  19.818     Quat  operator*  (T s) const            { return Quat(x * s, y * s, z * s, w * s); }
  19.819     Quat& operator*= (T s)                  { w *= s; x *= s; y *= s; z *= s; return *this; }
  19.820     Quat  operator/  (T s) const            { T rcp = T(1)/s; return Quat(x * rcp, y * rcp, z * rcp, w *rcp); }
  19.821     Quat& operator/= (T s)                  { T rcp = T(1)/s; w *= rcp; x *= rcp; y *= rcp; z *= rcp; return *this; }
  19.822 
  19.823     // Get Imaginary part vector
  19.824     Vector3<T> Imag() const                 { return Vector3<T>(x,y,z); }
  19.825 
  19.826     // Get quaternion length.
  19.827     T       Length() const                  { return sqrt(x * x + y * y + z * z + w * w); }
  19.828     // Get quaternion length squared.
  19.829     T       LengthSq() const                { return (x * x + y * y + z * z + w * w); }
  19.830     // Simple Eulidean distance in R^4 (not SLERP distance, but at least respects Haar measure)
  19.831     T       Distance(const Quat& q) const
  19.832     {
  19.833         T d1 = (*this - q).Length();
  19.834         T d2 = (*this + q).Length(); // Antipoldal point check
  19.835         return (d1 < d2) ? d1 : d2;
  19.836     }
  19.837     T       DistanceSq(const Quat& q) const
  19.838     {
  19.839         T d1 = (*this - q).LengthSq();
  19.840         T d2 = (*this + q).LengthSq(); // Antipoldal point check
  19.841         return (d1 < d2) ? d1 : d2;
  19.842     }
  19.843 
  19.844     // Normalize
  19.845     bool    IsNormalized() const            { return fabs(LengthSq() - 1) < Math<T>::Tolerance; }
  19.846     void    Normalize()                     { *this /= Length(); }
  19.847     Quat    Normalized() const              { return *this / Length(); }
  19.848 
  19.849     // Returns conjugate of the quaternion. Produces inverse rotation if quaternion is normalized.
  19.850     Quat    Conj() const                    { return Quat(-x, -y, -z, w); }
  19.851 
  19.852     // AnnaSteve fixed: order of quaternion multiplication
  19.853     // Quaternion multiplication. Combines quaternion rotations, performing the one on the 
  19.854     // right hand side first.
  19.855     Quat  operator* (const Quat& b) const   { return Quat(w * b.x + x * b.w + y * b.z - z * b.y,
  19.856                                                           w * b.y - x * b.z + y * b.w + z * b.x,
  19.857                                                           w * b.z + x * b.y - y * b.x + z * b.w,
  19.858                                                           w * b.w - x * b.x - y * b.y - z * b.z); }
  19.859 
  19.860     // 
  19.861     // this^p normalized; same as rotating by this p times.
  19.862     Quat PowNormalized(T p) const
  19.863     {
  19.864         Vector3<T> v;
  19.865         T          a;
  19.866         GetAxisAngle(&v, &a);
  19.867         return Quat(v, a * p);
  19.868     }
  19.869     
  19.870     // Rotate transforms vector in a manner that matches Matrix rotations (counter-clockwise,
  19.871     // assuming negative direction of the axis). Standard formula: q(t) * V * q(t)^-1. 
  19.872     Vector3<T> Rotate(const Vector3<T>& v) const
  19.873     {
  19.874         return ((*this * Quat<T>(v.x, v.y, v.z, 0)) * Inverted()).Imag();
  19.875     }
  19.876 
  19.877     
  19.878     // Inversed quaternion rotates in the opposite direction.
  19.879     Quat        Inverted() const
  19.880     {
  19.881         return Quat(-x, -y, -z, w);
  19.882     }
  19.883 
  19.884     // Sets this quaternion to the one rotates in the opposite direction.
  19.885     void        Invert()
  19.886     {
  19.887         *this = Quat(-x, -y, -z, w);
  19.888     }
  19.889     
  19.890     // Converting quaternion to matrix.
  19.891     operator Matrix4f() const
  19.892     {
  19.893         T ww = w*w;
  19.894         T xx = x*x;
  19.895         T yy = y*y;
  19.896         T zz = z*z;
  19.897 
  19.898         return Matrix4f(float(ww + xx - yy - zz),  float(T(2) * (x*y - w*z)), float(T(2) * (x*z + w*y)),
  19.899                         float(T(2) * (x*y + w*z)), float(ww - xx + yy - zz),  float(T(2) * (y*z - w*x)),
  19.900                         float(T(2) * (x*z - w*y)), float(T(2) * (y*z + w*x)), float(ww - xx - yy + zz) );
  19.901     }
  19.902 
  19.903     
  19.904     // GetEulerAngles extracts Euler angles from the quaternion, in the specified order of
  19.905     // axis rotations and the specified coordinate system. Right-handed coordinate system
  19.906     // is the default, with CCW rotations while looking in the negative axis direction.
  19.907     // Here a,b,c, are the Yaw/Pitch/Roll angles to be returned.
  19.908     // rotation a around axis A1
  19.909     // is followed by rotation b around axis A2
  19.910     // is followed by rotation c around axis A3
  19.911     // rotations are CCW or CW (D) in LH or RH coordinate system (S)
  19.912     template <Axis A1, Axis A2, Axis A3, RotateDirection D, HandedSystem S>
  19.913     void GetEulerAngles(T *a, T *b, T *c)
  19.914     {
  19.915         OVR_COMPILER_ASSERT((A1 != A2) && (A2 != A3) && (A1 != A3));
  19.916 
  19.917         T Q[3] = { x, y, z };  //Quaternion components x,y,z
  19.918 
  19.919         T ww  = w*w;
  19.920         T Q11 = Q[A1]*Q[A1];
  19.921         T Q22 = Q[A2]*Q[A2];
  19.922         T Q33 = Q[A3]*Q[A3];
  19.923 
  19.924         T psign = T(-1.0);
  19.925         // Determine whether even permutation
  19.926         if (((A1 + 1) % 3 == A2) && ((A2 + 1) % 3 == A3))
  19.927             psign = T(1.0);
  19.928         
  19.929         T s2 = psign * T(2.0) * (psign*w*Q[A2] + Q[A1]*Q[A3]);
  19.930 
  19.931         if (s2 < (T)-1.0 + Math<T>::SingularityRadius)
  19.932         { // South pole singularity
  19.933             *a = T(0.0);
  19.934             *b = -S*D*Math<T>::PiOver2;
  19.935             *c = S*D*atan2((T)2.0*(psign*Q[A1]*Q[A2] + w*Q[A3]),
  19.936 		                   ww + Q22 - Q11 - Q33 );
  19.937         }
  19.938         else if (s2 > (T)1.0 - Math<T>::SingularityRadius)
  19.939         {  // North pole singularity
  19.940             *a = (T)0.0;
  19.941             *b = S*D*Math<T>::PiOver2;
  19.942             *c = S*D*atan2((T)2.0*(psign*Q[A1]*Q[A2] + w*Q[A3]),
  19.943 		                   ww + Q22 - Q11 - Q33);
  19.944         }
  19.945         else
  19.946         {
  19.947             *a = -S*D*atan2((T)-2.0*(w*Q[A1] - psign*Q[A2]*Q[A3]),
  19.948 		                    ww + Q33 - Q11 - Q22);
  19.949             *b = S*D*asin(s2);
  19.950             *c = S*D*atan2((T)2.0*(w*Q[A3] - psign*Q[A1]*Q[A2]),
  19.951 		                   ww + Q11 - Q22 - Q33);
  19.952         }      
  19.953         return;
  19.954     }
  19.955 
  19.956     template <Axis A1, Axis A2, Axis A3, RotateDirection D>
  19.957     void GetEulerAngles(T *a, T *b, T *c)
  19.958     { GetEulerAngles<A1, A2, A3, D, Handed_R>(a, b, c); }
  19.959 
  19.960     template <Axis A1, Axis A2, Axis A3>
  19.961     void GetEulerAngles(T *a, T *b, T *c)
  19.962     { GetEulerAngles<A1, A2, A3, Rotate_CCW, Handed_R>(a, b, c); }
  19.963 
  19.964 
  19.965     // GetEulerAnglesABA extracts Euler angles from the quaternion, in the specified order of
  19.966     // axis rotations and the specified coordinate system. Right-handed coordinate system
  19.967     // is the default, with CCW rotations while looking in the negative axis direction.
  19.968     // Here a,b,c, are the Yaw/Pitch/Roll angles to be returned.
  19.969     // rotation a around axis A1
  19.970     // is followed by rotation b around axis A2
  19.971     // is followed by rotation c around axis A1
  19.972     // Rotations are CCW or CW (D) in LH or RH coordinate system (S)
  19.973     template <Axis A1, Axis A2, RotateDirection D, HandedSystem S>
  19.974     void GetEulerAnglesABA(T *a, T *b, T *c)
  19.975     {
  19.976         OVR_COMPILER_ASSERT(A1 != A2);
  19.977 
  19.978         T Q[3] = {x, y, z}; // Quaternion components
  19.979 
  19.980         // Determine the missing axis that was not supplied
  19.981         int m = 3 - A1 - A2;
  19.982 
  19.983         T ww = w*w;
  19.984         T Q11 = Q[A1]*Q[A1];
  19.985         T Q22 = Q[A2]*Q[A2];
  19.986         T Qmm = Q[m]*Q[m];
  19.987 
  19.988         T psign = T(-1.0);
  19.989         if ((A1 + 1) % 3 == A2) // Determine whether even permutation
  19.990         {
  19.991             psign = (T)1.0;
  19.992         }
  19.993 
  19.994         T c2 = ww + Q11 - Q22 - Qmm;
  19.995         if (c2 < (T)-1.0 + Math<T>::SingularityRadius)
  19.996         { // South pole singularity
  19.997             *a = (T)0.0;
  19.998             *b = S*D*Math<T>::Pi;
  19.999             *c = S*D*atan2( (T)2.0*(w*Q[A1] - psign*Q[A2]*Q[m]),
 19.1000 		                    ww + Q22 - Q11 - Qmm);
 19.1001         }
 19.1002         else if (c2 > (T)1.0 - Math<T>::SingularityRadius)
 19.1003         {  // North pole singularity
 19.1004             *a = (T)0.0;
 19.1005             *b = (T)0.0;
 19.1006             *c = S*D*atan2( (T)2.0*(w*Q[A1] - psign*Q[A2]*Q[m]),
 19.1007 		                   ww + Q22 - Q11 - Qmm);
 19.1008         }
 19.1009         else
 19.1010         {
 19.1011             *a = S*D*atan2( psign*w*Q[m] + Q[A1]*Q[A2],
 19.1012 		                   w*Q[A2] -psign*Q[A1]*Q[m]);
 19.1013             *b = S*D*acos(c2);
 19.1014             *c = S*D*atan2( -psign*w*Q[m] + Q[A1]*Q[A2],
 19.1015 		                   w*Q[A2] + psign*Q[A1]*Q[m]);
 19.1016         }
 19.1017         return;
 19.1018     }
 19.1019 };
 19.1020 
 19.1021 
 19.1022 typedef Quat<float>  Quatf;
 19.1023 typedef Quat<double> Quatd;
 19.1024 
 19.1025 
 19.1026 
 19.1027 //-------------------------------------------------------------------------------------
 19.1028 // ***** Angle
 19.1029 
 19.1030 // Cleanly representing the algebra of 2D rotations.
 19.1031 // The operations maintain the angle between -Pi and Pi, the same range as atan2.
 19.1032 // 
 19.1033 
 19.1034 template<class T>
 19.1035 class Angle
 19.1036 {
 19.1037 public:
 19.1038 	enum AngularUnits
 19.1039 	{
 19.1040 		Radians = 0,
 19.1041 		Degrees = 1
 19.1042 	};
 19.1043 
 19.1044     Angle() : a(0) {}
 19.1045     
 19.1046 	// Fix the range to be between -Pi and Pi
 19.1047 	Angle(T a_, AngularUnits u = Radians) : a((u == Radians) ? a_ : a_*Math<T>::DegreeToRadFactor) { FixRange(); }
 19.1048 
 19.1049 	T    Get(AngularUnits u = Radians) const       { return (u == Radians) ? a : a*Math<T>::RadToDegreeFactor; }
 19.1050 	void Set(const T& x, AngularUnits u = Radians) { a = (u == Radians) ? x : x*Math<T>::DegreeToRadFactor; FixRange(); }
 19.1051 	int Sign() const                               { if (a == 0) return 0; else return (a > 0) ? 1 : -1; }
 19.1052 	T   Abs() const                                { return (a > 0) ? a : -a; }
 19.1053 
 19.1054     bool operator== (const Angle& b) const    { return a == b.a; }
 19.1055     bool operator!= (const Angle& b) const    { return a != b.a; }
 19.1056 //	bool operator<  (const Angle& b) const    { return a < a.b; } 
 19.1057 //	bool operator>  (const Angle& b) const    { return a > a.b; } 
 19.1058 //	bool operator<= (const Angle& b) const    { return a <= a.b; } 
 19.1059 //	bool operator>= (const Angle& b) const    { return a >= a.b; } 
 19.1060 //	bool operator= (const T& x)               { a = x; FixRange(); }
 19.1061 
 19.1062 	// These operations assume a is already between -Pi and Pi.
 19.1063     Angle  operator+  (const Angle& b) const  { return Angle(a + b.a); }
 19.1064 	Angle  operator+  (const T& x) const      { return Angle(a + x); }
 19.1065 	Angle& operator+= (const Angle& b)        { a = a + b.a; FastFixRange(); return *this; }
 19.1066 	Angle& operator+= (const T& x)            { a = a + x; FixRange(); return *this; }
 19.1067 	Angle  operator-  (const Angle& b) const  { return Angle(a - b.a); }
 19.1068 	Angle  operator-  (const T& x) const      { return Angle(a - x); }
 19.1069 	Angle& operator-= (const Angle& b)        { a = a - b.a; FastFixRange(); return *this; }
 19.1070 	Angle& operator-= (const T& x)            { a = a - x; FixRange(); return *this; }
 19.1071 	
 19.1072 	T   Distance(const Angle& b)              { T c = fabs(a - b.a); return (c <= Math<T>::Pi) ? c : Math<T>::TwoPi - c; }
 19.1073 
 19.1074 private:
 19.1075 
 19.1076 	// The stored angle, which should be maintained between -Pi and Pi
 19.1077 	T a;
 19.1078 
 19.1079 	// Fixes the angle range to [-Pi,Pi], but assumes no more than 2Pi away on either side 
 19.1080 	inline void FastFixRange()
 19.1081 	{
 19.1082 		if (a < -Math<T>::Pi)
 19.1083 			a += Math<T>::TwoPi;
 19.1084 		else if (a > Math<T>::Pi)
 19.1085 			a -= Math<T>::TwoPi;
 19.1086 	}
 19.1087 
 19.1088 	// Fixes the angle range to [-Pi,Pi] for any given range, but slower then the fast method
 19.1089 	inline void FixRange()
 19.1090 	{
 19.1091 		a = fmod(a,Math<T>::TwoPi);
 19.1092 		if (a < -Math<T>::Pi)
 19.1093 			a += Math<T>::TwoPi;
 19.1094 		else if (a > Math<T>::Pi)
 19.1095 			a -= Math<T>::TwoPi;
 19.1096 	}
 19.1097 };
 19.1098 
 19.1099 
 19.1100 typedef Angle<float>  Anglef;
 19.1101 typedef Angle<double> Angled;
 19.1102 
 19.1103 
 19.1104 //-------------------------------------------------------------------------------------
 19.1105 // ***** Plane
 19.1106 
 19.1107 // Consists of a normal vector and distance from the origin where the plane is located.
 19.1108 
 19.1109 template<class T>
 19.1110 class Plane : public RefCountBase<Plane<T> >
 19.1111 {
 19.1112 public:
 19.1113     Vector3<T> N;
 19.1114     T          D;
 19.1115 
 19.1116     Plane() : D(0) {}
 19.1117 
 19.1118     // Normals must already be normalized
 19.1119     Plane(const Vector3<T>& n, T d) : N(n), D(d) {}
 19.1120     Plane(T x, T y, T z, T d) : N(x,y,z), D(d) {}
 19.1121 
 19.1122     // construct from a point on the plane and the normal
 19.1123     Plane(const Vector3<T>& p, const Vector3<T>& n) : N(n), D(-(p * n)) {}
 19.1124 
 19.1125     // Find the point to plane distance. The sign indicates what side of the plane the point is on (0 = point on plane).
 19.1126     T TestSide(const Vector3<T>& p) const
 19.1127     {
 19.1128         return (N * p) + D;
 19.1129     }
 19.1130 
 19.1131     Plane<T> Flipped() const
 19.1132     {
 19.1133         return Plane(-N, -D);
 19.1134     }
 19.1135 
 19.1136     void Flip()
 19.1137     {
 19.1138         N = -N;
 19.1139         D = -D;
 19.1140     }
 19.1141 
 19.1142 	bool operator==(const Plane<T>& rhs) const
 19.1143 	{
 19.1144 		return (this->D == rhs.D && this->N == rhs.N);
 19.1145 	}
 19.1146 };
 19.1147 
 19.1148 typedef Plane<float> Planef;
 19.1149 
 19.1150 }
 19.1151 
 19.1152 #endif
 19.1153 \ No newline at end of file
 19.1154 +/************************************************************************************
 19.1155 +
 19.1156 +PublicHeader:   OVR.h
 19.1157 +Filename    :   OVR_Math.h
 19.1158 +Content     :   Implementation of 3D primitives such as vectors, matrices.
 19.1159 +Created     :   September 4, 2012
 19.1160 +Authors     :   Andrew Reisse, Michael Antonov, Steve LaValle, Anna Yershova
 19.1161 +
 19.1162 +Copyright   :   Copyright 2012 Oculus VR, Inc. All Rights reserved.
 19.1163 +
 19.1164 +Use of this software is subject to the terms of the Oculus license
 19.1165 +agreement provided at the time of installation or download, or which
 19.1166 +otherwise accompanies this software in either electronic or hard copy form.
 19.1167 +
 19.1168 +*************************************************************************************/
 19.1169 +
 19.1170 +#ifndef OVR_Math_h
 19.1171 +#define OVR_Math_h
 19.1172 +
 19.1173 +#include <assert.h>
 19.1174 +#include <stdlib.h>
 19.1175 +#include <math.h>
 19.1176 +
 19.1177 +#include "OVR_Types.h"
 19.1178 +#include "OVR_RefCount.h"
 19.1179 +
 19.1180 +namespace OVR {
 19.1181 +
 19.1182 +//-------------------------------------------------------------------------------------
 19.1183 +// Constants for 3D world/axis definitions.
 19.1184 +
 19.1185 +// Definitions of axes for coordinate and rotation conversions.
 19.1186 +enum Axis
 19.1187 +{
 19.1188 +    Axis_X = 0, Axis_Y = 1, Axis_Z = 2
 19.1189 +};
 19.1190 +
 19.1191 +// RotateDirection describes the rotation direction around an axis, interpreted as follows:
 19.1192 +//  CW  - Clockwise while looking "down" from positive axis towards the origin.
 19.1193 +//  CCW - Counter-clockwise while looking from the positive axis towards the origin,
 19.1194 +//        which is in the negative axis direction.
 19.1195 +//  CCW is the default for the RHS coordinate system. Oculus standard RHS coordinate
 19.1196 +//  system defines Y up, X right, and Z back (pointing out from the screen). In this
 19.1197 +//  system Rotate_CCW around Z will specifies counter-clockwise rotation in XY plane.
 19.1198 +enum RotateDirection
 19.1199 +{
 19.1200 +    Rotate_CCW = 1,
 19.1201 +    Rotate_CW  = -1 
 19.1202 +};
 19.1203 +
 19.1204 +enum HandedSystem
 19.1205 +{
 19.1206 +    Handed_R = 1, Handed_L = -1
 19.1207 +};
 19.1208 +
 19.1209 +// AxisDirection describes which way the axis points. Used by WorldAxes.
 19.1210 +enum AxisDirection
 19.1211 +{
 19.1212 +    Axis_Up    =  2,
 19.1213 +    Axis_Down  = -2,
 19.1214 +    Axis_Right =  1,
 19.1215 +    Axis_Left  = -1,
 19.1216 +    Axis_In    =  3,
 19.1217 +    Axis_Out   = -3
 19.1218 +};
 19.1219 +
 19.1220 +struct WorldAxes
 19.1221 +{
 19.1222 +    AxisDirection XAxis, YAxis, ZAxis;
 19.1223 +
 19.1224 +    WorldAxes(AxisDirection x, AxisDirection y, AxisDirection z)
 19.1225 +        : XAxis(x), YAxis(y), ZAxis(z) 
 19.1226 +    { OVR_ASSERT(abs(x) != abs(y) && abs(y) != abs(z) && abs(z) != abs(x));}
 19.1227 +};
 19.1228 +
 19.1229 +
 19.1230 +//-------------------------------------------------------------------------------------
 19.1231 +// ***** Math
 19.1232 +
 19.1233 +// Math class contains constants and functions. This class is a template specialized
 19.1234 +// per type, with Math<float> and Math<double> being distinct.
 19.1235 +template<class Type>
 19.1236 +class Math
 19.1237 +{  
 19.1238 +};
 19.1239 +
 19.1240 +// Single-precision Math constants class.
 19.1241 +template<>
 19.1242 +class Math<float>
 19.1243 +{
 19.1244 +public:
 19.1245 +    static const float Pi;
 19.1246 +    static const float TwoPi;
 19.1247 +    static const float PiOver2;
 19.1248 +    static const float PiOver4;
 19.1249 +    static const float E;
 19.1250 +
 19.1251 +    static const float MaxValue;          // Largest positive float Value
 19.1252 +    static const float MinPositiveValue;  // Smallest possible positive value
 19.1253 +
 19.1254 +    static const float RadToDegreeFactor;
 19.1255 +    static const float DegreeToRadFactor;
 19.1256 +
 19.1257 +    static const float Tolerance; //  0.00001f;
 19.1258 +    static const float SingularityRadius; //0.00000000001f for Gimbal lock numerical problems
 19.1259 +};
 19.1260 +
 19.1261 +// Double-precision Math constants class.
 19.1262 +template<>
 19.1263 +class Math<double>
 19.1264 +{
 19.1265 +public:
 19.1266 +    static const double Pi;
 19.1267 +    static const double TwoPi;
 19.1268 +    static const double PiOver2;
 19.1269 +    static const double PiOver4;
 19.1270 +    static const double E;
 19.1271 +
 19.1272 +    static const double MaxValue;          // Largest positive double Value
 19.1273 +    static const double MinPositiveValue;  // Smallest possible positive value
 19.1274 +
 19.1275 +    static const double RadToDegreeFactor;
 19.1276 +    static const double DegreeToRadFactor;
 19.1277 +
 19.1278 +    static const double Tolerance; //  0.00001f;
 19.1279 +    static const double SingularityRadius; //0.00000000001 for Gimbal lock numerical problems
 19.1280 +};
 19.1281 +
 19.1282 +typedef Math<float>  Mathf;
 19.1283 +typedef Math<double> Mathd;
 19.1284 +
 19.1285 +// Conversion functions between degrees and radians
 19.1286 +template<class FT>
 19.1287 +FT RadToDegree(FT rads) { return rads * Math<FT>::RadToDegreeFactor; }
 19.1288 +template<class FT>
 19.1289 +FT DegreeToRad(FT rads) { return rads * Math<FT>::DegreeToRadFactor; }
 19.1290 +
 19.1291 +template<class T>
 19.1292 +class Quat;
 19.1293 +
 19.1294 +//-------------------------------------------------------------------------------------
 19.1295 +// ***** Vector2f - 2D Vector2f
 19.1296 +
 19.1297 +// Vector2f represents a 2-dimensional vector or point in space,
 19.1298 +// consisting of coordinates x and y,
 19.1299 +
 19.1300 +template<class T>
 19.1301 +class Vector2
 19.1302 +{
 19.1303 +public:
 19.1304 +    T x, y;
 19.1305 +
 19.1306 +    Vector2() : x(0), y(0) { }
 19.1307 +    Vector2(T x_, T y_) : x(x_), y(y_) { }
 19.1308 +    explicit Vector2(T s) : x(s), y(s) { }
 19.1309 +
 19.1310 +    bool     operator== (const Vector2& b) const  { return x == b.x && y == b.y; }
 19.1311 +    bool     operator!= (const Vector2& b) const  { return x != b.x || y != b.y; }
 19.1312 +             
 19.1313 +    Vector2  operator+  (const Vector2& b) const  { return Vector2(x + b.x, y + b.y); }
 19.1314 +    Vector2& operator+= (const Vector2& b)        { x += b.x; y += b.y; return *this; }
 19.1315 +    Vector2  operator-  (const Vector2& b) const  { return Vector2(x - b.x, y - b.y); }
 19.1316 +    Vector2& operator-= (const Vector2& b)        { x -= b.x; y -= b.y; return *this; }
 19.1317 +    Vector2  operator- () const                   { return Vector2(-x, -y); }
 19.1318 +
 19.1319 +    // Scalar multiplication/division scales vector.
 19.1320 +    Vector2  operator*  (T s) const               { return Vector2(x*s, y*s); }
 19.1321 +    Vector2& operator*= (T s)                     { x *= s; y *= s; return *this; }
 19.1322 +
 19.1323 +    Vector2  operator/  (T s) const               { T rcp = T(1)/s;
 19.1324 +                                                    return Vector2(x*rcp, y*rcp); }
 19.1325 +    Vector2& operator/= (T s)                     { T rcp = T(1)/s;
 19.1326 +                                                    x *= rcp; y *= rcp;
 19.1327 +                                                    return *this; }
 19.1328 +
 19.1329 +    // Compare two vectors for equality with tolerance. Returns true if vectors match withing tolerance.
 19.1330 +    bool      Compare(const Vector2&b, T tolerance = Mathf::Tolerance)
 19.1331 +    {
 19.1332 +        return (fabs(b.x-x) < tolerance) && (fabs(b.y-y) < tolerance);
 19.1333 +    }
 19.1334 +    
 19.1335 +    // Dot product overload.
 19.1336 +    // Used to calculate angle q between two vectors among other things,
 19.1337 +    // as (A dot B) = |a||b|cos(q).
 19.1338 +    T     operator*  (const Vector2& b) const    { return x*b.x + y*b.y; }
 19.1339 +
 19.1340 +    // Returns the angle from this vector to b, in radians.
 19.1341 +    T       Angle(const Vector2& b) const        { return acos((*this * b)/(Length()*b.Length())); }
 19.1342 +
 19.1343 +    // Return Length of the vector squared.
 19.1344 +    T       LengthSq() const                     { return (x * x + y * y); }
 19.1345 +    // Return vector length.
 19.1346 +    T       Length() const                       { return sqrt(LengthSq()); }
 19.1347 +
 19.1348 +    // Returns distance between two points represented by vectors.
 19.1349 +    T       Distance(Vector2& b) const           { return (*this - b).Length(); }
 19.1350 +    
 19.1351 +    // Determine if this a unit vector.
 19.1352 +    bool    IsNormalized() const                 { return fabs(LengthSq() - T(1)) < Math<T>::Tolerance; }
 19.1353 +    // Normalize, convention vector length to 1.    
 19.1354 +    void    Normalize()                          { *this /= Length(); }
 19.1355 +    // Returns normalized (unit) version of the vector without modifying itself.
 19.1356 +    Vector2 Normalized() const                   { return *this / Length(); }
 19.1357 +
 19.1358 +    // Linearly interpolates from this vector to another.
 19.1359 +    // Factor should be between 0.0 and 1.0, with 0 giving full value to this.
 19.1360 +    Vector2 Lerp(const Vector2& b, T f) const    { return *this*(T(1) - f) + b*f; }
 19.1361 +
 19.1362 +    // Projects this vector onto the argument; in other words,
 19.1363 +    // A.Project(B) returns projection of vector A onto B.
 19.1364 +    Vector2 ProjectTo(const Vector2& b) const    { return b * ((*this * b) / b.LengthSq()); }
 19.1365 +};
 19.1366 +
 19.1367 +
 19.1368 +typedef Vector2<float>  Vector2f;
 19.1369 +typedef Vector2<double> Vector2d;
 19.1370 +
 19.1371 +//-------------------------------------------------------------------------------------
 19.1372 +// ***** Vector3f - 3D Vector3f
 19.1373 +
 19.1374 +// Vector3f represents a 3-dimensional vector or point in space,
 19.1375 +// consisting of coordinates x, y and z.
 19.1376 +
 19.1377 +template<class T>
 19.1378 +class Vector3
 19.1379 +{
 19.1380 +public:
 19.1381 +    T x, y, z;
 19.1382 +
 19.1383 +    Vector3() : x(0), y(0), z(0) { }
 19.1384 +    Vector3(T x_, T y_, T z_ = 0) : x(x_), y(y_), z(z_) { }
 19.1385 +    explicit Vector3(T s) : x(s), y(s), z(s) { }
 19.1386 +
 19.1387 +    bool     operator== (const Vector3& b) const  { return x == b.x && y == b.y && z == b.z; }
 19.1388 +    bool     operator!= (const Vector3& b) const  { return x != b.x || y != b.y || z != b.z; }
 19.1389 +             
 19.1390 +    Vector3  operator+  (const Vector3& b) const  { return Vector3(x + b.x, y + b.y, z + b.z); }
 19.1391 +    Vector3& operator+= (const Vector3& b)        { x += b.x; y += b.y; z += b.z; return *this; }
 19.1392 +    Vector3  operator-  (const Vector3& b) const  { return Vector3(x - b.x, y - b.y, z - b.z); }
 19.1393 +    Vector3& operator-= (const Vector3& b)        { x -= b.x; y -= b.y; z -= b.z; return *this; }
 19.1394 +    Vector3  operator- () const                   { return Vector3(-x, -y, -z); }
 19.1395 +
 19.1396 +    // Scalar multiplication/division scales vector.
 19.1397 +    Vector3  operator*  (T s) const               { return Vector3(x*s, y*s, z*s); }
 19.1398 +    Vector3& operator*= (T s)                     { x *= s; y *= s; z *= s; return *this; }
 19.1399 +
 19.1400 +    Vector3  operator/  (T s) const               { T rcp = T(1)/s;
 19.1401 +                                                    return Vector3(x*rcp, y*rcp, z*rcp); }
 19.1402 +    Vector3& operator/= (T s)                     { T rcp = T(1)/s;
 19.1403 +                                                    x *= rcp; y *= rcp; z *= rcp;
 19.1404 +                                                    return *this; }
 19.1405 +
 19.1406 +    // Compare two vectors for equality with tolerance. Returns true if vectors match withing tolerance.
 19.1407 +    bool      Compare(const Vector3&b, T tolerance = Mathf::Tolerance)
 19.1408 +    {
 19.1409 +        return (fabs(b.x-x) < tolerance) && (fabs(b.y-y) < tolerance) && (fabs(b.z-z) < tolerance);
 19.1410 +    }
 19.1411 +    
 19.1412 +    // Dot product overload.
 19.1413 +    // Used to calculate angle q between two vectors among other things,
 19.1414 +    // as (A dot B) = |a||b|cos(q).
 19.1415 +    T     operator*  (const Vector3& b) const    { return x*b.x + y*b.y + z*b.z; }
 19.1416 +
 19.1417 +    // Compute cross product, which generates a normal vector.
 19.1418 +    // Direction vector can be determined by right-hand rule: Pointing index finder in
 19.1419 +    // direction a and middle finger in direction b, thumb will point in a.Cross(b).
 19.1420 +    Vector3 Cross(const Vector3& b) const        { return Vector3(y*b.z - z*b.y,
 19.1421 +                                                                  z*b.x - x*b.z,
 19.1422 +                                                                  x*b.y - y*b.x); }
 19.1423 +
 19.1424 +    // Returns the angle from this vector to b, in radians.
 19.1425 +    T       Angle(const Vector3& b) const        { return acos((*this * b)/(Length()*b.Length())); }
 19.1426 +
 19.1427 +    // Return Length of the vector squared.
 19.1428 +    T       LengthSq() const                     { return (x * x + y * y + z * z); }
 19.1429 +    // Return vector length.
 19.1430 +    T       Length() const                       { return sqrt(LengthSq()); }
 19.1431 +
 19.1432 +    // Returns distance between two points represented by vectors.
 19.1433 +    T       Distance(Vector3& b) const           { return (*this - b).Length(); }
 19.1434 +    
 19.1435 +    // Determine if this a unit vector.
 19.1436 +    bool    IsNormalized() const                 { return fabs(LengthSq() - T(1)) < Math<T>::Tolerance; }
 19.1437 +    // Normalize, convention vector length to 1.    
 19.1438 +    void    Normalize()                          { *this /= Length(); }
 19.1439 +    // Returns normalized (unit) version of the vector without modifying itself.
 19.1440 +    Vector3 Normalized() const                   { return *this / Length(); }
 19.1441 +
 19.1442 +    // Linearly interpolates from this vector to another.
 19.1443 +    // Factor should be between 0.0 and 1.0, with 0 giving full value to this.
 19.1444 +    Vector3 Lerp(const Vector3& b, T f) const    { return *this*(T(1) - f) + b*f; }
 19.1445 +
 19.1446 +    // Projects this vector onto the argument; in other words,
 19.1447 +    // A.Project(B) returns projection of vector A onto B.
 19.1448 +    Vector3 ProjectTo(const Vector3& b) const    { return b * ((*this * b) / b.LengthSq()); }
 19.1449 +};
 19.1450 +
 19.1451 +
 19.1452 +typedef Vector3<float>  Vector3f;
 19.1453 +typedef Vector3<double> Vector3d;
 19.1454 +
 19.1455 +
 19.1456 +//-------------------------------------------------------------------------------------
 19.1457 +// ***** Matrix4f 
 19.1458 +
 19.1459 +// Matrix4f is a 4x4 matrix used for 3d transformations and projections.
 19.1460 +// Translation stored in the last column.
 19.1461 +// The matrix is stored in row-major order in memory, meaning that values
 19.1462 +// of the first row are stored before the next one.
 19.1463 +//
 19.1464 +// The arrangement of the matrix is chosen to be in Right-Handed 
 19.1465 +// coordinate system and counterclockwise rotations when looking down
 19.1466 +// the axis
 19.1467 +//
 19.1468 +// Transformation Order:
 19.1469 +//   - Transformations are applied from right to left, so the expression
 19.1470 +//     M1 * M2 * M3 * V means that the vector V is transformed by M3 first,
 19.1471 +//     followed by M2 and M1. 
 19.1472 +//
 19.1473 +// Coordinate system: Right Handed
 19.1474 +//
 19.1475 +// Rotations: Counterclockwise when looking down the axis. All angles are in radians.
 19.1476 +//    
 19.1477 +//  | sx   01   02   tx |    // First column  (sx, 10, 20): Axis X basis vector.
 19.1478 +//  | 10   sy   12   ty |    // Second column (01, sy, 21): Axis Y basis vector.
 19.1479 +//  | 20   21   sz   tz |    // Third columnt (02, 12, sz): Axis Z basis vector.
 19.1480 +//  | 30   31   32   33 |
 19.1481 +//
 19.1482 +//  The basis vectors are first three columns.
 19.1483 +
 19.1484 +class Matrix4f
 19.1485 +{
 19.1486 +    static Matrix4f IdentityValue;
 19.1487 +
 19.1488 +public:
 19.1489 +    float M[4][4];    
 19.1490 +
 19.1491 +    enum NoInitType { NoInit };
 19.1492 +
 19.1493 +    // Construct with no memory initialization.
 19.1494 +    Matrix4f(NoInitType) { }
 19.1495 +
 19.1496 +    // By default, we construct identity matrix.
 19.1497 +    Matrix4f()
 19.1498 +    {
 19.1499 +        SetIdentity();        
 19.1500 +    }
 19.1501 +
 19.1502 +    Matrix4f(float m11, float m12, float m13, float m14,
 19.1503 +             float m21, float m22, float m23, float m24,
 19.1504 +             float m31, float m32, float m33, float m34,
 19.1505 +             float m41, float m42, float m43, float m44)
 19.1506 +    {
 19.1507 +        M[0][0] = m11; M[0][1] = m12; M[0][2] = m13; M[0][3] = m14;
 19.1508 +        M[1][0] = m21; M[1][1] = m22; M[1][2] = m23; M[1][3] = m24;
 19.1509 +        M[2][0] = m31; M[2][1] = m32; M[2][2] = m33; M[2][3] = m34;
 19.1510 +        M[3][0] = m41; M[3][1] = m42; M[3][2] = m43; M[3][3] = m44;
 19.1511 +    }
 19.1512 +
 19.1513 +    Matrix4f(float m11, float m12, float m13,
 19.1514 +             float m21, float m22, float m23,
 19.1515 +             float m31, float m32, float m33)
 19.1516 +    {
 19.1517 +        M[0][0] = m11; M[0][1] = m12; M[0][2] = m13; M[0][3] = 0;
 19.1518 +        M[1][0] = m21; M[1][1] = m22; M[1][2] = m23; M[1][3] = 0;
 19.1519 +        M[2][0] = m31; M[2][1] = m32; M[2][2] = m33; M[2][3] = 0;
 19.1520 +        M[3][0] = 0;   M[3][1] = 0;   M[3][2] = 0;   M[3][3] = 1;
 19.1521 +    }
 19.1522 +
 19.1523 +    static const Matrix4f& Identity()  { return IdentityValue; }
 19.1524 +
 19.1525 +    void SetIdentity()
 19.1526 +    {
 19.1527 +        M[0][0] = M[1][1] = M[2][2] = M[3][3] = 1;
 19.1528 +        M[0][1] = M[1][0] = M[2][3] = M[3][1] = 0;
 19.1529 +        M[0][2] = M[1][2] = M[2][0] = M[3][2] = 0;
 19.1530 +        M[0][3] = M[1][3] = M[2][1] = M[3][0] = 0;
 19.1531 +    }
 19.1532 +
 19.1533 +    // Multiplies two matrices into destination with minimum copying.
 19.1534 +    static Matrix4f& Multiply(Matrix4f* d, const Matrix4f& a, const Matrix4f& b)
 19.1535 +    {
 19.1536 +        OVR_ASSERT((d != &a) && (d != &b));
 19.1537 +        int i = 0;
 19.1538 +        do {
 19.1539 +            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];
 19.1540 +            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];
 19.1541 +            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];
 19.1542 +            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];
 19.1543 +        } while((++i) < 4);
 19.1544 +
 19.1545 +        return *d;
 19.1546 +    }
 19.1547 +
 19.1548 +    Matrix4f operator* (const Matrix4f& b) const
 19.1549 +    {
 19.1550 +        Matrix4f result(Matrix4f::NoInit);
 19.1551 +        Multiply(&result, *this, b);
 19.1552 +        return result;
 19.1553 +    }
 19.1554 +
 19.1555 +    Matrix4f& operator*= (const Matrix4f& b)
 19.1556 +    {
 19.1557 +        return Multiply(this, Matrix4f(*this), b);
 19.1558 +    }
 19.1559 +
 19.1560 +    Matrix4f operator* (float s) const
 19.1561 +    {
 19.1562 +        return Matrix4f(M[0][0] * s, M[0][1] * s, M[0][2] * s, M[0][3] * s,
 19.1563 +                        M[1][0] * s, M[1][1] * s, M[1][2] * s, M[1][3] * s,
 19.1564 +                        M[2][0] * s, M[2][1] * s, M[2][2] * s, M[2][3] * s,
 19.1565 +                        M[3][0] * s, M[3][1] * s, M[3][2] * s, M[3][3] * s);
 19.1566 +    }
 19.1567 +
 19.1568 +    Matrix4f& operator*= (float s)
 19.1569 +    {
 19.1570 +        M[0][0] *= s; M[0][1] *= s; M[0][2] *= s; M[0][3] *= s;
 19.1571 +        M[1][0] *= s; M[1][1] *= s; M[1][2] *= s; M[1][3] *= s;
 19.1572 +        M[2][0] *= s; M[2][1] *= s; M[2][2] *= s; M[2][3] *= s;
 19.1573 +        M[3][0] *= s; M[3][1] *= s; M[3][2] *= s; M[3][3] *= s;
 19.1574 +        return *this;
 19.1575 +    }
 19.1576 +
 19.1577 +    Vector3f Transform(const Vector3f& v) const
 19.1578 +    {
 19.1579 +        return Vector3f(M[0][0] * v.x + M[0][1] * v.y + M[0][2] * v.z + M[0][3],
 19.1580 +                        M[1][0] * v.x + M[1][1] * v.y + M[1][2] * v.z + M[1][3],
 19.1581 +                        M[2][0] * v.x + M[2][1] * v.y + M[2][2] * v.z + M[2][3]);
 19.1582 +    }
 19.1583 +
 19.1584 +    Matrix4f Transposed() const
 19.1585 +    {
 19.1586 +        return Matrix4f(M[0][0], M[1][0], M[2][0], M[3][0],
 19.1587 +                        M[0][1], M[1][1], M[2][1], M[3][1],
 19.1588 +                        M[0][2], M[1][2], M[2][2], M[3][2],
 19.1589 +                        M[0][3], M[1][3], M[2][3], M[3][3]);
 19.1590 +    }
 19.1591 +
 19.1592 +    void     Transpose()
 19.1593 +    {
 19.1594 +        *this = Transposed();
 19.1595 +    }
 19.1596 +
 19.1597 +
 19.1598 +    float SubDet (const int* rows, const int* cols) const
 19.1599 +    {
 19.1600 +        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]])
 19.1601 +             - 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]])
 19.1602 +             + 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]]);
 19.1603 +    }
 19.1604 +
 19.1605 +    float Cofactor(int I, int J) const
 19.1606 +    {
 19.1607 +        const int indices[4][3] = {{1,2,3},{0,2,3},{0,1,3},{0,1,2}};
 19.1608 +        return ((I+J)&1) ? -SubDet(indices[I],indices[J]) : SubDet(indices[I],indices[J]);
 19.1609 +    }
 19.1610 +
 19.1611 +    float    Determinant() const
 19.1612 +    {
 19.1613 +        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);
 19.1614 +    }
 19.1615 +
 19.1616 +    Matrix4f Adjugated() const
 19.1617 +    {
 19.1618 +        return Matrix4f(Cofactor(0,0), Cofactor(1,0), Cofactor(2,0), Cofactor(3,0), 
 19.1619 +                        Cofactor(0,1), Cofactor(1,1), Cofactor(2,1), Cofactor(3,1), 
 19.1620 +                        Cofactor(0,2), Cofactor(1,2), Cofactor(2,2), Cofactor(3,2),
 19.1621 +                        Cofactor(0,3), Cofactor(1,3), Cofactor(2,3), Cofactor(3,3));
 19.1622 +    }
 19.1623 +
 19.1624 +    Matrix4f Inverted() const
 19.1625 +    {
 19.1626 +        float det = Determinant();
 19.1627 +        assert(det != 0);
 19.1628 +        return Adjugated() * (1.0f/det);
 19.1629 +    }
 19.1630 +
 19.1631 +    void Invert()
 19.1632 +    {
 19.1633 +        *this = Inverted();
 19.1634 +    }
 19.1635 +
 19.1636 +    //AnnaSteve:
 19.1637 +    // a,b,c, are the YawPitchRoll angles to be returned
 19.1638 +    // rotation a around axis A1
 19.1639 +    // is followed by rotation b around axis A2
 19.1640 +    // is followed by rotation c around axis A3
 19.1641 +    // rotations are CCW or CW (D) in LH or RH coordinate system (S)
 19.1642 +    template <Axis A1, Axis A2, Axis A3, RotateDirection D, HandedSystem S>
 19.1643 +    void ToEulerAngles(float *a, float *b, float *c)
 19.1644 +    {
 19.1645 +        OVR_COMPILER_ASSERT((A1 != A2) && (A2 != A3) && (A1 != A3));
 19.1646 +
 19.1647 +        float psign = -1.0f;
 19.1648 +        if (((A1 + 1) % 3 == A2) && ((A2 + 1) % 3 == A3)) // Determine whether even permutation
 19.1649 +        psign = 1.0f;
 19.1650 +        
 19.1651 +        float pm = psign*M[A1][A3];
 19.1652 +        if (pm < -1.0f + Math<float>::SingularityRadius)
 19.1653 +        { // South pole singularity
 19.1654 +            *a = 0.0f;
 19.1655 +            *b = -S*D*Math<float>::PiOver2;
 19.1656 +            *c = S*D*atan2( psign*M[A2][A1], M[A2][A2] );
 19.1657 +        }
 19.1658 +        else if (pm > 1.0 - Math<float>::SingularityRadius)
 19.1659 +        { // North pole singularity
 19.1660 +            *a = 0.0f;
 19.1661 +            *b = S*D*Math<float>::PiOver2;
 19.1662 +            *c = S*D*atan2( psign*M[A2][A1], M[A2][A2] );
 19.1663 +        }
 19.1664 +        else
 19.1665 +        { // Normal case (nonsingular)
 19.1666 +            *a = S*D*atan2( -psign*M[A2][A3], M[A3][A3] );
 19.1667 +            *b = S*D*asin(pm);
 19.1668 +            *c = S*D*atan2( -psign*M[A1][A2], M[A1][A1] );
 19.1669 +        }
 19.1670 +
 19.1671 +        return;
 19.1672 +    }
 19.1673 +
 19.1674 +    //AnnaSteve:
 19.1675 +    // a,b,c, are the YawPitchRoll angles to be returned
 19.1676 +    // rotation a around axis A1
 19.1677 +    // is followed by rotation b around axis A2
 19.1678 +    // is followed by rotation c around axis A1
 19.1679 +    // rotations are CCW or CW (D) in LH or RH coordinate system (S)
 19.1680 +    template <Axis A1, Axis A2, RotateDirection D, HandedSystem S>
 19.1681 +    void ToEulerAnglesABA(float *a, float *b, float *c)
 19.1682 +    {        
 19.1683 +         OVR_COMPILER_ASSERT(A1 != A2);
 19.1684 +  
 19.1685 +        // Determine the axis that was not supplied
 19.1686 +        int m = 3 - A1 - A2;
 19.1687 +
 19.1688 +        float psign = -1.0f;
 19.1689 +        if ((A1 + 1) % 3 == A2) // Determine whether even permutation
 19.1690 +            psign = 1.0f;
 19.1691 +
 19.1692 +        float c2 = M[A1][A1];
 19.1693 +        if (c2 < -1.0 + Math<float>::SingularityRadius)
 19.1694 +        { // South pole singularity
 19.1695 +            *a = 0.0f;
 19.1696 +            *b = S*D*Math<float>::Pi;
 19.1697 +            *c = S*D*atan2( -psign*M[A2][m],M[A2][A2]);
 19.1698 +        }
 19.1699 +        else if (c2 > 1.0 - Math<float>::SingularityRadius)
 19.1700 +        { // North pole singularity
 19.1701 +            *a = 0.0f;
 19.1702 +            *b = 0.0f;
 19.1703 +            *c = S*D*atan2( -psign*M[A2][m],M[A2][A2]);
 19.1704 +        }
 19.1705 +        else
 19.1706 +        { // Normal case (nonsingular)
 19.1707 +            *a = S*D*atan2( M[A2][A1],-psign*M[m][A1]);
 19.1708 +            *b = S*D*acos(c2);
 19.1709 +            *c = S*D*atan2( M[A1][A2],psign*M[A1][m]);
 19.1710 +        }
 19.1711 +        return;
 19.1712 +    }
 19.1713 +  
 19.1714 +    // Creates a matrix that converts the vertices from one coordinate system
 19.1715 +    // to another.
 19.1716 +    // 
 19.1717 +    static Matrix4f AxisConversion(const WorldAxes& to, const WorldAxes& from)
 19.1718 +    {        
 19.1719 +        // Holds axis values from the 'to' structure
 19.1720 +        int toArray[3] = { to.XAxis, to.YAxis, to.ZAxis };
 19.1721 +
 19.1722 +        // The inverse of the toArray
 19.1723 +        int inv[4]; 
 19.1724 +        inv[0] = inv[abs(to.XAxis)] = 0;
 19.1725 +        inv[abs(to.YAxis)] = 1;
 19.1726 +        inv[abs(to.ZAxis)] = 2;
 19.1727 +
 19.1728 +        Matrix4f m(0,  0,  0, 
 19.1729 +                   0,  0,  0,
 19.1730 +                   0,  0,  0);
 19.1731 +
 19.1732 +        // Only three values in the matrix need to be changed to 1 or -1.
 19.1733 +        m.M[inv[abs(from.XAxis)]][0] = float(from.XAxis/toArray[inv[abs(from.XAxis)]]);
 19.1734 +        m.M[inv[abs(from.YAxis)]][1] = float(from.YAxis/toArray[inv[abs(from.YAxis)]]);
 19.1735 +        m.M[inv[abs(from.ZAxis)]][2] = float(from.ZAxis/toArray[inv[abs(from.ZAxis)]]);
 19.1736 +        return m;
 19.1737 +    } 
 19.1738 +
 19.1739 +
 19.1740 +
 19.1741 +    static Matrix4f Translation(const Vector3f& v)
 19.1742 +    {
 19.1743 +        Matrix4f t;
 19.1744 +        t.M[0][3] = v.x;
 19.1745 +        t.M[1][3] = v.y;
 19.1746 +        t.M[2][3] = v.z;
 19.1747 +        return t;
 19.1748 +    }
 19.1749 +
 19.1750 +    static Matrix4f Translation(float x, float y, float z = 0.0f)
 19.1751 +    {
 19.1752 +        Matrix4f t;
 19.1753 +        t.M[0][3] = x;
 19.1754 +        t.M[1][3] = y;
 19.1755 +        t.M[2][3] = z;
 19.1756 +        return t;
 19.1757 +    }
 19.1758 +
 19.1759 +    static Matrix4f Scaling(const Vector3f& v)
 19.1760 +    {
 19.1761 +        Matrix4f t;
 19.1762 +        t.M[0][0] = v.x;
 19.1763 +        t.M[1][1] = v.y;
 19.1764 +        t.M[2][2] = v.z;
 19.1765 +        return t;
 19.1766 +    }
 19.1767 +
 19.1768 +    static Matrix4f Scaling(float x, float y, float z)
 19.1769 +    {
 19.1770 +        Matrix4f t;
 19.1771 +        t.M[0][0] = x;
 19.1772 +        t.M[1][1] = y;
 19.1773 +        t.M[2][2] = z;
 19.1774 +        return t;
 19.1775 +    }
 19.1776 +
 19.1777 +    static Matrix4f Scaling(float s)
 19.1778 +    {
 19.1779 +        Matrix4f t;
 19.1780 +        t.M[0][0] = s;
 19.1781 +        t.M[1][1] = s;
 19.1782 +        t.M[2][2] = s;
 19.1783 +        return t;
 19.1784 +    }
 19.1785 +
 19.1786 +  
 19.1787 +
 19.1788 +    //AnnaSteve : Just for quick testing.  Not for final API.  Need to remove case.
 19.1789 +    static Matrix4f RotationAxis(Axis A, float angle, RotateDirection d, HandedSystem s)
 19.1790 +    {
 19.1791 +        float sina = s * d *sin(angle);
 19.1792 +        float cosa = cos(angle);
 19.1793 +        
 19.1794 +        switch(A)
 19.1795 +        {
 19.1796 +        case Axis_X:
 19.1797 +            return Matrix4f(1,  0,     0, 
 19.1798 +                            0,  cosa,  -sina,
 19.1799 +                            0,  sina,  cosa);
 19.1800 +        case Axis_Y:
 19.1801 +            return Matrix4f(cosa,  0,   sina, 
 19.1802 +                            0,     1,   0,
 19.1803 +                            -sina, 0,   cosa);
 19.1804 +        case Axis_Z:
 19.1805 +            return Matrix4f(cosa,  -sina,  0, 
 19.1806 +                            sina,  cosa,   0,
 19.1807 +                            0,     0,      1);
 19.1808 +        }
 19.1809 +    }
 19.1810 +
 19.1811 +
 19.1812 +    // Creates a rotation matrix rotating around the X axis by 'angle' radians.
 19.1813 +    // Rotation direction is depends on the coordinate system:
 19.1814 +    //  RHS (Oculus default): Positive angle values rotate Counter-clockwise (CCW),
 19.1815 +    //                        while looking in the negative axis direction. This is the
 19.1816 +    //                        same as looking down from positive axis values towards origin.
 19.1817 +    //  LHS: Positive angle values rotate clock-wise (CW), while looking in the
 19.1818 +    //       negative axis direction.
 19.1819 +    static Matrix4f RotationX(float angle)
 19.1820 +    {
 19.1821 +        float sina = sin(angle);
 19.1822 +        float cosa = cos(angle);
 19.1823 +        return Matrix4f(1,  0,     0, 
 19.1824 +                        0,  cosa,  -sina,
 19.1825 +                        0,  sina,  cosa);
 19.1826 +    }
 19.1827 +
 19.1828 +    // Creates a rotation matrix rotating around the Y axis by 'angle' radians.
 19.1829 +    // Rotation direction is depends on the coordinate system:
 19.1830 +    //  RHS (Oculus default): Positive angle values rotate Counter-clockwise (CCW),
 19.1831 +    //                        while looking in the negative axis direction. This is the
 19.1832 +    //                        same as looking down from positive axis values towards origin.
 19.1833 +    //  LHS: Positive angle values rotate clock-wise (CW), while looking in the
 19.1834 +    //       negative axis direction.
 19.1835 +    static Matrix4f RotationY(float angle)
 19.1836 +    {
 19.1837 +        float sina = sin(angle);
 19.1838 +        float cosa = cos(angle);
 19.1839 +        return Matrix4f(cosa,  0,   sina, 
 19.1840 +                        0,     1,   0,
 19.1841 +                        -sina, 0,   cosa);
 19.1842 +    }
 19.1843 +
 19.1844 +    // Creates a rotation matrix rotating around the Z axis by 'angle' radians.
 19.1845 +    // Rotation direction is depends on the coordinate system:
 19.1846 +    //  RHS (Oculus default): Positive angle values rotate Counter-clockwise (CCW),
 19.1847 +    //                        while looking in the negative axis direction. This is the
 19.1848 +    //                        same as looking down from positive axis values towards origin.
 19.1849 +    //  LHS: Positive angle values rotate clock-wise (CW), while looking in the
 19.1850 +    //       negative axis direction.
 19.1851 +    static Matrix4f RotationZ(float angle)
 19.1852 +    {
 19.1853 +        float sina = sin(angle);
 19.1854 +        float cosa = cos(angle);
 19.1855 +        return Matrix4f(cosa,  -sina,  0, 
 19.1856 +                        sina,  cosa,   0,
 19.1857 +                        0,     0,      1);
 19.1858 +    }
 19.1859 +
 19.1860 +
 19.1861 +    // LookAtRH creates a View transformation matrix for right-handed coordinate system.
 19.1862 +    // The resulting matrix points camera from 'eye' towards 'at' direction, with 'up'
 19.1863 +    // specifying the up vector. The resulting matrix should be used with PerspectiveRH
 19.1864 +    // projection.
 19.1865 +    static Matrix4f LookAtRH(const Vector3f& eye, const Vector3f& at, const Vector3f& up);
 19.1866 +
 19.1867 +    // LookAtLH creates a View transformation matrix for left-handed coordinate system.
 19.1868 +    // The resulting matrix points camera from 'eye' towards 'at' direction, with 'up'
 19.1869 +    // specifying the up vector. 
 19.1870 +    static Matrix4f LookAtLH(const Vector3f& eye, const Vector3f& at, const Vector3f& up);
 19.1871 +    
 19.1872 +    
 19.1873 +    // PerspectiveRH creates a right-handed perspective projection matrix that can be
 19.1874 +    // used with the Oculus sample renderer. 
 19.1875 +    //  yfov   - Specifies vertical field of view in radians.
 19.1876 +    //  aspect - Screen aspect ration, which is usually width/height for square pixels.
 19.1877 +    //           Note that xfov = yfov * aspect.
 19.1878 +    //  znear  - Absolute value of near Z clipping clipping range.
 19.1879 +    //  zfar   - Absolute value of far  Z clipping clipping range (larger then near).
 19.1880 +    // Even though RHS usually looks in the direction of negative Z, positive values
 19.1881 +    // are expected for znear and zfar.
 19.1882 +    static Matrix4f PerspectiveRH(float yfov, float aspect, float znear, float zfar);
 19.1883 +    
 19.1884 +    
 19.1885 +    // PerspectiveRH creates a left-handed perspective projection matrix that can be
 19.1886 +    // used with the Oculus sample renderer. 
 19.1887 +    //  yfov   - Specifies vertical field of view in radians.
 19.1888 +    //  aspect - Screen aspect ration, which is usually width/height for square pixels.
 19.1889 +    //           Note that xfov = yfov * aspect.
 19.1890 +    //  znear  - Absolute value of near Z clipping clipping range.
 19.1891 +    //  zfar   - Absolute value of far  Z clipping clipping range (larger then near).
 19.1892 +    static Matrix4f PerspectiveLH(float yfov, float aspect, float znear, float zfar);
 19.1893 +
 19.1894 +
 19.1895 +    static Matrix4f Ortho2D(float w, float h);
 19.1896 +};
 19.1897 +
 19.1898 +
 19.1899 +//-------------------------------------------------------------------------------------
 19.1900 +// ***** Quat
 19.1901 +
 19.1902 +// Quatf represents a quaternion class used for rotations.
 19.1903 +// 
 19.1904 +// Quaternion multiplications are done in right-to-left order, to match the
 19.1905 +// behavior of matrices.
 19.1906 +
 19.1907 +
 19.1908 +template<class T>
 19.1909 +class Quat
 19.1910 +{
 19.1911 +public:
 19.1912 +    // w + Xi + Yj + Zk
 19.1913 +    T x, y, z, w;    
 19.1914 +
 19.1915 +    Quat() : x(0), y(0), z(0), w(1) {}
 19.1916 +    Quat(T x_, T y_, T z_, T w_) : x(x_), y(y_), z(z_), w(w_) {}
 19.1917 +
 19.1918 +
 19.1919 +    // Constructs rotation quaternion around the axis.
 19.1920 +    Quat(const Vector3<T>& axis, T angle)
 19.1921 +    {
 19.1922 +        Vector3<T> unitAxis = axis.Normalized();
 19.1923 +        T          sinHalfAngle = sin(angle * T(0.5));
 19.1924 +
 19.1925 +        w = cos(angle * T(0.5));
 19.1926 +        x = unitAxis.x * sinHalfAngle;
 19.1927 +        y = unitAxis.y * sinHalfAngle;
 19.1928 +        z = unitAxis.z * sinHalfAngle;
 19.1929 +    }
 19.1930 +
 19.1931 +    //AnnaSteve:
 19.1932 +    void AxisAngle(Axis A, T angle, RotateDirection d, HandedSystem s)
 19.1933 +    {
 19.1934 +        T sinHalfAngle = s * d *sin(angle * (T)0.5);
 19.1935 +        T v[3];
 19.1936 +        v[0] = v[1] = v[2] = (T)0;
 19.1937 +        v[A] = sinHalfAngle;
 19.1938 +        //return Quat(v[0], v[1], v[2], cos(angle * (T)0.5));
 19.1939 +        w = cos(angle * (T)0.5);
 19.1940 +        x = v[0];
 19.1941 +        y = v[1];
 19.1942 +        z = v[2];
 19.1943 +    }
 19.1944 +
 19.1945 +
 19.1946 +    void GetAxisAngle(Vector3<T>* axis, T* angle) const
 19.1947 +    {
 19.1948 +        if (LengthSq() > Math<T>::Tolerance * Math<T>::Tolerance)
 19.1949 +        {
 19.1950 +            *axis  = Vector3<T>(x, y, z).Normalized();
 19.1951 +            *angle = 2 * acos(w);
 19.1952 +        }
 19.1953 +        else
 19.1954 +        {
 19.1955 +            *axis = Vector3<T>(1, 0, 0);
 19.1956 +            *angle= 0;
 19.1957 +        }
 19.1958 +    }
 19.1959 +
 19.1960 +    bool operator== (const Quat& b) const   { return x == b.x && y == b.y && z == b.z && w == b.w; }
 19.1961 +    bool operator!= (const Quat& b) const   { return x != b.x || y != b.y || z != b.z || w != b.w; }
 19.1962 +
 19.1963 +    Quat  operator+  (const Quat& b) const  { return Quat(x + b.x, y + b.y, z + b.z, w + b.w); }
 19.1964 +    Quat& operator+= (const Quat& b)        { w += b.w; x += b.x; y += b.y; z += b.z; return *this; }
 19.1965 +    Quat  operator-  (const Quat& b) const  { return Quat(x - b.x, y - b.y, z - b.z, w - b.w); }
 19.1966 +    Quat& operator-= (const Quat& b)        { w -= b.w; x -= b.x; y -= b.y; z -= b.z; return *this; }
 19.1967 +
 19.1968 +    Quat  operator*  (T s) const            { return Quat(x * s, y * s, z * s, w * s); }
 19.1969 +    Quat& operator*= (T s)                  { w *= s; x *= s; y *= s; z *= s; return *this; }
 19.1970 +    Quat  operator/  (T s) const            { T rcp = T(1)/s; return Quat(x * rcp, y * rcp, z * rcp, w *rcp); }
 19.1971 +    Quat& operator/= (T s)                  { T rcp = T(1)/s; w *= rcp; x *= rcp; y *= rcp; z *= rcp; return *this; }
 19.1972 +
 19.1973 +    // Get Imaginary part vector
 19.1974 +    Vector3<T> Imag() const                 { return Vector3<T>(x,y,z); }
 19.1975 +
 19.1976 +    // Get quaternion length.
 19.1977 +    T       Length() const                  { return sqrt(x * x + y * y + z * z + w * w); }
 19.1978 +    // Get quaternion length squared.
 19.1979 +    T       LengthSq() const                { return (x * x + y * y + z * z + w * w); }
 19.1980 +    // Simple Eulidean distance in R^4 (not SLERP distance, but at least respects Haar measure)
 19.1981 +    T       Distance(const Quat& q) const
 19.1982 +    {
 19.1983 +        T d1 = (*this - q).Length();
 19.1984 +        T d2 = (*this + q).Length(); // Antipoldal point check
 19.1985 +        return (d1 < d2) ? d1 : d2;
 19.1986 +    }
 19.1987 +    T       DistanceSq(const Quat& q) const
 19.1988 +    {
 19.1989 +        T d1 = (*this - q).LengthSq();
 19.1990 +        T d2 = (*this + q).LengthSq(); // Antipoldal point check
 19.1991 +        return (d1 < d2) ? d1 : d2;
 19.1992 +    }
 19.1993 +
 19.1994 +    // Normalize
 19.1995 +    bool    IsNormalized() const            { return fabs(LengthSq() - 1) < Math<T>::Tolerance; }
 19.1996 +    void    Normalize()                     { *this /= Length(); }
 19.1997 +    Quat    Normalized() const              { return *this / Length(); }
 19.1998 +
 19.1999 +    // Returns conjugate of the quaternion. Produces inverse rotation if quaternion is normalized.
 19.2000 +    Quat    Conj() const                    { return Quat(-x, -y, -z, w); }
 19.2001 +
 19.2002 +    // AnnaSteve fixed: order of quaternion multiplication
 19.2003 +    // Quaternion multiplication. Combines quaternion rotations, performing the one on the 
 19.2004 +    // right hand side first.
 19.2005 +    Quat  operator* (const Quat& b) const   { return Quat(w * b.x + x * b.w + y * b.z - z * b.y,
 19.2006 +                                                          w * b.y - x * b.z + y * b.w + z * b.x,
 19.2007 +                                                          w * b.z + x * b.y - y * b.x + z * b.w,
 19.2008 +                                                          w * b.w - x * b.x - y * b.y - z * b.z); }
 19.2009 +
 19.2010 +    // 
 19.2011 +    // this^p normalized; same as rotating by this p times.
 19.2012 +    Quat PowNormalized(T p) const
 19.2013 +    {
 19.2014 +        Vector3<T> v;
 19.2015 +        T          a;
 19.2016 +        GetAxisAngle(&v, &a);
 19.2017 +        return Quat(v, a * p);
 19.2018 +    }
 19.2019 +    
 19.2020 +    // Rotate transforms vector in a manner that matches Matrix rotations (counter-clockwise,
 19.2021 +    // assuming negative direction of the axis). Standard formula: q(t) * V * q(t)^-1. 
 19.2022 +    Vector3<T> Rotate(const Vector3<T>& v) const
 19.2023 +    {
 19.2024 +        return ((*this * Quat<T>(v.x, v.y, v.z, 0)) * Inverted()).Imag();
 19.2025 +    }
 19.2026 +
 19.2027 +    
 19.2028 +    // Inversed quaternion rotates in the opposite direction.
 19.2029 +    Quat        Inverted() const
 19.2030 +    {
 19.2031 +        return Quat(-x, -y, -z, w);
 19.2032 +    }
 19.2033 +
 19.2034 +    // Sets this quaternion to the one rotates in the opposite direction.
 19.2035 +    void        Invert()
 19.2036 +    {
 19.2037 +        *this = Quat(-x, -y, -z, w);
 19.2038 +    }
 19.2039 +    
 19.2040 +    // Converting quaternion to matrix.
 19.2041 +    operator Matrix4f() const
 19.2042 +    {
 19.2043 +        T ww = w*w;
 19.2044 +        T xx = x*x;
 19.2045 +        T yy = y*y;
 19.2046 +        T zz = z*z;
 19.2047 +
 19.2048 +        return Matrix4f(float(ww + xx - yy - zz),  float(T(2) * (x*y - w*z)), float(T(2) * (x*z + w*y)),
 19.2049 +                        float(T(2) * (x*y + w*z)), float(ww - xx + yy - zz),  float(T(2) * (y*z - w*x)),
 19.2050 +                        float(T(2) * (x*z - w*y)), float(T(2) * (y*z + w*x)), float(ww - xx - yy + zz) );
 19.2051 +    }
 19.2052 +
 19.2053 +    
 19.2054 +    // GetEulerAngles extracts Euler angles from the quaternion, in the specified order of
 19.2055 +    // axis rotations and the specified coordinate system. Right-handed coordinate system
 19.2056 +    // is the default, with CCW rotations while looking in the negative axis direction.
 19.2057 +    // Here a,b,c, are the Yaw/Pitch/Roll angles to be returned.
 19.2058 +    // rotation a around axis A1
 19.2059 +    // is followed by rotation b around axis A2
 19.2060 +    // is followed by rotation c around axis A3
 19.2061 +    // rotations are CCW or CW (D) in LH or RH coordinate system (S)
 19.2062 +    template <Axis A1, Axis A2, Axis A3, RotateDirection D, HandedSystem S>
 19.2063 +    void GetEulerAngles(T *a, T *b, T *c)
 19.2064 +    {
 19.2065 +        OVR_COMPILER_ASSERT((A1 != A2) && (A2 != A3) && (A1 != A3));
 19.2066 +
 19.2067 +        T Q[3] = { x, y, z };  //Quaternion components x,y,z
 19.2068 +
 19.2069 +        T ww  = w*w;
 19.2070 +        T Q11 = Q[A1]*Q[A1];
 19.2071 +        T Q22 = Q[A2]*Q[A2];
 19.2072 +        T Q33 = Q[A3]*Q[A3];
 19.2073 +
 19.2074 +        T psign = T(-1.0);
 19.2075 +        // Determine whether even permutation
 19.2076 +        if (((A1 + 1) % 3 == A2) && ((A2 + 1) % 3 == A3))
 19.2077 +            psign = T(1.0);
 19.2078 +        
 19.2079 +        T s2 = psign * T(2.0) * (psign*w*Q[A2] + Q[A1]*Q[A3]);
 19.2080 +
 19.2081 +        if (s2 < (T)-1.0 + Math<T>::SingularityRadius)
 19.2082 +        { // South pole singularity
 19.2083 +            *a = T(0.0);
 19.2084 +            *b = -S*D*Math<T>::PiOver2;
 19.2085 +            *c = S*D*atan2((T)2.0*(psign*Q[A1]*Q[A2] + w*Q[A3]),
 19.2086 +		                   ww + Q22 - Q11 - Q33 );
 19.2087 +        }
 19.2088 +        else if (s2 > (T)1.0 - Math<T>::SingularityRadius)
 19.2089 +        {  // North pole singularity
 19.2090 +            *a = (T)0.0;
 19.2091 +            *b = S*D*Math<T>::PiOver2;
 19.2092 +            *c = S*D*atan2((T)2.0*(psign*Q[A1]*Q[A2] + w*Q[A3]),
 19.2093 +		                   ww + Q22 - Q11 - Q33);
 19.2094 +        }
 19.2095 +        else
 19.2096 +        {
 19.2097 +            *a = -S*D*atan2((T)-2.0*(w*Q[A1] - psign*Q[A2]*Q[A3]),
 19.2098 +		                    ww + Q33 - Q11 - Q22);
 19.2099 +            *b = S*D*asin(s2);
 19.2100 +            *c = S*D*atan2((T)2.0*(w*Q[A3] - psign*Q[A1]*Q[A2]),
 19.2101 +		                   ww + Q11 - Q22 - Q33);
 19.2102 +        }      
 19.2103 +        return;
 19.2104 +    }
 19.2105 +
 19.2106 +    template <Axis A1, Axis A2, Axis A3, RotateDirection D>
 19.2107 +    void GetEulerAngles(T *a, T *b, T *c)
 19.2108 +    { GetEulerAngles<A1, A2, A3, D, Handed_R>(a, b, c); }
 19.2109 +
 19.2110 +    template <Axis A1, Axis A2, Axis A3>
 19.2111 +    void GetEulerAngles(T *a, T *b, T *c)
 19.2112 +    { GetEulerAngles<A1, A2, A3, Rotate_CCW, Handed_R>(a, b, c); }
 19.2113 +
 19.2114 +
 19.2115 +    // GetEulerAnglesABA extracts Euler angles from the quaternion, in the specified order of
 19.2116 +    // axis rotations and the specified coordinate system. Right-handed coordinate system
 19.2117 +    // is the default, with CCW rotations while looking in the negative axis direction.
 19.2118 +    // Here a,b,c, are the Yaw/Pitch/Roll angles to be returned.
 19.2119 +    // rotation a around axis A1
 19.2120 +    // is followed by rotation b around axis A2
 19.2121 +    // is followed by rotation c around axis A1
 19.2122 +    // Rotations are CCW or CW (D) in LH or RH coordinate system (S)
 19.2123 +    template <Axis A1, Axis A2, RotateDirection D, HandedSystem S>
 19.2124 +    void GetEulerAnglesABA(T *a, T *b, T *c)
 19.2125 +    {
 19.2126 +        OVR_COMPILER_ASSERT(A1 != A2);
 19.2127 +
 19.2128 +        T Q[3] = {x, y, z}; // Quaternion components
 19.2129 +
 19.2130 +        // Determine the missing axis that was not supplied
 19.2131 +        int m = 3 - A1 - A2;
 19.2132 +
 19.2133 +        T ww = w*w;
 19.2134 +        T Q11 = Q[A1]*Q[A1];
 19.2135 +        T Q22 = Q[A2]*Q[A2];
 19.2136 +        T Qmm = Q[m]*Q[m];
 19.2137 +
 19.2138 +        T psign = T(-1.0);
 19.2139 +        if ((A1 + 1) % 3 == A2) // Determine whether even permutation
 19.2140 +        {
 19.2141 +            psign = (T)1.0;
 19.2142 +        }
 19.2143 +
 19.2144 +        T c2 = ww + Q11 - Q22 - Qmm;
 19.2145 +        if (c2 < (T)-1.0 + Math<T>::SingularityRadius)
 19.2146 +        { // South pole singularity
 19.2147 +            *a = (T)0.0;
 19.2148 +            *b = S*D*Math<T>::Pi;
 19.2149 +            *c = S*D*atan2( (T)2.0*(w*Q[A1] - psign*Q[A2]*Q[m]),
 19.2150 +		                    ww + Q22 - Q11 - Qmm);
 19.2151 +        }
 19.2152 +        else if (c2 > (T)1.0 - Math<T>::SingularityRadius)
 19.2153 +        {  // North pole singularity
 19.2154 +            *a = (T)0.0;
 19.2155 +            *b = (T)0.0;
 19.2156 +            *c = S*D*atan2( (T)2.0*(w*Q[A1] - psign*Q[A2]*Q[m]),
 19.2157 +		                   ww + Q22 - Q11 - Qmm);
 19.2158 +        }
 19.2159 +        else
 19.2160 +        {
 19.2161 +            *a = S*D*atan2( psign*w*Q[m] + Q[A1]*Q[A2],
 19.2162 +		                   w*Q[A2] -psign*Q[A1]*Q[m]);
 19.2163 +            *b = S*D*acos(c2);
 19.2164 +            *c = S*D*atan2( -psign*w*Q[m] + Q[A1]*Q[A2],
 19.2165 +		                   w*Q[A2] + psign*Q[A1]*Q[m]);
 19.2166 +        }
 19.2167 +        return;
 19.2168 +    }
 19.2169 +};
 19.2170 +
 19.2171 +
 19.2172 +typedef Quat<float>  Quatf;
 19.2173 +typedef Quat<double> Quatd;
 19.2174 +
 19.2175 +
 19.2176 +
 19.2177 +//-------------------------------------------------------------------------------------
 19.2178 +// ***** Angle
 19.2179 +
 19.2180 +// Cleanly representing the algebra of 2D rotations.
 19.2181 +// The operations maintain the angle between -Pi and Pi, the same range as atan2.
 19.2182 +// 
 19.2183 +
 19.2184 +template<class T>
 19.2185 +class Angle
 19.2186 +{
 19.2187 +public:
 19.2188 +	enum AngularUnits
 19.2189 +	{
 19.2190 +		Radians = 0,
 19.2191 +		Degrees = 1
 19.2192 +	};
 19.2193 +
 19.2194 +    Angle() : a(0) {}
 19.2195 +    
 19.2196 +	// Fix the range to be between -Pi and Pi
 19.2197 +	Angle(T a_, AngularUnits u = Radians) : a((u == Radians) ? a_ : a_*Math<T>::DegreeToRadFactor) { FixRange(); }
 19.2198 +
 19.2199 +	T    Get(AngularUnits u = Radians) const       { return (u == Radians) ? a : a*Math<T>::RadToDegreeFactor; }
 19.2200 +	void Set(const T& x, AngularUnits u = Radians) { a = (u == Radians) ? x : x*Math<T>::DegreeToRadFactor; FixRange(); }
 19.2201 +	int Sign() const                               { if (a == 0) return 0; else return (a > 0) ? 1 : -1; }
 19.2202 +	T   Abs() const                                { return (a > 0) ? a : -a; }
 19.2203 +
 19.2204 +    bool operator== (const Angle& b) const    { return a == b.a; }
 19.2205 +    bool operator!= (const Angle& b) const    { return a != b.a; }
 19.2206 +//	bool operator<  (const Angle& b) const    { return a < a.b; } 
 19.2207 +//	bool operator>  (const Angle& b) const    { return a > a.b; } 
 19.2208 +//	bool operator<= (const Angle& b) const    { return a <= a.b; } 
 19.2209 +//	bool operator>= (const Angle& b) const    { return a >= a.b; } 
 19.2210 +//	bool operator= (const T& x)               { a = x; FixRange(); }
 19.2211 +
 19.2212 +	// These operations assume a is already between -Pi and Pi.
 19.2213 +    Angle  operator+  (const Angle& b) const  { return Angle(a + b.a); }
 19.2214 +	Angle  operator+  (const T& x) const      { return Angle(a + x); }
 19.2215 +	Angle& operator+= (const Angle& b)        { a = a + b.a; FastFixRange(); return *this; }
 19.2216 +	Angle& operator+= (const T& x)            { a = a + x; FixRange(); return *this; }
 19.2217 +	Angle  operator-  (const Angle& b) const  { return Angle(a - b.a); }
 19.2218 +	Angle  operator-  (const T& x) const      { return Angle(a - x); }
 19.2219 +	Angle& operator-= (const Angle& b)        { a = a - b.a; FastFixRange(); return *this; }
 19.2220 +	Angle& operator-= (const T& x)            { a = a - x; FixRange(); return *this; }
 19.2221 +	
 19.2222 +	T   Distance(const Angle& b)              { T c = fabs(a - b.a); return (c <= Math<T>::Pi) ? c : Math<T>::TwoPi - c; }
 19.2223 +
 19.2224 +private:
 19.2225 +
 19.2226 +	// The stored angle, which should be maintained between -Pi and Pi
 19.2227 +	T a;
 19.2228 +
 19.2229 +	// Fixes the angle range to [-Pi,Pi], but assumes no more than 2Pi away on either side 
 19.2230 +	inline void FastFixRange()
 19.2231 +	{
 19.2232 +		if (a < -Math<T>::Pi)
 19.2233 +			a += Math<T>::TwoPi;
 19.2234 +		else if (a > Math<T>::Pi)
 19.2235 +			a -= Math<T>::TwoPi;
 19.2236 +	}
 19.2237 +
 19.2238 +	// Fixes the angle range to [-Pi,Pi] for any given range, but slower then the fast method
 19.2239 +	inline void FixRange()
 19.2240 +	{
 19.2241 +		a = fmod(a,Math<T>::TwoPi);
 19.2242 +		if (a < -Math<T>::Pi)
 19.2243 +			a += Math<T>::TwoPi;
 19.2244 +		else if (a > Math<T>::Pi)
 19.2245 +			a -= Math<T>::TwoPi;
 19.2246 +	}
 19.2247 +};
 19.2248 +
 19.2249 +
 19.2250 +typedef Angle<float>  Anglef;
 19.2251 +typedef Angle<double> Angled;
 19.2252 +
 19.2253 +
 19.2254 +//-------------------------------------------------------------------------------------
 19.2255 +// ***** Plane
 19.2256 +
 19.2257 +// Consists of a normal vector and distance from the origin where the plane is located.
 19.2258 +
 19.2259 +template<class T>
 19.2260 +class Plane : public RefCountBase<Plane<T> >
 19.2261 +{
 19.2262 +public:
 19.2263 +    Vector3<T> N;
 19.2264 +    T          D;
 19.2265 +
 19.2266 +    Plane() : D(0) {}
 19.2267 +
 19.2268 +    // Normals must already be normalized
 19.2269 +    Plane(const Vector3<T>& n, T d) : N(n), D(d) {}
 19.2270 +    Plane(T x, T y, T z, T d) : N(x,y,z), D(d) {}
 19.2271 +
 19.2272 +    // construct from a point on the plane and the normal
 19.2273 +    Plane(const Vector3<T>& p, const Vector3<T>& n) : N(n), D(-(p * n)) {}
 19.2274 +
 19.2275 +    // Find the point to plane distance. The sign indicates what side of the plane the point is on (0 = point on plane).
 19.2276 +    T TestSide(const Vector3<T>& p) const
 19.2277 +    {
 19.2278 +        return (N * p) + D;
 19.2279 +    }
 19.2280 +
 19.2281 +    Plane<T> Flipped() const
 19.2282 +    {
 19.2283 +        return Plane(-N, -D);
 19.2284 +    }
 19.2285 +
 19.2286 +    void Flip()
 19.2287 +    {
 19.2288 +        N = -N;
 19.2289 +        D = -D;
 19.2290 +    }
 19.2291 +
 19.2292 +	bool operator==(const Plane<T>& rhs) const
 19.2293 +	{
 19.2294 +		return (this->D == rhs.D && this->N == rhs.N);
 19.2295 +	}
 19.2296 +};
 19.2297 +
 19.2298 +typedef Plane<float> Planef;
 19.2299 +
 19.2300 +}
 19.2301 +
 19.2302 +#endif
    20.1 --- a/libovr/Src/Kernel/OVR_RefCount.cpp	Sat Sep 14 17:51:03 2013 +0300
    20.2 +++ b/libovr/Src/Kernel/OVR_RefCount.cpp	Sun Sep 15 04:10:05 2013 +0300
    20.3 @@ -1,1 +1,100 @@
    20.4 -/************************************************************************************
    20.5 
    20.6 Filename    :   OVR_RefCount.cpp
    20.7 Content     :   Reference counting implementation
    20.8 Created     :   September 19, 2012
    20.9 Notes       : 
   20.10 
   20.11 Copyright   :   Copyright 2012 Oculus VR, Inc. All Rights reserved.
   20.12 
   20.13 Use of this software is subject to the terms of the Oculus license
   20.14 agreement provided at the time of installation or download, or which
   20.15 otherwise accompanies this software in either electronic or hard copy form.
   20.16 
   20.17 ************************************************************************************/
   20.18 
   20.19 #include "OVR_RefCount.h"
   20.20 #include "OVR_Atomic.h"
   20.21 #include "OVR_Log.h"
   20.22 
   20.23 namespace OVR {
   20.24 
   20.25 #ifdef OVR_CC_ARM
   20.26 void* ReturnArg0(void* p)
   20.27 {
   20.28     return p;
   20.29 }
   20.30 #endif
   20.31 
   20.32 // ***** Reference Count Base implementation
   20.33 
   20.34 RefCountImplCore::~RefCountImplCore()
   20.35 {
   20.36     // RefCount can be either 1 or 0 here.
   20.37     //  0 if Release() was properly called.
   20.38     //  1 if the object was declared on stack or as an aggregate.
   20.39     OVR_ASSERT(RefCount <= 1);
   20.40 }
   20.41 
   20.42 #ifdef OVR_BUILD_DEBUG
   20.43 void RefCountImplCore::reportInvalidDelete(void *pmem)
   20.44 {
   20.45     OVR_DEBUG_LOG(
   20.46         ("Invalid delete call on ref-counted object at %p. Please use Release()", pmem));
   20.47     OVR_ASSERT(0);
   20.48 }
   20.49 #endif
   20.50 
   20.51 RefCountNTSImplCore::~RefCountNTSImplCore()
   20.52 {
   20.53     // RefCount can be either 1 or 0 here.
   20.54     //  0 if Release() was properly called.
   20.55     //  1 if the object was declared on stack or as an aggregate.
   20.56     OVR_ASSERT(RefCount <= 1);
   20.57 }
   20.58 
   20.59 #ifdef OVR_BUILD_DEBUG
   20.60 void RefCountNTSImplCore::reportInvalidDelete(void *pmem)
   20.61 {
   20.62     OVR_DEBUG_LOG(
   20.63         ("Invalid delete call on ref-counted object at %p. Please use Release()", pmem));
   20.64     OVR_ASSERT(0);
   20.65 }
   20.66 #endif
   20.67 
   20.68 
   20.69 // *** Thread-Safe RefCountImpl
   20.70 
   20.71 void    RefCountImpl::AddRef()
   20.72 {
   20.73     AtomicOps<int>::ExchangeAdd_NoSync(&RefCount, 1);
   20.74 }
   20.75 void    RefCountImpl::Release()
   20.76 {
   20.77     if ((AtomicOps<int>::ExchangeAdd_NoSync(&RefCount, -1) - 1) == 0)
   20.78         delete this;
   20.79 }
   20.80 
   20.81 // *** Thread-Safe RefCountVImpl w/virtual AddRef/Release
   20.82 
   20.83 void    RefCountVImpl::AddRef()
   20.84 {
   20.85     AtomicOps<int>::ExchangeAdd_NoSync(&RefCount, 1);
   20.86 }
   20.87 void    RefCountVImpl::Release()
   20.88 {
   20.89     if ((AtomicOps<int>::ExchangeAdd_NoSync(&RefCount, -1) - 1) == 0)
   20.90         delete this;
   20.91 }
   20.92 
   20.93 // *** NON-Thread-Safe RefCountImpl
   20.94 
   20.95 void    RefCountNTSImpl::Release() const
   20.96 {
   20.97     RefCount--;
   20.98     if (RefCount == 0)
   20.99         delete this;
  20.100 }
  20.101 
  20.102 
  20.103 } // OVR
  20.104 \ No newline at end of file
  20.105 +/************************************************************************************
  20.106 +
  20.107 +Filename    :   OVR_RefCount.cpp
  20.108 +Content     :   Reference counting implementation
  20.109 +Created     :   September 19, 2012
  20.110 +Notes       : 
  20.111 +
  20.112 +Copyright   :   Copyright 2012 Oculus VR, Inc. All Rights reserved.
  20.113 +
  20.114 +Use of this software is subject to the terms of the Oculus license
  20.115 +agreement provided at the time of installation or download, or which
  20.116 +otherwise accompanies this software in either electronic or hard copy form.
  20.117 +
  20.118 +************************************************************************************/
  20.119 +
  20.120 +#include "OVR_RefCount.h"
  20.121 +#include "OVR_Atomic.h"
  20.122 +#include "OVR_Log.h"
  20.123 +
  20.124 +namespace OVR {
  20.125 +
  20.126 +#ifdef OVR_CC_ARM
  20.127 +void* ReturnArg0(void* p)
  20.128 +{
  20.129 +    return p;
  20.130 +}
  20.131 +#endif
  20.132 +
  20.133 +// ***** Reference Count Base implementation
  20.134 +
  20.135 +RefCountImplCore::~RefCountImplCore()
  20.136 +{
  20.137 +    // RefCount can be either 1 or 0 here.
  20.138 +    //  0 if Release() was properly called.
  20.139 +    //  1 if the object was declared on stack or as an aggregate.
  20.140 +    OVR_ASSERT(RefCount <= 1);
  20.141 +}
  20.142 +
  20.143 +#ifdef OVR_BUILD_DEBUG
  20.144 +void RefCountImplCore::reportInvalidDelete(void *pmem)
  20.145 +{
  20.146 +    OVR_DEBUG_LOG(
  20.147 +        ("Invalid delete call on ref-counted object at %p. Please use Release()", pmem));
  20.148 +    OVR_ASSERT(0);
  20.149 +}
  20.150 +#endif
  20.151 +
  20.152 +RefCountNTSImplCore::~RefCountNTSImplCore()
  20.153 +{
  20.154 +    // RefCount can be either 1 or 0 here.
  20.155 +    //  0 if Release() was properly called.
  20.156 +    //  1 if the object was declared on stack or as an aggregate.
  20.157 +    OVR_ASSERT(RefCount <= 1);
  20.158 +}
  20.159 +
  20.160 +#ifdef OVR_BUILD_DEBUG
  20.161 +void RefCountNTSImplCore::reportInvalidDelete(void *pmem)
  20.162 +{
  20.163 +    OVR_DEBUG_LOG(
  20.164 +        ("Invalid delete call on ref-counted object at %p. Please use Release()", pmem));
  20.165 +    OVR_ASSERT(0);
  20.166 +}
  20.167 +#endif
  20.168 +
  20.169 +
  20.170 +// *** Thread-Safe RefCountImpl
  20.171 +
  20.172 +void    RefCountImpl::AddRef()
  20.173 +{
  20.174 +    AtomicOps<int>::ExchangeAdd_NoSync(&RefCount, 1);
  20.175 +}
  20.176 +void    RefCountImpl::Release()
  20.177 +{
  20.178 +    if ((AtomicOps<int>::ExchangeAdd_NoSync(&RefCount, -1) - 1) == 0)
  20.179 +        delete this;
  20.180 +}
  20.181 +
  20.182 +// *** Thread-Safe RefCountVImpl w/virtual AddRef/Release
  20.183 +
  20.184 +void    RefCountVImpl::AddRef()
  20.185 +{
  20.186 +    AtomicOps<int>::ExchangeAdd_NoSync(&RefCount, 1);
  20.187 +}
  20.188 +void    RefCountVImpl::Release()
  20.189 +{
  20.190 +    if ((AtomicOps<int>::ExchangeAdd_NoSync(&RefCount, -1) - 1) == 0)
  20.191 +        delete this;
  20.192 +}
  20.193 +
  20.194 +// *** NON-Thread-Safe RefCountImpl
  20.195 +
  20.196 +void    RefCountNTSImpl::Release() const
  20.197 +{
  20.198 +    RefCount--;
  20.199 +    if (RefCount == 0)
  20.200 +        delete this;
  20.201 +}
  20.202 +
  20.203 +
  20.204 +} // OVR
    21.1 --- a/libovr/Src/Kernel/OVR_RefCount.h	Sat Sep 14 17:51:03 2013 +0300
    21.2 +++ b/libovr/Src/Kernel/OVR_RefCount.h	Sun Sep 15 04:10:05 2013 +0300
    21.3 @@ -1,1 +1,522 @@
    21.4 -/************************************************************************************
    21.5 
    21.6 PublicHeader:   Kernel
    21.7 Filename    :   OVR_RefCount.h
    21.8 Content     :   Reference counting implementation headers
    21.9 Created     :   September 19, 2012
   21.10 Notes       : 
   21.11 
   21.12 Copyright   :   Copyright 2012 Oculus VR, Inc. All Rights reserved.
   21.13 
   21.14 Use of this software is subject to the terms of the Oculus license
   21.15 agreement provided at the time of installation or download, or which
   21.16 otherwise accompanies this software in either electronic or hard copy form.
   21.17 
   21.18 ************************************************************************************/
   21.19 
   21.20 #ifndef OVR_RefCount_h
   21.21 #define OVR_RefCount_h
   21.22 
   21.23 #include "OVR_Types.h"
   21.24 #include "OVR_Allocator.h"
   21.25 
   21.26 namespace OVR {
   21.27 
   21.28 //-----------------------------------------------------------------------------------
   21.29 // ***** Reference Counting
   21.30 
   21.31 // There are three types of reference counting base classes:
   21.32 //
   21.33 //  RefCountBase     - Provides thread-safe reference counting (Default).
   21.34 //  RefCountBaseNTS  - Non Thread Safe version of reference counting.
   21.35 
   21.36 
   21.37 // ***** Declared classes
   21.38 
   21.39 template<class C>
   21.40 class   RefCountBase;
   21.41 template<class C>
   21.42 class   RefCountBaseNTS;
   21.43 
   21.44 class   RefCountImpl;
   21.45 class   RefCountNTSImpl;
   21.46 
   21.47 
   21.48 //-----------------------------------------------------------------------------------
   21.49 // ***** Implementation For Reference Counting
   21.50 
   21.51 // RefCountImplCore holds RefCount value and defines a few utility
   21.52 // functions shared by all implementations.
   21.53 
   21.54 class RefCountImplCore
   21.55 {
   21.56 protected:
   21.57     volatile int RefCount;
   21.58 
   21.59 public:
   21.60     // RefCountImpl constructor always initializes RefCount to 1 by default.
   21.61     OVR_FORCE_INLINE RefCountImplCore() : RefCount(1) { }
   21.62 
   21.63     // Need virtual destructor
   21.64     // This:    1. Makes sure the right destructor's called.
   21.65     //          2. Makes us have VTable, necessary if we are going to have format needed by InitNewMem()
   21.66     virtual ~RefCountImplCore();
   21.67 
   21.68     // Debug method only.
   21.69     int GetRefCount() const { return RefCount;  }
   21.70 
   21.71     // This logic is used to detect invalid 'delete' calls of reference counted
   21.72     // objects. Direct delete calls are not allowed on them unless they come in
   21.73     // internally from Release.
   21.74 #ifdef OVR_BUILD_DEBUG    
   21.75     static void   OVR_CDECL  reportInvalidDelete(void *pmem);
   21.76     inline static void checkInvalidDelete(RefCountImplCore *pmem)
   21.77     {
   21.78         if (pmem->RefCount != 0)
   21.79             reportInvalidDelete(pmem);
   21.80     }
   21.81 #else
   21.82     inline static void checkInvalidDelete(RefCountImplCore *) { }
   21.83 #endif
   21.84 
   21.85     // Base class ref-count content should not be copied.
   21.86     void operator = (const RefCountImplCore &) { }  
   21.87 };
   21.88 
   21.89 class RefCountNTSImplCore
   21.90 {
   21.91 protected:
   21.92     mutable int RefCount;
   21.93 
   21.94 public:
   21.95     // RefCountImpl constructor always initializes RefCount to 1 by default.
   21.96     OVR_FORCE_INLINE RefCountNTSImplCore() : RefCount(1) { }
   21.97 
   21.98     // Need virtual destructor
   21.99     // This:    1. Makes sure the right destructor's called.
  21.100     //          2. Makes us have VTable, necessary if we are going to have format needed by InitNewMem()
  21.101     virtual ~RefCountNTSImplCore();
  21.102 
  21.103     // Debug method only.
  21.104     int             GetRefCount() const { return RefCount;  }
  21.105 
  21.106     // This logic is used to detect invalid 'delete' calls of reference counted
  21.107     // objects. Direct delete calls are not allowed on them unless they come in
  21.108     // internally from Release.
  21.109 #ifdef OVR_BUILD_DEBUG    
  21.110     static void   OVR_CDECL  reportInvalidDelete(void *pmem);
  21.111     OVR_FORCE_INLINE static void checkInvalidDelete(RefCountNTSImplCore *pmem)
  21.112     {
  21.113         if (pmem->RefCount != 0)
  21.114             reportInvalidDelete(pmem);
  21.115     }
  21.116 #else
  21.117     OVR_FORCE_INLINE static void checkInvalidDelete(RefCountNTSImplCore *) { }
  21.118 #endif
  21.119 
  21.120     // Base class ref-count content should not be copied.
  21.121     void operator = (const RefCountNTSImplCore &) { }  
  21.122 };
  21.123 
  21.124 
  21.125 
  21.126 // RefCountImpl provides Thread-Safe implementation of reference counting, so
  21.127 // it should be used by default in most places.
  21.128 
  21.129 class RefCountImpl : public RefCountImplCore
  21.130 {
  21.131 public:
  21.132     // Thread-Safe Ref-Count Implementation.
  21.133     void    AddRef();
  21.134     void    Release();   
  21.135 };
  21.136 
  21.137 // RefCountVImpl provides Thread-Safe implementation of reference counting, plus,
  21.138 // virtual AddRef and Release.
  21.139 
  21.140 class RefCountVImpl : public RefCountImplCore
  21.141 {
  21.142 public:
  21.143     // Thread-Safe Ref-Count Implementation.
  21.144     virtual void      AddRef();
  21.145     virtual void      Release();   
  21.146 };
  21.147 
  21.148 
  21.149 // RefCountImplNTS provides Non-Thread-Safe implementation of reference counting,
  21.150 // which is slightly more efficient since it doesn't use atomics.
  21.151 
  21.152 class RefCountNTSImpl : public RefCountNTSImplCore
  21.153 {
  21.154 public:
  21.155     OVR_FORCE_INLINE void    AddRef() const { RefCount++; }
  21.156     void    Release() const;   
  21.157 };
  21.158 
  21.159 
  21.160 
  21.161 // RefCountBaseStatImpl<> is a common class that adds new/delete override with Stat tracking
  21.162 // to the reference counting implementation. Base must be one of the RefCountImpl classes.
  21.163 
  21.164 template<class Base>
  21.165 class RefCountBaseStatImpl : public Base
  21.166 {
  21.167 public:
  21.168     RefCountBaseStatImpl() { }
  21.169      
  21.170     // *** Override New and Delete
  21.171 
  21.172     // DOM-IGNORE-BEGIN
  21.173     // Undef new temporarily if it is being redefined
  21.174 #ifdef OVR_DEFINE_NEW
  21.175 #undef new
  21.176 #endif
  21.177 
  21.178 #ifdef OVR_BUILD_DEBUG
  21.179     // Custom check used to detect incorrect calls of 'delete' on ref-counted objects.
  21.180     #define OVR_REFCOUNTALLOC_CHECK_DELETE(class_name, p)   \
  21.181         do {if (p) Base::checkInvalidDelete((class_name*)p); } while(0)
  21.182 #else
  21.183     #define OVR_REFCOUNTALLOC_CHECK_DELETE(class_name, p)
  21.184 #endif
  21.185 
  21.186     // Redefine all new & delete operators.
  21.187     OVR_MEMORY_REDEFINE_NEW_IMPL(Base, OVR_REFCOUNTALLOC_CHECK_DELETE)
  21.188 
  21.189 #ifdef OVR_DEFINE_NEW
  21.190 #define new OVR_DEFINE_NEW
  21.191 #endif
  21.192         // OVR_BUILD_DEFINE_NEW
  21.193         // DOM-IGNORE-END
  21.194 };
  21.195 
  21.196 
  21.197 
  21.198 //-----------------------------------------------------------------------------------
  21.199 // *** End user RefCountBase<> classes
  21.200 
  21.201 
  21.202 // RefCountBase is a base class for classes that require thread-safe reference
  21.203 // counting; it also overrides the new and delete operators to use MemoryHeap.
  21.204 //
  21.205 // Reference counted objects start out with RefCount value of 1. Further lifetime
  21.206 // management is done through the AddRef() and Release() methods, typically
  21.207 // hidden by Ptr<>.
  21.208 
  21.209 template<class C>
  21.210 class RefCountBase : public RefCountBaseStatImpl<RefCountImpl>
  21.211 {
  21.212 public:    
  21.213     // Constructor.
  21.214     OVR_FORCE_INLINE RefCountBase() : RefCountBaseStatImpl<RefCountImpl>() { }    
  21.215 };
  21.216 
  21.217 // RefCountBaseV is the same as RefCountBase but with virtual AddRef/Release
  21.218 
  21.219 template<class C>
  21.220 class RefCountBaseV : public RefCountBaseStatImpl<RefCountVImpl>
  21.221 {
  21.222 public:    
  21.223     // Constructor.
  21.224     OVR_FORCE_INLINE RefCountBaseV() : RefCountBaseStatImpl<RefCountVImpl>() { }    
  21.225 };
  21.226 
  21.227 
  21.228 // RefCountBaseNTS is a base class for classes that require Non-Thread-Safe reference
  21.229 // counting; it also overrides the new and delete operators to use MemoryHeap.
  21.230 // This class should only be used if all pointers to it are known to be assigned,
  21.231 // destroyed and manipulated within one thread.
  21.232 //
  21.233 // Reference counted objects start out with RefCount value of 1. Further lifetime
  21.234 // management is done through the AddRef() and Release() methods, typically
  21.235 // hidden by Ptr<>.
  21.236 
  21.237 template<class C>
  21.238 class RefCountBaseNTS : public RefCountBaseStatImpl<RefCountNTSImpl>
  21.239 {
  21.240 public:    
  21.241     // Constructor.
  21.242     OVR_FORCE_INLINE RefCountBaseNTS() : RefCountBaseStatImpl<RefCountNTSImpl>() { }    
  21.243 };
  21.244 
  21.245 //-----------------------------------------------------------------------------------
  21.246 // ***** Pickable template pointer
  21.247 enum PickType { PickValue };
  21.248 
  21.249 template <typename T>
  21.250 class Pickable
  21.251 {
  21.252 public:
  21.253     Pickable() : pV(NULL) {}
  21.254     explicit Pickable(T* p) : pV(p) {}
  21.255     Pickable(T* p, PickType) : pV(p) 
  21.256     {
  21.257         OVR_ASSERT(pV);
  21.258         if (pV)
  21.259             pV->AddRef();
  21.260     }
  21.261     template <typename OT>
  21.262     Pickable(const Pickable<OT>& other) : pV(other.GetPtr()) {}
  21.263 
  21.264 public:
  21.265     Pickable& operator =(const Pickable& other)
  21.266     {
  21.267         OVR_ASSERT(pV == NULL);
  21.268         pV = other.pV;
  21.269         // Extra check.
  21.270         //other.pV = NULL;
  21.271         return *this;
  21.272     }
  21.273 
  21.274 public:
  21.275     T* GetPtr() const { return pV; }
  21.276     T* operator->() const
  21.277     {
  21.278         return pV;
  21.279     }
  21.280     T& operator*() const
  21.281     {
  21.282         OVR_ASSERT(pV);
  21.283         return *pV;
  21.284     }
  21.285 
  21.286 private:
  21.287     T* pV;
  21.288 };
  21.289 
  21.290 template <typename T>
  21.291 OVR_FORCE_INLINE
  21.292 Pickable<T> MakePickable(T* p)
  21.293 {
  21.294     return Pickable<T>(p);
  21.295 }
  21.296 
  21.297 //-----------------------------------------------------------------------------------
  21.298 // ***** Ref-Counted template pointer
  21.299 
  21.300 // Automatically AddRefs and Releases interfaces
  21.301 
  21.302 void* ReturnArg0(void* p);
  21.303 
  21.304 template<class C>
  21.305 class Ptr
  21.306 {
  21.307 #ifdef OVR_CC_ARM
  21.308     static C* ReturnArg(void* p) { return (C*)ReturnArg0(p); }
  21.309 #endif
  21.310 
  21.311 protected:
  21.312     C   *pObject;
  21.313 
  21.314 public:
  21.315 
  21.316     // Constructors
  21.317     OVR_FORCE_INLINE Ptr() : pObject(0)
  21.318     { }
  21.319 #ifdef OVR_CC_ARM
  21.320     OVR_FORCE_INLINE Ptr(C &robj) : pObject(ReturnArg(&robj))
  21.321 #else
  21.322     OVR_FORCE_INLINE Ptr(C &robj) : pObject(&robj)
  21.323 #endif
  21.324     { }
  21.325     OVR_FORCE_INLINE Ptr(Pickable<C> v) : pObject(v.GetPtr())
  21.326     {
  21.327         // No AddRef() on purpose.
  21.328     }
  21.329     OVR_FORCE_INLINE Ptr(Ptr<C>& other, PickType) : pObject(other.pObject)
  21.330     {
  21.331         other.pObject = NULL;
  21.332         // No AddRef() on purpose.
  21.333     }
  21.334     OVR_FORCE_INLINE Ptr(C *pobj)
  21.335     {
  21.336         if (pobj) pobj->AddRef();   
  21.337         pObject = pobj;
  21.338     }
  21.339     OVR_FORCE_INLINE Ptr(const Ptr<C> &src)
  21.340     {
  21.341         if (src.pObject) src.pObject->AddRef();     
  21.342         pObject = src.pObject;
  21.343     }
  21.344 
  21.345     template<class R>
  21.346     OVR_FORCE_INLINE Ptr(Ptr<R> &src)
  21.347     {
  21.348         if (src) src->AddRef();
  21.349         pObject = src;
  21.350     }
  21.351     template<class R>
  21.352     OVR_FORCE_INLINE Ptr(Pickable<R> v) : pObject(v.GetPtr())
  21.353     {
  21.354         // No AddRef() on purpose.
  21.355     }
  21.356 
  21.357     // Destructor
  21.358     OVR_FORCE_INLINE ~Ptr()
  21.359     {
  21.360         if (pObject) pObject->Release();        
  21.361     }
  21.362 
  21.363     // Compares
  21.364     OVR_FORCE_INLINE bool operator == (const Ptr &other) const       { return pObject == other.pObject; }
  21.365     OVR_FORCE_INLINE bool operator != (const Ptr &other) const       { return pObject != other.pObject; }
  21.366 
  21.367     OVR_FORCE_INLINE bool operator == (C *pother) const              { return pObject == pother; }
  21.368     OVR_FORCE_INLINE bool operator != (C *pother) const              { return pObject != pother; }
  21.369 
  21.370 
  21.371     OVR_FORCE_INLINE bool operator < (const Ptr &other) const       { return pObject < other.pObject; }
  21.372 
  21.373     // Assignment
  21.374     template<class R>
  21.375     OVR_FORCE_INLINE const Ptr<C>& operator = (const Ptr<R> &src)
  21.376     {
  21.377         if (src) src->AddRef();
  21.378         if (pObject) pObject->Release();        
  21.379         pObject = src;
  21.380         return *this;
  21.381     }   
  21.382     // Specialization
  21.383     OVR_FORCE_INLINE const Ptr<C>& operator = (const Ptr<C> &src)
  21.384     {
  21.385         if (src) src->AddRef();
  21.386         if (pObject) pObject->Release();        
  21.387         pObject = src;
  21.388         return *this;
  21.389     }   
  21.390     
  21.391     OVR_FORCE_INLINE const Ptr<C>& operator = (C *psrc)
  21.392     {
  21.393         if (psrc) psrc->AddRef();
  21.394         if (pObject) pObject->Release();        
  21.395         pObject = psrc;
  21.396         return *this;
  21.397     }   
  21.398     OVR_FORCE_INLINE const Ptr<C>& operator = (C &src)
  21.399     {       
  21.400         if (pObject) pObject->Release();        
  21.401         pObject = &src;
  21.402         return *this;
  21.403     }
  21.404     OVR_FORCE_INLINE Ptr<C>& operator = (Pickable<C> src)
  21.405     {
  21.406         return Pick(src);
  21.407     }
  21.408     template<class R>
  21.409     OVR_FORCE_INLINE Ptr<C>& operator = (Pickable<R> src)
  21.410     {
  21.411         return Pick(src);
  21.412     }
  21.413     
  21.414     // Set Assignment
  21.415     template<class R>
  21.416     OVR_FORCE_INLINE Ptr<C>& SetPtr(const Ptr<R> &src)
  21.417     {
  21.418         if (src) src->AddRef();
  21.419         if (pObject) pObject->Release();
  21.420         pObject = src;
  21.421         return *this;
  21.422     }
  21.423     // Specialization
  21.424     OVR_FORCE_INLINE Ptr<C>& SetPtr(const Ptr<C> &src)
  21.425     {
  21.426         if (src) src->AddRef();
  21.427         if (pObject) pObject->Release();
  21.428         pObject = src;
  21.429         return *this;
  21.430     }   
  21.431     
  21.432     OVR_FORCE_INLINE Ptr<C>& SetPtr(C *psrc)
  21.433     {
  21.434         if (psrc) psrc->AddRef();
  21.435         if (pObject) pObject->Release();
  21.436         pObject = psrc;
  21.437         return *this;
  21.438     }   
  21.439     OVR_FORCE_INLINE Ptr<C>& SetPtr(C &src)
  21.440     {       
  21.441         if (pObject) pObject->Release();
  21.442         pObject = &src;
  21.443         return *this;
  21.444     }
  21.445     OVR_FORCE_INLINE Ptr<C>& SetPtr(Pickable<C> src)
  21.446     {       
  21.447         return Pick(src);
  21.448     }
  21.449 
  21.450     // Nulls ref-counted pointer without decrement
  21.451     OVR_FORCE_INLINE void    NullWithoutRelease()    
  21.452     { 
  21.453         pObject = 0;    
  21.454     }
  21.455 
  21.456     // Clears the pointer to the object
  21.457     OVR_FORCE_INLINE void    Clear()
  21.458     {
  21.459         if (pObject) pObject->Release();
  21.460         pObject = 0;
  21.461     }
  21.462 
  21.463     // Obtain pointer reference directly, for D3D interfaces
  21.464     OVR_FORCE_INLINE C*& GetRawRef()                 { return pObject; }
  21.465 
  21.466     // Access Operators
  21.467     OVR_FORCE_INLINE C* GetPtr() const               { return pObject; }
  21.468     OVR_FORCE_INLINE C& operator * () const          { return *pObject; }
  21.469     OVR_FORCE_INLINE C* operator -> ()  const        { return pObject; }
  21.470     // Conversion                   
  21.471     OVR_FORCE_INLINE operator C* () const            { return pObject; }
  21.472 
  21.473     // Pickers.
  21.474 
  21.475     // Pick a value.
  21.476     OVR_FORCE_INLINE Ptr<C>& Pick(Ptr<C>& other)
  21.477     {
  21.478         if (&other != this)
  21.479         {
  21.480             if (pObject) pObject->Release();
  21.481             pObject = other.pObject;
  21.482             other.pObject = 0;
  21.483         }
  21.484 
  21.485         return *this;
  21.486     }
  21.487 
  21.488     OVR_FORCE_INLINE Ptr<C>& Pick(Pickable<C> v)
  21.489     {
  21.490         if (v.GetPtr() != pObject)
  21.491         {
  21.492             if (pObject) pObject->Release();
  21.493             pObject = v.GetPtr();
  21.494         }
  21.495 
  21.496         return *this;
  21.497     }
  21.498 
  21.499     template<class R>
  21.500     OVR_FORCE_INLINE Ptr<C>& Pick(Pickable<R> v)
  21.501     {
  21.502         if (v.GetPtr() != pObject)
  21.503         {
  21.504             if (pObject) pObject->Release();
  21.505             pObject = v.GetPtr();
  21.506         }
  21.507 
  21.508         return *this;
  21.509     }
  21.510 
  21.511     OVR_FORCE_INLINE Ptr<C>& Pick(C* p)
  21.512     {
  21.513         if (p != pObject)
  21.514         {
  21.515             if (pObject) pObject->Release();
  21.516             pObject = p;
  21.517         }
  21.518 
  21.519         return *this;
  21.520     }
  21.521 };
  21.522 
  21.523 } // OVR
  21.524 
  21.525 #endif
  21.526 \ No newline at end of file
  21.527 +/************************************************************************************
  21.528 +
  21.529 +PublicHeader:   Kernel
  21.530 +Filename    :   OVR_RefCount.h
  21.531 +Content     :   Reference counting implementation headers
  21.532 +Created     :   September 19, 2012
  21.533 +Notes       : 
  21.534 +
  21.535 +Copyright   :   Copyright 2012 Oculus VR, Inc. All Rights reserved.
  21.536 +
  21.537 +Use of this software is subject to the terms of the Oculus license
  21.538 +agreement provided at the time of installation or download, or which
  21.539 +otherwise accompanies this software in either electronic or hard copy form.
  21.540 +
  21.541 +************************************************************************************/
  21.542 +
  21.543 +#ifndef OVR_RefCount_h
  21.544 +#define OVR_RefCount_h
  21.545 +
  21.546 +#include "OVR_Types.h"
  21.547 +#include "OVR_Allocator.h"
  21.548 +
  21.549 +namespace OVR {
  21.550 +
  21.551 +//-----------------------------------------------------------------------------------
  21.552 +// ***** Reference Counting
  21.553 +
  21.554 +// There are three types of reference counting base classes:
  21.555 +//
  21.556 +//  RefCountBase     - Provides thread-safe reference counting (Default).
  21.557 +//  RefCountBaseNTS  - Non Thread Safe version of reference counting.
  21.558 +
  21.559 +
  21.560 +// ***** Declared classes
  21.561 +
  21.562 +template<class C>
  21.563 +class   RefCountBase;
  21.564 +template<class C>
  21.565 +class   RefCountBaseNTS;
  21.566 +
  21.567 +class   RefCountImpl;
  21.568 +class   RefCountNTSImpl;
  21.569 +
  21.570 +
  21.571 +//-----------------------------------------------------------------------------------
  21.572 +// ***** Implementation For Reference Counting
  21.573 +
  21.574 +// RefCountImplCore holds RefCount value and defines a few utility
  21.575 +// functions shared by all implementations.
  21.576 +
  21.577 +class RefCountImplCore
  21.578 +{
  21.579 +protected:
  21.580 +    volatile int RefCount;
  21.581 +
  21.582 +public:
  21.583 +    // RefCountImpl constructor always initializes RefCount to 1 by default.
  21.584 +    OVR_FORCE_INLINE RefCountImplCore() : RefCount(1) { }
  21.585 +
  21.586 +    // Need virtual destructor
  21.587 +    // This:    1. Makes sure the right destructor's called.
  21.588 +    //          2. Makes us have VTable, necessary if we are going to have format needed by InitNewMem()
  21.589 +    virtual ~RefCountImplCore();
  21.590 +
  21.591 +    // Debug method only.
  21.592 +    int GetRefCount() const { return RefCount;  }
  21.593 +
  21.594 +    // This logic is used to detect invalid 'delete' calls of reference counted
  21.595 +    // objects. Direct delete calls are not allowed on them unless they come in
  21.596 +    // internally from Release.
  21.597 +#ifdef OVR_BUILD_DEBUG    
  21.598 +    static void   OVR_CDECL  reportInvalidDelete(void *pmem);
  21.599 +    inline static void checkInvalidDelete(RefCountImplCore *pmem)
  21.600 +    {
  21.601 +        if (pmem->RefCount != 0)
  21.602 +            reportInvalidDelete(pmem);
  21.603 +    }
  21.604 +#else
  21.605 +    inline static void checkInvalidDelete(RefCountImplCore *) { }
  21.606 +#endif
  21.607 +
  21.608 +    // Base class ref-count content should not be copied.
  21.609 +    void operator = (const RefCountImplCore &) { }  
  21.610 +};
  21.611 +
  21.612 +class RefCountNTSImplCore
  21.613 +{
  21.614 +protected:
  21.615 +    mutable int RefCount;
  21.616 +
  21.617 +public:
  21.618 +    // RefCountImpl constructor always initializes RefCount to 1 by default.
  21.619 +    OVR_FORCE_INLINE RefCountNTSImplCore() : RefCount(1) { }
  21.620 +
  21.621 +    // Need virtual destructor
  21.622 +    // This:    1. Makes sure the right destructor's called.
  21.623 +    //          2. Makes us have VTable, necessary if we are going to have format needed by InitNewMem()
  21.624 +    virtual ~RefCountNTSImplCore();
  21.625 +
  21.626 +    // Debug method only.
  21.627 +    int             GetRefCount() const { return RefCount;  }
  21.628 +
  21.629 +    // This logic is used to detect invalid 'delete' calls of reference counted
  21.630 +    // objects. Direct delete calls are not allowed on them unless they come in
  21.631 +    // internally from Release.
  21.632 +#ifdef OVR_BUILD_DEBUG    
  21.633 +    static void   OVR_CDECL  reportInvalidDelete(void *pmem);
  21.634 +    OVR_FORCE_INLINE static void checkInvalidDelete(RefCountNTSImplCore *pmem)
  21.635 +    {
  21.636 +        if (pmem->RefCount != 0)
  21.637 +            reportInvalidDelete(pmem);
  21.638 +    }
  21.639 +#else
  21.640 +    OVR_FORCE_INLINE static void checkInvalidDelete(RefCountNTSImplCore *) { }
  21.641 +#endif
  21.642 +
  21.643 +    // Base class ref-count content should not be copied.
  21.644 +    void operator = (const RefCountNTSImplCore &) { }  
  21.645 +};
  21.646 +
  21.647 +
  21.648 +
  21.649 +// RefCountImpl provides Thread-Safe implementation of reference counting, so
  21.650 +// it should be used by default in most places.
  21.651 +
  21.652 +class RefCountImpl : public RefCountImplCore
  21.653 +{
  21.654 +public:
  21.655 +    // Thread-Safe Ref-Count Implementation.
  21.656 +    void    AddRef();
  21.657 +    void    Release();   
  21.658 +};
  21.659 +
  21.660 +// RefCountVImpl provides Thread-Safe implementation of reference counting, plus,
  21.661 +// virtual AddRef and Release.
  21.662 +
  21.663 +class RefCountVImpl : public RefCountImplCore
  21.664 +{
  21.665 +public:
  21.666 +    // Thread-Safe Ref-Count Implementation.
  21.667 +    virtual void      AddRef();
  21.668 +    virtual void      Release();   
  21.669 +};
  21.670 +
  21.671 +
  21.672 +// RefCountImplNTS provides Non-Thread-Safe implementation of reference counting,
  21.673 +// which is slightly more efficient since it doesn't use atomics.
  21.674 +
  21.675 +class RefCountNTSImpl : public RefCountNTSImplCore
  21.676 +{
  21.677 +public:
  21.678 +    OVR_FORCE_INLINE void    AddRef() const { RefCount++; }
  21.679 +    void    Release() const;   
  21.680 +};
  21.681 +
  21.682 +
  21.683 +
  21.684 +// RefCountBaseStatImpl<> is a common class that adds new/delete override with Stat tracking
  21.685 +// to the reference counting implementation. Base must be one of the RefCountImpl classes.
  21.686 +
  21.687 +template<class Base>
  21.688 +class RefCountBaseStatImpl : public Base
  21.689 +{
  21.690 +public:
  21.691 +    RefCountBaseStatImpl() { }
  21.692 +     
  21.693 +    // *** Override New and Delete
  21.694 +
  21.695 +    // DOM-IGNORE-BEGIN
  21.696 +    // Undef new temporarily if it is being redefined
  21.697 +#ifdef OVR_DEFINE_NEW
  21.698 +#undef new
  21.699 +#endif
  21.700 +
  21.701 +#ifdef OVR_BUILD_DEBUG
  21.702 +    // Custom check used to detect incorrect calls of 'delete' on ref-counted objects.
  21.703 +    #define OVR_REFCOUNTALLOC_CHECK_DELETE(class_name, p)   \
  21.704 +        do {if (p) Base::checkInvalidDelete((class_name*)p); } while(0)
  21.705 +#else
  21.706 +    #define OVR_REFCOUNTALLOC_CHECK_DELETE(class_name, p)
  21.707 +#endif
  21.708 +
  21.709 +    // Redefine all new & delete operators.
  21.710 +    OVR_MEMORY_REDEFINE_NEW_IMPL(Base, OVR_REFCOUNTALLOC_CHECK_DELETE)
  21.711 +
  21.712 +#ifdef OVR_DEFINE_NEW
  21.713 +#define new OVR_DEFINE_NEW
  21.714 +#endif
  21.715 +        // OVR_BUILD_DEFINE_NEW
  21.716 +        // DOM-IGNORE-END
  21.717 +};
  21.718 +
  21.719 +
  21.720 +
  21.721 +//-----------------------------------------------------------------------------------
  21.722 +// *** End user RefCountBase<> classes
  21.723 +
  21.724 +
  21.725 +// RefCountBase is a base class for classes that require thread-safe reference
  21.726 +// counting; it also overrides the new and delete operators to use MemoryHeap.
  21.727 +//
  21.728 +// Reference counted objects start out with RefCount value of 1. Further lifetime
  21.729 +// management is done through the AddRef() and Release() methods, typically
  21.730 +// hidden by Ptr<>.
  21.731 +
  21.732 +template<class C>
  21.733 +class RefCountBase : public RefCountBaseStatImpl<RefCountImpl>
  21.734 +{
  21.735 +public:    
  21.736 +    // Constructor.
  21.737 +    OVR_FORCE_INLINE RefCountBase() : RefCountBaseStatImpl<RefCountImpl>() { }    
  21.738 +};
  21.739 +
  21.740 +// RefCountBaseV is the same as RefCountBase but with virtual AddRef/Release
  21.741 +
  21.742 +template<class C>
  21.743 +class RefCountBaseV : public RefCountBaseStatImpl<RefCountVImpl>
  21.744 +{
  21.745 +public:    
  21.746 +    // Constructor.
  21.747 +    OVR_FORCE_INLINE RefCountBaseV() : RefCountBaseStatImpl<RefCountVImpl>() { }    
  21.748 +};
  21.749 +
  21.750 +
  21.751 +// RefCountBaseNTS is a base class for classes that require Non-Thread-Safe reference
  21.752 +// counting; it also overrides the new and delete operators to use MemoryHeap.
  21.753 +// This class should only be used if all pointers to it are known to be assigned,
  21.754 +// destroyed and manipulated within one thread.
  21.755 +//
  21.756 +// Reference counted objects start out with RefCount value of 1. Further lifetime
  21.757 +// management is done through the AddRef() and Release() methods, typically
  21.758 +// hidden by Ptr<>.
  21.759 +
  21.760 +template<class C>
  21.761 +class RefCountBaseNTS : public RefCountBaseStatImpl<RefCountNTSImpl>
  21.762 +{
  21.763 +public:    
  21.764 +    // Constructor.
  21.765 +    OVR_FORCE_INLINE RefCountBaseNTS() : RefCountBaseStatImpl<RefCountNTSImpl>() { }    
  21.766 +};
  21.767 +
  21.768 +//-----------------------------------------------------------------------------------
  21.769 +// ***** Pickable template pointer
  21.770 +enum PickType { PickValue };
  21.771 +
  21.772 +template <typename T>
  21.773 +class Pickable
  21.774 +{
  21.775 +public:
  21.776 +    Pickable() : pV(NULL) {}
  21.777 +    explicit Pickable(T* p) : pV(p) {}
  21.778 +    Pickable(T* p, PickType) : pV(p) 
  21.779 +    {
  21.780 +        OVR_ASSERT(pV);
  21.781 +        if (pV)
  21.782 +            pV->AddRef();
  21.783 +    }
  21.784 +    template <typename OT>
  21.785 +    Pickable(const Pickable<OT>& other) : pV(other.GetPtr()) {}
  21.786 +
  21.787 +public:
  21.788 +    Pickable& operator =(const Pickable& other)
  21.789 +    {
  21.790 +        OVR_ASSERT(pV == NULL);
  21.791 +        pV = other.pV;
  21.792 +        // Extra check.
  21.793 +        //other.pV = NULL;
  21.794 +        return *this;
  21.795 +    }
  21.796 +
  21.797 +public:
  21.798 +    T* GetPtr() const { return pV; }
  21.799 +    T* operator->() const
  21.800 +    {
  21.801 +        return pV;
  21.802 +    }
  21.803 +    T& operator*() const
  21.804 +    {
  21.805 +        OVR_ASSERT(pV);
  21.806 +        return *pV;
  21.807 +    }
  21.808 +
  21.809 +private:
  21.810 +    T* pV;
  21.811 +};
  21.812 +
  21.813 +template <typename T>
  21.814 +OVR_FORCE_INLINE
  21.815 +Pickable<T> MakePickable(T* p)
  21.816 +{
  21.817 +    return Pickable<T>(p);
  21.818 +}
  21.819 +
  21.820 +//-----------------------------------------------------------------------------------
  21.821 +// ***** Ref-Counted template pointer
  21.822 +
  21.823 +// Automatically AddRefs and Releases interfaces
  21.824 +
  21.825 +void* ReturnArg0(void* p);
  21.826 +
  21.827 +template<class C>
  21.828 +class Ptr
  21.829 +{
  21.830 +#ifdef OVR_CC_ARM
  21.831 +    static C* ReturnArg(void* p) { return (C*)ReturnArg0(p); }
  21.832 +#endif
  21.833 +
  21.834 +protected:
  21.835 +    C   *pObject;
  21.836 +
  21.837 +public:
  21.838 +
  21.839 +    // Constructors
  21.840 +    OVR_FORCE_INLINE Ptr() : pObject(0)
  21.841 +    { }
  21.842 +#ifdef OVR_CC_ARM
  21.843 +    OVR_FORCE_INLINE Ptr(C &robj) : pObject(ReturnArg(&robj))
  21.844 +#else
  21.845 +    OVR_FORCE_INLINE Ptr(C &robj) : pObject(&robj)
  21.846 +#endif
  21.847 +    { }
  21.848 +    OVR_FORCE_INLINE Ptr(Pickable<C> v) : pObject(v.GetPtr())
  21.849 +    {
  21.850 +        // No AddRef() on purpose.
  21.851 +    }
  21.852 +    OVR_FORCE_INLINE Ptr(Ptr<C>& other, PickType) : pObject(other.pObject)
  21.853 +    {
  21.854 +        other.pObject = NULL;
  21.855 +        // No AddRef() on purpose.
  21.856 +    }
  21.857 +    OVR_FORCE_INLINE Ptr(C *pobj)
  21.858 +    {
  21.859 +        if (pobj) pobj->AddRef();   
  21.860 +        pObject = pobj;
  21.861 +    }
  21.862 +    OVR_FORCE_INLINE Ptr(const Ptr<C> &src)
  21.863 +    {
  21.864 +        if (src.pObject) src.pObject->AddRef();     
  21.865 +        pObject = src.pObject;
  21.866 +    }
  21.867 +
  21.868 +    template<class R>
  21.869 +    OVR_FORCE_INLINE Ptr(Ptr<R> &src)
  21.870 +    {
  21.871 +        if (src) src->AddRef();
  21.872 +        pObject = src;
  21.873 +    }
  21.874 +    template<class R>
  21.875 +    OVR_FORCE_INLINE Ptr(Pickable<R> v) : pObject(v.GetPtr())
  21.876 +    {
  21.877 +        // No AddRef() on purpose.
  21.878 +    }
  21.879 +
  21.880 +    // Destructor
  21.881 +    OVR_FORCE_INLINE ~Ptr()
  21.882 +    {
  21.883 +        if (pObject) pObject->Release();        
  21.884 +    }
  21.885 +
  21.886 +    // Compares
  21.887 +    OVR_FORCE_INLINE bool operator == (const Ptr &other) const       { return pObject == other.pObject; }
  21.888 +    OVR_FORCE_INLINE bool operator != (const Ptr &other) const       { return pObject != other.pObject; }
  21.889 +
  21.890 +    OVR_FORCE_INLINE bool operator == (C *pother) const              { return pObject == pother; }
  21.891 +    OVR_FORCE_INLINE bool operator != (C *pother) const              { return pObject != pother; }
  21.892 +
  21.893 +
  21.894 +    OVR_FORCE_INLINE bool operator < (const Ptr &other) const       { return pObject < other.pObject; }
  21.895 +
  21.896 +    // Assignment
  21.897 +    template<class R>
  21.898 +    OVR_FORCE_INLINE const Ptr<C>& operator = (const Ptr<R> &src)
  21.899 +    {
  21.900 +        if (src) src->AddRef();
  21.901 +        if (pObject) pObject->Release();        
  21.902 +        pObject = src;
  21.903 +        return *this;
  21.904 +    }   
  21.905 +    // Specialization
  21.906 +    OVR_FORCE_INLINE const Ptr<C>& operator = (const Ptr<C> &src)
  21.907 +    {
  21.908 +        if (src) src->AddRef();
  21.909 +        if (pObject) pObject->Release();        
  21.910 +        pObject = src;
  21.911 +        return *this;
  21.912 +    }   
  21.913 +    
  21.914 +    OVR_FORCE_INLINE const Ptr<C>& operator = (C *psrc)
  21.915 +    {
  21.916 +        if (psrc) psrc->AddRef();
  21.917 +        if (pObject) pObject->Release();        
  21.918 +        pObject = psrc;
  21.919 +        return *this;
  21.920 +    }   
  21.921 +    OVR_FORCE_INLINE const Ptr<C>& operator = (C &src)
  21.922 +    {       
  21.923 +        if (pObject) pObject->Release();        
  21.924 +        pObject = &src;
  21.925 +        return *this;
  21.926 +    }
  21.927 +    OVR_FORCE_INLINE Ptr<C>& operator = (Pickable<C> src)
  21.928 +    {
  21.929 +        return Pick(src);
  21.930 +    }
  21.931 +    template<class R>
  21.932 +    OVR_FORCE_INLINE Ptr<C>& operator = (Pickable<R> src)
  21.933 +    {
  21.934 +        return Pick(src);
  21.935 +    }
  21.936 +    
  21.937 +    // Set Assignment
  21.938 +    template<class R>
  21.939 +    OVR_FORCE_INLINE Ptr<C>& SetPtr(const Ptr<R> &src)
  21.940 +    {
  21.941 +        if (src) src->AddRef();
  21.942 +        if (pObject) pObject->Release();
  21.943 +        pObject = src;
  21.944 +        return *this;
  21.945 +    }
  21.946 +    // Specialization
  21.947 +    OVR_FORCE_INLINE Ptr<C>& SetPtr(const Ptr<C> &src)
  21.948 +    {
  21.949 +        if (src) src->AddRef();
  21.950 +        if (pObject) pObject->Release();
  21.951 +        pObject = src;
  21.952 +        return *this;
  21.953 +    }   
  21.954 +    
  21.955 +    OVR_FORCE_INLINE Ptr<C>& SetPtr(C *psrc)
  21.956 +    {
  21.957 +        if (psrc) psrc->AddRef();
  21.958 +        if (pObject) pObject->Release();
  21.959 +        pObject = psrc;
  21.960 +        return *this;
  21.961 +    }   
  21.962 +    OVR_FORCE_INLINE Ptr<C>& SetPtr(C &src)
  21.963 +    {       
  21.964 +        if (pObject) pObject->Release();
  21.965 +        pObject = &src;
  21.966 +        return *this;
  21.967 +    }
  21.968 +    OVR_FORCE_INLINE Ptr<C>& SetPtr(Pickable<C> src)
  21.969 +    {       
  21.970 +        return Pick(src);
  21.971 +    }
  21.972 +
  21.973 +    // Nulls ref-counted pointer without decrement
  21.974 +    OVR_FORCE_INLINE void    NullWithoutRelease()    
  21.975 +    { 
  21.976 +        pObject = 0;    
  21.977 +    }
  21.978 +
  21.979 +    // Clears the pointer to the object
  21.980 +    OVR_FORCE_INLINE void    Clear()
  21.981 +    {
  21.982 +        if (pObject) pObject->Release();
  21.983 +        pObject = 0;
  21.984 +    }
  21.985 +
  21.986 +    // Obtain pointer reference directly, for D3D interfaces
  21.987 +    OVR_FORCE_INLINE C*& GetRawRef()                 { return pObject; }
  21.988 +
  21.989 +    // Access Operators
  21.990 +    OVR_FORCE_INLINE C* GetPtr() const               { return pObject; }
  21.991 +    OVR_FORCE_INLINE C& operator * () const          { return *pObject; }
  21.992 +    OVR_FORCE_INLINE C* operator -> ()  const        { return pObject; }
  21.993 +    // Conversion                   
  21.994 +    OVR_FORCE_INLINE operator C* () const            { return pObject; }
  21.995 +
  21.996 +    // Pickers.
  21.997 +
  21.998 +    // Pick a value.
  21.999 +    OVR_FORCE_INLINE Ptr<C>& Pick(Ptr<C>& other)
 21.1000 +    {
 21.1001 +        if (&other != this)
 21.1002 +        {
 21.1003 +            if (pObject) pObject->Release();
 21.1004 +            pObject = other.pObject;
 21.1005 +            other.pObject = 0;
 21.1006 +        }
 21.1007 +
 21.1008 +        return *this;
 21.1009 +    }
 21.1010 +
 21.1011 +    OVR_FORCE_INLINE Ptr<C>& Pick(Pickable<C> v)
 21.1012 +    {
 21.1013 +        if (v.GetPtr() != pObject)
 21.1014 +        {
 21.1015 +            if (pObject) pObject->Release();
 21.1016 +            pObject = v.GetPtr();
 21.1017 +        }
 21.1018 +
 21.1019 +        return *this;
 21.1020 +    }
 21.1021 +
 21.1022 +    template<class R>
 21.1023 +    OVR_FORCE_INLINE Ptr<C>& Pick(Pickable<R> v)
 21.1024 +    {
 21.1025 +        if (v.GetPtr() != pObject)
 21.1026 +        {
 21.1027 +            if (pObject) pObject->Release();
 21.1028 +            pObject = v.GetPtr();
 21.1029 +        }
 21.1030 +
 21.1031 +        return *this;
 21.1032 +    }
 21.1033 +
 21.1034 +    OVR_FORCE_INLINE Ptr<C>& Pick(C* p)
 21.1035 +    {
 21.1036 +        if (p != pObject)
 21.1037 +        {
 21.1038 +            if (pObject) pObject->Release();
 21.1039 +            pObject = p;
 21.1040 +        }
 21.1041 +
 21.1042 +        return *this;
 21.1043 +    }
 21.1044 +};
 21.1045 +
 21.1046 +} // OVR
 21.1047 +
 21.1048 +#endif
    22.1 --- a/libovr/Src/Kernel/OVR_Std.cpp	Sat Sep 14 17:51:03 2013 +0300
    22.2 +++ b/libovr/Src/Kernel/OVR_Std.cpp	Sun Sep 15 04:10:05 2013 +0300
    22.3 @@ -1,1 +1,1025 @@
    22.4 -/************************************************************************************
    22.5 
    22.6 Filename    :   OVR_Std.cpp
    22.7 Content     :   Standard C function implementation
    22.8 Created     :   September 19, 2012
    22.9 Notes       : 
   22.10 
   22.11 Copyright   :   Copyright 2012 Oculus VR, Inc. All Rights reserved.
   22.12 
   22.13 Use of this software is subject to the terms of the Oculus license
   22.14 agreement provided at the time of installation or download, or which
   22.15 otherwise accompanies this software in either electronic or hard copy form.
   22.16 
   22.17 ************************************************************************************/
   22.18 
   22.19 #include "OVR_Std.h"
   22.20 #include "OVR_Alg.h"
   22.21 
   22.22 // localeconv() call in OVR_strtod()
   22.23 #include <locale.h>
   22.24 
   22.25 namespace OVR {
   22.26 
   22.27 // Source for functions not available on all platforms is included here.
   22.28 
   22.29 // Case insensitive compare implemented in platform-specific way.
   22.30 int OVR_CDECL OVR_stricmp(const char* a, const char* b)
   22.31 {
   22.32 #if defined(OVR_OS_WIN32)
   22.33     #if defined(OVR_CC_MSVC) && (OVR_CC_MSVC >= 1400)
   22.34         return ::_stricmp(a, b);
   22.35     #else
   22.36         return ::stricmp(a, b);
   22.37     #endif
   22.38 
   22.39 #else
   22.40     return strcasecmp(a, b);
   22.41 #endif
   22.42 }
   22.43 
   22.44 int OVR_CDECL OVR_strnicmp(const char* a, const char* b, UPInt count)
   22.45 {
   22.46 #if defined(OVR_OS_WIN32)
   22.47 #if defined(OVR_CC_MSVC) && (OVR_CC_MSVC >= 1400)
   22.48     return ::_strnicmp(a, b, count);
   22.49 #else
   22.50     return ::strnicmp(a, b, count);
   22.51 #endif
   22.52 
   22.53 #else
   22.54     return strncasecmp(a, b, count);
   22.55 #endif
   22.56 }
   22.57 
   22.58 wchar_t* OVR_CDECL OVR_wcscpy(wchar_t* dest, UPInt destsize, const wchar_t* src)
   22.59 {
   22.60 #if defined(OVR_MSVC_SAFESTRING)
   22.61     wcscpy_s(dest, destsize, src);
   22.62     return dest;
   22.63 #elif defined(OVR_OS_WIN32)
   22.64     OVR_UNUSED(destsize);
   22.65     wcscpy(dest, src);
   22.66     return dest;
   22.67 #else
   22.68     UPInt l = OVR_wcslen(src) + 1; // incl term null
   22.69     l = (l < destsize) ? l : destsize;
   22.70     memcpy(dest, src, l * sizeof(wchar_t));
   22.71     return dest;
   22.72 #endif
   22.73 }
   22.74 
   22.75 wchar_t* OVR_CDECL OVR_wcsncpy(wchar_t* dest, UPInt destsize, const wchar_t* src, UPInt count)
   22.76 {
   22.77 #if defined(OVR_MSVC_SAFESTRING)
   22.78     wcsncpy_s(dest, destsize, src, count);
   22.79     return dest;
   22.80 #else
   22.81     UPInt srclen = OVR_wcslen(src);
   22.82     UPInt l = Alg::Min(srclen, count);
   22.83     l = (l < destsize) ? l : destsize;
   22.84     memcpy(dest, src, l * sizeof(wchar_t));
   22.85     if (count > srclen)
   22.86     {
   22.87         UPInt remLen = Alg::Min(destsize - l, (count - srclen));
   22.88         memset(&dest[l], 0, sizeof(wchar_t)*remLen);
   22.89     }
   22.90     else if (l < destsize)
   22.91         dest[l] = 0;
   22.92     return dest;
   22.93 #endif
   22.94 }
   22.95 
   22.96 
   22.97 wchar_t* OVR_CDECL OVR_wcscat(wchar_t* dest, UPInt destsize, const wchar_t* src)
   22.98 {
   22.99 #if defined(OVR_MSVC_SAFESTRING)
  22.100     wcscat_s(dest, destsize, src);
  22.101     return dest;
  22.102 #elif defined(OVR_OS_WIN32)
  22.103     OVR_UNUSED(destsize);
  22.104     wcscat(dest, src);
  22.105     return dest;
  22.106 #else
  22.107     UPInt dstlen = OVR_wcslen(dest); // do not incl term null
  22.108     UPInt srclen = OVR_wcslen(src) + 1; // incl term null
  22.109     UPInt copylen = (dstlen + srclen < destsize) ? srclen : destsize - dstlen;
  22.110     memcpy(dest + dstlen, src, copylen * sizeof(wchar_t));
  22.111     return dest;
  22.112 #endif
  22.113 }
  22.114 
  22.115 UPInt   OVR_CDECL OVR_wcslen(const wchar_t* str)
  22.116 {
  22.117 #if defined(OVR_OS_WIN32)
  22.118     return wcslen(str);
  22.119 #else
  22.120     UPInt i = 0;
  22.121     while(str[i] != '\0')
  22.122         ++i;
  22.123     return i;
  22.124 #endif
  22.125 }
  22.126 
  22.127 int OVR_CDECL OVR_wcscmp(const wchar_t* a, const wchar_t* b)
  22.128 {
  22.129 #if defined(OVR_OS_WIN32) || defined(OVR_OS_LINUX)
  22.130     return wcscmp(a, b);
  22.131 #else
  22.132     // not supported, use custom implementation
  22.133     const wchar_t *pa = a, *pb = b;
  22.134     while (*pa && *pb)
  22.135     {
  22.136         wchar_t ca = *pa;
  22.137         wchar_t cb = *pb;
  22.138         if (ca < cb)
  22.139             return -1;
  22.140         else if (ca > cb)
  22.141             return 1;
  22.142         pa++;
  22.143         pb++;
  22.144     }
  22.145     if (*pa)
  22.146         return 1;
  22.147     else if (*pb)
  22.148         return -1;
  22.149     else
  22.150         return 0;
  22.151 #endif
  22.152 }
  22.153 
  22.154 int OVR_CDECL OVR_wcsicmp(const wchar_t* a, const wchar_t* b)
  22.155 {
  22.156 #if defined(OVR_OS_WIN32)
  22.157 #if defined(OVR_CC_MSVC) && (OVR_CC_MSVC >= 1400)
  22.158     return ::_wcsicmp(a, b);
  22.159 #else
  22.160     return ::wcsicmp(a, b);
  22.161 #endif
  22.162 #elif defined(OVR_OS_MAC) || defined(__CYGWIN__) || defined(OVR_OS_ANDROID) || defined(OVR_OS_IPHONE)
  22.163     // not supported, use custom implementation
  22.164     const wchar_t *pa = a, *pb = b;
  22.165     while (*pa && *pb)
  22.166     {
  22.167         wchar_t ca = OVR_towlower(*pa);
  22.168         wchar_t cb = OVR_towlower(*pb);
  22.169         if (ca < cb)
  22.170             return -1;
  22.171         else if (ca > cb)
  22.172             return 1;
  22.173         pa++;
  22.174         pb++;
  22.175     }
  22.176     if (*pa)
  22.177         return 1;
  22.178     else if (*pb)
  22.179         return -1;
  22.180     else
  22.181         return 0;
  22.182 #else
  22.183     return wcscasecmp(a, b);
  22.184 #endif
  22.185 }
  22.186 
  22.187 // This function is not inline because of dependency on <locale.h>
  22.188 double OVR_CDECL OVR_strtod(const char* string, char** tailptr)
  22.189 {
  22.190 #if !defined(OVR_OS_ANDROID)
  22.191     const char s = *localeconv()->decimal_point;
  22.192 
  22.193     if (s != '.')
  22.194     {
  22.195         char buffer[347 + 1];
  22.196 
  22.197         OVR_strcpy(buffer, sizeof(buffer), string);
  22.198 
  22.199         for (char* c = buffer; *c != '\0'; ++c)
  22.200         {
  22.201             if (*c == '.')
  22.202             {
  22.203                 *c = s;
  22.204                 break;
  22.205             }
  22.206         }
  22.207 
  22.208         return strtod(buffer, tailptr);
  22.209     }
  22.210 #endif
  22.211 
  22.212     return strtod(string, tailptr);
  22.213 }
  22.214 
  22.215 
  22.216 #ifndef OVR_NO_WCTYPE
  22.217 
  22.218 //// Use this class to generate Unicode bitsets. For example:
  22.219 ////
  22.220 //// UnicodeBitSet bitSet;
  22.221 //// for(unsigned i = 0; i < 65536; ++i)
  22.222 //// {
  22.223 ////     if (iswalpha(i))
  22.224 ////         bitSet.Set(i);
  22.225 //// }
  22.226 //// bitSet.Dump();
  22.227 ////
  22.228 ////---------------------------------------------------------------
  22.229 //class UnicodeBitSet
  22.230 //{
  22.231 //public:
  22.232 //    UnicodeBitSet()
  22.233 //    {
  22.234 //        memset(Offsets, 0, sizeof(Offsets));
  22.235 //        memset(Bits,    0, sizeof(Bits));
  22.236 //    }
  22.237 //
  22.238 //    void Set(unsigned bit) { Bits[bit >> 8][(bit >> 4) & 15] |= 1 << (bit & 15); }
  22.239 //
  22.240 //    void Dump()
  22.241 //    {
  22.242 //        unsigned i, j;
  22.243 //        unsigned offsetCount = 0;
  22.244 //        for(i = 0; i < 256; ++i)
  22.245 //        {
  22.246 //            if (isNull(i)) Offsets[i] = 0;
  22.247 //            else
  22.248 //            if (isFull(i)) Offsets[i] = 1;
  22.249 //            else           Offsets[i] = UInt16(offsetCount++ * 16 + 256);
  22.250 //        }
  22.251 //        for(i = 0; i < 16; ++i)
  22.252 //        {
  22.253 //            for(j = 0; j < 16; ++j)
  22.254 //            {
  22.255 //                printf("%5u,", Offsets[i*16+j]);
  22.256 //            }
  22.257 //            printf("\n");
  22.258 //        }
  22.259 //        for(i = 0; i < 256; ++i)
  22.260 //        {
  22.261 //            if (Offsets[i] > 255)
  22.262 //            {
  22.263 //                for(j = 0; j < 16; j++)
  22.264 //                {
  22.265 //                    printf("%5u,", Bits[i][j]);
  22.266 //                }
  22.267 //                printf("\n");
  22.268 //            }
  22.269 //        }
  22.270 //    }
  22.271 //
  22.272 //private:
  22.273 //    bool isNull(unsigned n) const
  22.274 //    {
  22.275 //        const UInt16* p = Bits[n];
  22.276 //        for(unsigned i = 0; i < 16; ++i)
  22.277 //            if (p[i] != 0) return false;
  22.278 //        return true;
  22.279 //    }
  22.280 //
  22.281 //    bool isFull(unsigned n) const
  22.282 //    {
  22.283 //        const UInt16* p = Bits[n];
  22.284 //        for(unsigned i = 0; i < 16; ++i)
  22.285 //            if (p[i] != 0xFFFF) return false;
  22.286 //        return true;
  22.287 //    }
  22.288 //
  22.289 //    UInt16 Offsets[256];
  22.290 //    UInt16 Bits[256][16];
  22.291 //};
  22.292 
  22.293 
  22.294 const UInt16 UnicodeAlnumBits[] = {
  22.295   256,    1,  272,  288,  304,  320,  336,  352,    0,  368,  384,  400,  416,  432,  448,  464,
  22.296   480,  496,  512,  528,  544,    1,  560,  576,  592,    0,    0,    0,    0,    0,  608,  624,
  22.297   640,  656,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  22.298   672,  688,    0,    0,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
  22.299     1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,  704,    1,    1,
  22.300     1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
  22.301     1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
  22.302     1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
  22.303     1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
  22.304     1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,  720,
  22.305     1,    1,    1,    1,  736,    0,    0,    0,    0,    0,    0,    0,    1,    1,    1,    1,
  22.306     1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
  22.307     1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
  22.308     1,    1,    1,    1,    1,    1,    1,  752,    0,    0,    0,    0,    0,    0,    0,    0,
  22.309     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  22.310     0,    0,    0,    0,    0,    0,    0,    0,    0,    1,  768,  784,    1,  800,  816,  832,
  22.311     0,    0,    0, 1023,65534, 2047,65534, 2047,    0,    0,    0,  524,65535,65407,65535,65407,
  22.312 65535,65535,65532,   15,    0,65535,65535,65535,65535,65535,16383,63999,    3,    0,16415,    0,
  22.313     0,    0,    0,    0,   32,    0,    0, 1024,55104,65535,65531,65535,32767,64767,65535,   15,
  22.314 65535,65535,65535,65535,65535,65535,65535,65535,61443,65535,65535,65535, 6559,65535,65535,  831,
  22.315     0,    0,    0,65534,65535,  639,65534,65535,  255,    0,    0,    0,    0,65535, 2047,    7,
  22.316     0,    0,65534, 2047,65534,   63, 1023,65535,65535,65535,65535,65535,65535, 8175, 8702, 8191,
  22.317     0,65535, 8191,65535,    0,    0,    0,    0,65535,65535,65535,    1,    0,    0,    0,    0,
  22.318 65518,65535,65535,58367, 8191,65281,65487,    0,40942,65529,65023,50117, 6559,45184,65487,    3,
  22.319 34788,65529,65023,50029, 6535,24064,65472,   31,45038,65531,65023,58349, 7103,    1,65473,    0,
  22.320 40942,65529,65023,58317, 6543,45248,65475,    0,51180,54845,50968,50111, 7623,  128,65408,    0,
  22.321 57326,65533,65023,50159, 7647,   96,65475,    0,57324,65533,65023,50159, 7647,16480,65475,    0,
  22.322 57324,65533,65023,50175, 7631,  128,65475,    0,65516,64639,65535,12283,32895,65375,    0,   12,
  22.323 65534,65535,65535, 2047,32767, 1023,    0,    0, 9622,65264,60590,15359, 8223,13311,    0,    0,
  22.324     1,    0, 1023,    0,65279,65535, 2047,65534, 3843,65279,65535, 8191,    0,    0,    0,    0,
  22.325 65535,65535,63227,  327, 1023, 1023,    0,    0,    0,    0,65535,65535,   63,65535,65535,  127,
  22.326 65535,65535,65535,65535,65535,33791,65535,65535,65535,65535,65287,65535,65535,65535,65535, 1023,
  22.327 65407,65535,65535,65535,15743,15743,65535,65535,15743,65535,32767,32573,32573,65407,32767,65535,
  22.328 32767,32573,65535,65535,65407, 2047,65024,    3,    0,    0,65535,65535,65535,65535,65535,   31,
  22.329 65534,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,
  22.330 65535,65535,65535,65535,65535,65535,40959,  127,65534, 2047,65535,65535,65535,65535, 2047,    0,
  22.331     0,    0,    0,    0,    0,    0,    0,    0,65535,65535,65535,65535,  511,    0, 1023,    0,
  22.332     0, 1023,65535,65535,65527,65535,65535,  255,65535,65535, 1023,    0,    0,    0,    0,    0,
  22.333 65535,65535,65535,65535,65535,65535,65535,65535,65535, 4095,65535,65535,65535,65535,65535, 1023,
  22.334 65535,16191,65535,65535,16191,43775,65535,16383,65535,65535,65535,24543, 8156, 4047, 8191, 8156,
  22.335     0,    0,    0,    0,    0,    0,    0,32768,    0,    0,    0,    0,    0,    0,    0,    0,
  22.336 64644,15919,48464, 1019,    0,    0,65535,65535,   15,    0,    0,    0,    0,    0,    0,    0,
  22.337   192,    0, 1022, 1792,65534,65535,65535,65535,65535,   31,65534,65535,65535,65535,65535, 2047,
  22.338 65504,65535, 8191,65534,65535,65535,65535,65535,32767,    0,65535,  255,    0,    0,    0,    0,
  22.339 65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,   63,    0,    0,    0,    0,
  22.340 65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,   63,    0,    0,    0,    0,    0,
  22.341 65535,65535,65535,65535,65535,65535,65535,65535, 8191,    0,    0,    0,    0,    0,    0,    0,
  22.342 65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,   15,    0,    0,    0,    0,    0,
  22.343 65535,65535,16383,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  22.344   127,41208,65023,24447,65499,65535,65535,65535,65535,65535,65535,    3,    0,65528,65535,65535,
  22.345 65535,65535,65535,16383,    0,65535,65535,65535,65535,65532,65535,65535,  255,    0,    0, 4095,
  22.346     0,    0,    0,    0,    0,    0,    0,65495,65535,65535,65535,65535,65535,65535,65535, 8191,
  22.347     0, 1023,65534, 2047,65534, 2047,65472,65534,65535,16383,65535,32767,64764, 7420,    0,    0};
  22.348 
  22.349 const UInt16 UnicodeAlphaBits[] = {
  22.350   256,    1,  272,  288,  304,  320,  336,  352,    0,  368,  384,  400,  416,  432,  448,  464,
  22.351   480,  496,  512,  528,  544,    1,  560,  576,  592,    0,    0,    0,    0,    0,  608,  624,
  22.352   640,  656,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  22.353   672,  688,    0,    0,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
  22.354     1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,  704,    1,    1,
  22.355     1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
  22.356     1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
  22.357     1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
  22.358     1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
  22.359     1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,  720,
  22.360     1,    1,    1,    1,  736,    0,    0,    0,    0,    0,    0,    0,    1,    1,    1,    1,
  22.361     1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
  22.362     1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
  22.363     1,    1,    1,    1,    1,    1,    1,  752,    0,    0,    0,    0,    0,    0,    0,    0,
  22.364     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  22.365     0,    0,    0,    0,    0,    0,    0,    0,    0,    1,  768,  784,    1,  800,  816,  832,
  22.366     0,    0,    0,    0,65534, 2047,65534, 2047,    0,    0,    0,    0,65535,65407,65535,65407,
  22.367 65535,65535,65532,   15,    0,65535,65535,65535,65535,65535,16383,63999,    3,    0,16415,    0,
  22.368     0,    0,    0,    0,   32,    0,    0, 1024,55104,65535,65531,65535,32767,64767,65535,   15,
  22.369 65535,65535,65535,65535,65535,65535,65535,65535,61443,65535,65535,65535, 6559,65535,65535,  831,
  22.370     0,    0,    0,65534,65535,  639,65534,65535,  255,    0,    0,    0,    0,65535, 2047,    7,
  22.371     0,    0,65534, 2047,65534,   63,    0,65535,65535,65535,65535,65535,65535, 8175, 8702, 7168,
  22.372     0,65535, 8191,65535,    0,    0,    0,    0,65535,65535,65535,    1,    0,    0,    0,    0,
  22.373 65518,65535,65535,58367, 8191,65281,   15,    0,40942,65529,65023,50117, 6559,45184,   15,    3,
  22.374 34788,65529,65023,50029, 6535,24064,    0,   31,45038,65531,65023,58349, 7103,    1,    1,    0,
  22.375 40942,65529,65023,58317, 6543,45248,    3,    0,51180,54845,50968,50111, 7623,  128,    0,    0,
  22.376 57326,65533,65023,50159, 7647,   96,    3,    0,57324,65533,65023,50159, 7647,16480,    3,    0,
  22.377 57324,65533,65023,50175, 7631,  128,    3,    0,65516,64639,65535,12283,32895,65375,    0,   12,
  22.378 65534,65535,65535, 2047,32767,    0,    0,    0, 9622,65264,60590,15359, 8223,12288,    0,    0,
  22.379     1,    0,    0,    0,65279,65535, 2047,65534, 3843,65279,65535, 8191,    0,    0,    0,    0,
  22.380 65535,65535,63227,  327,    0, 1023,    0,    0,    0,    0,65535,65535,   63,65535,65535,  127,
  22.381 65535,65535,65535,65535,65535,33791,65535,65535,65535,65535,65287,65535,65535,65535,65535, 1023,
  22.382 65407,65535,65535,65535,15743,15743,65535,65535,15743,65535,32767,32573,32573,65407,32767,65535,
  22.383 32767,32573,65535,65535,65407, 2047,    0,    0,    0,    0,65535,65535,65535,65535,65535,   31,
  22.384 65534,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,
  22.385 65535,65535,65535,65535,65535,65535,40959,  127,65534, 2047,65535,65535,65535,65535, 2047,    0,
  22.386     0,    0,    0,    0,    0,    0,    0,    0,65535,65535,65535,65535,  511,    0,    0,    0,
  22.387     0,    0,65535,65535,65527,65535,65535,  255,65535,65535, 1023,    0,    0,    0,    0,    0,
  22.388 65535,65535,65535,65535,65535,65535,65535,65535,65535, 4095,65535,65535,65535,65535,65535, 1023,
  22.389 65535,16191,65535,65535,16191,43775,65535,16383,65535,65535,65535,24543, 8156, 4047, 8191, 8156,
  22.390     0,    0,    0,    0,    0,    0,    0,32768,    0,    0,    0,    0,    0,    0,    0,    0,
  22.391 64644,15919,48464, 1019,    0,    0,65535,65535,   15,    0,    0,    0,    0,    0,    0,    0,
  22.392   192,    0, 1022, 1792,65534,65535,65535,65535,65535,   31,65534,65535,65535,65535,65535, 2047,
  22.393 65504,65535, 8191,65534,65535,65535,65535,65535,32767,    0,65535,  255,    0,    0,    0,    0,
  22.394 65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,   63,    0,    0,    0,    0,
  22.395 65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,   63,    0,    0,    0,    0,    0,
  22.396 65535,65535,65535,65535,65535,65535,65535,65535, 8191,    0,    0,    0,    0,    0,    0,    0,
  22.397 65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,   15,    0,    0,    0,    0,    0,
  22.398 65535,65535,16383,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  22.399   127,41208,65023,24447,65499,65535,65535,65535,65535,65535,65535,    3,    0,65528,65535,65535,
  22.400 65535,65535,65535,16383,    0,65535,65535,65535,65535,65532,65535,65535,  255,    0,    0, 4095,
  22.401     0,    0,    0,    0,    0,    0,    0,65495,65535,65535,65535,65535,65535,65535,65535, 8191,
  22.402     0,    0,65534, 2047,65534, 2047,65472,65534,65535,16383,65535,32767,64764, 7420,    0,    0};
  22.403 
  22.404 const UInt16 UnicodeDigitBits[] = {
  22.405   256,    0,    0,    0,    0,    0,  272,    0,    0,  288,  304,  320,  336,  352,  368,  384,
  22.406   400,    0,    0,  416,    0,    0,    0,  432,  448,    0,    0,    0,    0,    0,    0,    0,
  22.407     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  22.408     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  22.409     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  22.410     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  22.411     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  22.412     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  22.413     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  22.414     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  22.415     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  22.416     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  22.417     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  22.418     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  22.419     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  22.420     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,  464,
  22.421     0,    0,    0, 1023,    0,    0,    0,    0,    0,    0,    0,  524,    0,    0,    0,    0,
  22.422     0,    0,    0,    0,    0,    0, 1023,    0,    0,    0,    0,    0,    0,    0,    0, 1023,
  22.423     0,    0,    0,    0,    0,    0,65472,    0,    0,    0,    0,    0,    0,    0,65472,    0,
  22.424     0,    0,    0,    0,    0,    0,65472,    0,    0,    0,    0,    0,    0,    0,65472,    0,
  22.425     0,    0,    0,    0,    0,    0,65472,    0,    0,    0,    0,    0,    0,    0,65408,    0,
  22.426     0,    0,    0,    0,    0,    0,65472,    0,    0,    0,    0,    0,    0,    0,65472,    0,
  22.427     0,    0,    0,    0,    0,    0,65472,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  22.428     0,    0,    0,    0,    0, 1023,    0,    0,    0,    0,    0,    0,    0, 1023,    0,    0,
  22.429     0,    0, 1023,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  22.430     0,    0,    0,    0, 1023,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  22.431     0,    0,    0,    0,    0,    0,65024,    3,    0,    0,    0,    0,    0,    0,    0,    0,
  22.432     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0, 1023,    0,
  22.433     0, 1023,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  22.434     0, 1023,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0};
  22.435 
  22.436 const UInt16 UnicodeSpaceBits[] = {
  22.437   256,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  22.438     0,    0,    0,    0,    0,    0,  272,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  22.439   288,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  22.440   304,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  22.441     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  22.442     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  22.443     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  22.444     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  22.445     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  22.446     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  22.447     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  22.448     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  22.449     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  22.450     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  22.451     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  22.452     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  22.453 15872,    0,    1,    0,    0,    0,    0,    0,    0,    0,    1,    0,    0,    0,    0,    0,
  22.454     0,    0,    0,    0,    0,    0,    0,    0,    1,    0,    0,    0,    0,    0,    0,    0,
  22.455  4095,    0,33536,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  22.456     1,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0};
  22.457 
  22.458 const UInt16 UnicodeXDigitBits[] = {
  22.459   256,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  22.460     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  22.461     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  22.462     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  22.463     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  22.464     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  22.465     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  22.466     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  22.467     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  22.468     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  22.469     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  22.470     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  22.471     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  22.472     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  22.473     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  22.474     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,  272,
  22.475     0,    0,    0, 1023,  126,    0,  126,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  22.476     0, 1023,  126,    0,  126,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0};
  22.477 
  22.478 // Uncomment if necessary
  22.479 //const UInt16 UnicodeCntrlBits[] = {
  22.480 //  256,    0,    0,    0,    0,    0,    0,  272,    0,    0,    0,    0,    0,    0,    0,    0,
  22.481 //    0,    0,    0,    0,    0,    0,    0,    0,  288,    0,    0,    0,    0,    0,    0,    0,
  22.482 //  304,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  22.483 //    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  22.484 //    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  22.485 //    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  22.486 //    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  22.487 //    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  22.488 //    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  22.489 //    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  22.490 //    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  22.491 //    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  22.492 //    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  22.493 //    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  22.494 //    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  22.495 //    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,  320,  336,
  22.496 //65535,65535,    0,    0,    0,    0,    0,32768,65535,65535,    0,    0,    0,    0,    0,    0,
  22.497 //32768,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  22.498 //30720,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  22.499 //61440,    0,31744,    0,    0,    0,64512,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  22.500 //    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,32768,
  22.501 //    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0, 3584};
  22.502 //
  22.503 //const UInt16 UnicodeGraphBits[] = {
  22.504 //  256,    1,  272,  288,  304,  320,  336,  352,    0,  368,  384,  400,  416,  432,  448,  464,
  22.505 //  480,  496,  512,  528,  544,    1,  560,  576,  592,    0,    0,    0,    0,    0,  608,  624,
  22.506 //  640,  656,    0,  672,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  22.507 //  688,  704,    0,    0,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
  22.508 //    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,  720,    1,    1,
  22.509 //    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
  22.510 //    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
  22.511 //    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
  22.512 //    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
  22.513 //    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,  736,
  22.514 //    1,    1,    1,    1,  752,    0,    0,    0,    0,    0,    0,    0,    1,    1,    1,    1,
  22.515 //    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
  22.516 //    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
  22.517 //    1,    1,    1,    1,    1,    1,    1,  768,    0,    0,    0,    0,    0,    0,    0,    0,
  22.518 //    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  22.519 //    0,    0,    0,    0,    0,    0,    0,    0,    0,    1,  784,  800,    1,  816,  832,  848,
  22.520 //    0,    0,65534,65535,65535,65535,65535,32767,    0,    0,65534,65535,65535,65535,65535,65535,
  22.521 //65535,65535,65532,   15,    0,65535,65535,65535,65535,65535,16383,63999,    3,    0,16415,    0,
  22.522 //    0,    0,    0,    0,   32,    0,    0,17408,55232,65535,65531,65535,32767,64767,65535,   15,
  22.523 //65535,65535,65535,65535,65535,65535,65535,65535,61443,65535,65535,65535, 6559,65535,65535,  831,
  22.524 //    0,    0,    0,65534,65535,65151,65534,65535, 1791,    0,    0,16384,    9,65535, 2047,   31,
  22.525 // 4096,34816,65534, 2047,65534,   63,16383,65535,65535,65535,65535,65535,65535, 8191, 8702, 8191,
  22.526 //16383,65535, 8191,65535,    0,    0,    0,    0,65535,65535,65535,    1,    0,    0,    0,    0,
  22.527 //65518,65535,65535,58367, 8191,65281,65535,    1,40942,65529,65023,50117, 6559,45184,65487,    3,
  22.528 //34788,65529,65023,50029, 6535,24064,65472,   31,45038,65531,65023,58349, 7103,    1,65473,    0,
  22.529 //40942,65529,65023,58317, 6543,45248,65475,    0,51180,54845,50968,50111, 7623,  128,65408,    0,
  22.530 //57326,65533,65023,50159, 7647,   96,65475,    0,57324,65533,65023,50159, 7647,16480,65475,    0,
  22.531 //57324,65533,65023,50175, 7631,  128,65475,    0,65516,64639,65535,12283,32895,65375,    0,   28,
  22.532 //65534,65535,65535, 2047,65535, 4095,    0,    0, 9622,65264,60590,15359, 8223,13311,    0,    0,
  22.533 //65521,    7, 1023,15360,65279,65535, 2047,65534, 3875,65279,65535, 8191,    0,    0,    0,    0,
  22.534 //65535,65535,63227,  327,65535, 1023,    0,    0,    0,    0,65535,65535,   63,65535,65535, 2175,
  22.535 //65535,65535,65535,65535,65535,33791,65535,65535,65535,65535,65287,65535,65535,65535,65535, 1023,
  22.536 //65407,65535,65535,65535,15743,15743,65535,65535,15743,65535,32767,32573,32573,65407,32767,65535,
  22.537 //32767,32573,65535,65535,65407, 2047,65534,    3,    0,    0,65535,65535,65535,65535,65535,   31,
  22.538 //65534,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,
  22.539 //65535,65535,65535,65535,65535,65535,65535,  127,65534, 8191,65535,65535,65535,65535,16383,    0,
  22.540 //    0,    0,    0,    0,    0,    0,    0,    0,65535,65535,65535,65535,  511, 6128, 1023,    0,
  22.541 // 2047, 1023,65535,65535,65527,65535,65535,  255,65535,65535, 1023,    0,    0,    0,    0,    0,
  22.542 //65535,65535,65535,65535,65535,65535,65535,65535,65535, 4095,65535,65535,65535,65535,65535, 1023,
  22.543 //65535,16191,65535,65535,16191,43775,65535,16383,65535,65535,65535,24543, 8156, 4047, 8191, 8156,
  22.544 //    0,65535,  255,65535,16239,    0,    0,57344,24576,    0,    0,    0,    0,    0,    0,    0,
  22.545 //64644,15919,48464, 1019,    0,    0,65535,65535,   15,    0,    0,    0,    0,    0,    0,    0,
  22.546 //    0,    0, 1536,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  22.547 //65486,65523, 1022, 1793,65534,65535,65535,65535,65535,   31,65534,65535,65535,65535,65535, 4095,
  22.548 //65504,65535, 8191,65534,65535,65535,65535,65535,32767,    0,65535,  255,    0,    0,    0,    0,
  22.549 //65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,   63,    0,    0,    0,    0,
  22.550 //65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,   63,    0,    0,    0,    0,    0,
  22.551 //65535,65535,65535,65535,65535,65535,65535,65535, 8191,    0,    0,    0,    0,    0,    0,    0,
  22.552 //65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,   15,    0,    0,    0,    0,    0,
  22.553 //65535,65535,16383,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  22.554 //  127,41208,65023,24447,65499,65535,65535,65535,65535,65535,65535,    3,    0,65528,65535,65535,
  22.555 //65535,65535,65535,65535,    0,65535,65535,65535,65535,65532,65535,65535,  255,    0,    0, 4095,
  22.556 //    0,    0,    0,65535,65055,65527, 3339,65495,65535,65535,65535,65535,65535,65535,65535, 8191,
  22.557 //63470,36863,65535,49151,65534,12287,65534,65534,65535,16383,65535,32767,64764, 7420,    0,    0};
  22.558 //
  22.559 //const UInt16 UnicodePrintBits[] = {
  22.560 //  256,    1,  272,  288,  304,  320,  336,  352,    0,  368,  384,  400,  416,  432,  448,  464,
  22.561 //  480,  496,  512,  528,  544,    1,  560,  576,  592,    0,    0,    0,    0,    0,  608,  624,
  22.562 //  640,  656,    0,  672,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  22.563 //  688,  704,    0,    0,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
  22.564 //    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,  720,    1,    1,
  22.565 //    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
  22.566 //    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
  22.567 //    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
  22.568 //    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
  22.569 //    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,  736,
  22.570 //    1,    1,    1,    1,  752,    0,    0,    0,    0,    0,    0,    0,    1,    1,    1,    1,
  22.571 //    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
  22.572 //    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
  22.573 //    1,    1,    1,    1,    1,    1,    1,  768,    0,    0,    0,    0,    0,    0,    0,    0,
  22.574 //    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  22.575 //    0,    0,    0,    0,    0,    0,    0,    0,    0,    1,  784,  800,    1,  816,  832,  848,
  22.576 //  512,    0,65535,65535,65535,65535,65535,32767,    0,    0,65535,65535,65535,65535,65535,65535,
  22.577 //65535,65535,65532,   15,    0,65535,65535,65535,65535,65535,16383,63999,    3,    0,16415,    0,
  22.578 //    0,    0,    0,    0,   32,    0,    0,17408,55232,65535,65531,65535,32767,64767,65535,   15,
  22.579 //65535,65535,65535,65535,65535,65535,65535,65535,61443,65535,65535,65535, 6559,65535,65535,  831,
  22.580 //    0,    0,    0,65534,65535,65151,65534,65535, 1791,    0,    0,16384,    9,65535, 2047,   31,
  22.581 // 4096,34816,65534, 2047,65534,   63,16383,65535,65535,65535,65535,65535,65535, 8191, 8702, 8191,
  22.582 //16383,65535, 8191,65535,    0,    0,    0,    0,65535,65535,65535,    1,    0,    0,    0,    0,
  22.583 //65518,65535,65535,58367, 8191,65281,65535,    1,40942,65529,65023,50117, 6559,45184,65487,    3,
  22.584 //34788,65529,65023,50029, 6535,24064,65472,   31,45038,65531,65023,58349, 7103,    1,65473,    0,
  22.585 //40942,65529,65023,58317, 6543,45248,65475,    0,51180,54845,50968,50111, 7623,  128,65408,    0,
  22.586 //57326,65533,65023,50159, 7647,   96,65475,    0,57324,65533,65023,50159, 7647,16480,65475,    0,
  22.587 //57324,65533,65023,50175, 7631,  128,65475,    0,65516,64639,65535,12283,32895,65375,    0,   28,
  22.588 //65534,65535,65535, 2047,65535, 4095,    0,    0, 9622,65264,60590,15359, 8223,13311,    0,    0,
  22.589 //65521,    7, 1023,15360,65279,65535, 2047,65534, 3875,65279,65535, 8191,    0,    0,    0,    0,
  22.590 //65535,65535,63227,  327,65535, 1023,    0,    0,    0,    0,65535,65535,   63,65535,65535, 2175,
  22.591 //65535,65535,65535,65535,65535,33791,65535,65535,65535,65535,65287,65535,65535,65535,65535, 1023,
  22.592 //65407,65535,65535,65535,15743,15743,65535,65535,15743,65535,32767,32573,32573,65407,32767,65535,
  22.593 //32767,32573,65535,65535,65407, 2047,65534,    3,    0,    0,65535,65535,65535,65535,65535,   31,
  22.594 //65534,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,
  22.595 //65535,65535,65535,65535,65535,65535,65535,  127,65534, 8191,65535,65535,65535,65535,16383,    0,
  22.596 //    0,    0,    0,    0,    0,    0,    0,    0,65535,65535,65535,65535,  511, 6128, 1023,    0,
  22.597 // 2047, 1023,65535,65535,65527,65535,65535,  255,65535,65535, 1023,    0,    0,    0,    0,    0,
  22.598 //65535,65535,65535,65535,65535,65535,65535,65535,65535, 4095,65535,65535,65535,65535,65535, 1023,
  22.599 //65535,16191,65535,65535,16191,43775,65535,16383,65535,65535,65535,24543, 8156, 4047, 8191, 8156,
  22.600 //    0,65535,  255,65535,16239,    0,    0,57344,24576,    0,    0,    0,    0,    0,    0,    0,
  22.601 //64644,15919,48464, 1019,    0,    0,65535,65535,   15,    0,    0,    0,    0,    0,    0,    0,
  22.602 //    0,    0, 1536,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  22.603 //65487,65523, 1022, 1793,65534,65535,65535,65535,65535,   31,65534,65535,65535,65535,65535, 4095,
  22.604 //65504,65535, 8191,65534,65535,65535,65535,65535,32767,    0,65535,  255,    0,    0,    0,    0,
  22.605 //65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,   63,    0,    0,    0,    0,
  22.606 //65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,   63,    0,    0,    0,    0,    0,
  22.607 //65535,65535,65535,65535,65535,65535,65535,65535, 8191,    0,    0,    0,    0,    0,    0,    0,
  22.608 //65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,   15,    0,    0,    0,    0,    0,
  22.609 //65535,65535,16383,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  22.610 //  127,41208,65023,24447,65499,65535,65535,65535,65535,65535,65535,    3,    0,65528,65535,65535,
  22.611 //65535,65535,65535,65535,    0,65535,65535,65535,65535,65532,65535,65535,  255,    0,    0, 4095,
  22.612 //    0,    0,    0,65535,65055,65527, 3339,65495,65535,65535,65535,65535,65535,65535,65535,40959,
  22.613 //63470,36863,65535,49151,65534,12287,65534,65534,65535,16383,65535,32767,64764, 7420,    0,    0};
  22.614 //
  22.615 //const UInt16 UnicodePunctBits[] = {
  22.616 //  256,    0,    0,  272,    0,  288,  304,  320,    0,  336,    0,    0,    0,  352,  368,  384,
  22.617 //  400,    0,    0,  416,    0,    0,  432,  448,  464,    0,    0,    0,    0,    0,    0,    0,
  22.618 //  480,    0,    0,  496,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  22.619 //  512,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  22.620 //    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  22.621 //    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  22.622 //    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  22.623 //    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  22.624 //    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  22.625 //    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  22.626 //    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  22.627 //    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  22.628 //    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  22.629 //    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  22.630 //    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  22.631 //    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,  528,  544,  560,
  22.632 //    0,    0,65534,64512,    1,63488,    1,30720,    0,    0,65534,65535,    0,  128,    0,  128,
  22.633 //    0,    0,    0,    0,    0,    0,    0,16384,  128,    0,    0,    0,    0,    0,    0,    0,
  22.634 //    0,    0,    0,    0,    0,64512,    0,    0, 1536,    0,    0,16384,    9,    0,    0,   24,
  22.635 // 4096,34816,    0,    0,    0,    0,15360,    0,    0,    0,    0,    0,    0,   16,    0,    0,
  22.636 //16383,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  22.637 //    0,    0,    0,    0,    0,    0,   48,    1,    0,    0,    0,    0,    0,    0,    0,    0,
  22.638 //    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,   16,
  22.639 //    0,    0,    0,    0,32768, 3072,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  22.640 //65520,    7,    0,15360,    0,    0,    0,    0,   32,    0,    0,    0,    0,    0,    0,    0,
  22.641 //    0,    0,    0,    0,64512,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0, 2048,
  22.642 //    0,    0,    0,    0,    0,    0,  510,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  22.643 //    0,    0,    0,    0,    0,    0,24576,    0,    0, 6144,    0,    0,    0,    0,14336,    0,
  22.644 //    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0, 6128,    0,    0,
  22.645 // 2047,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  22.646 //    0,65535,  255,65535,16239,    0,    0,24576,24576,    0,    0,    0,    0,    0,    0,    0,
  22.647 //    0,    0, 1536,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  22.648 //65294,65523,    0,    1,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0, 2048,
  22.649 //    0,    0,    0,49152,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  22.650 //    0,    0,    0,65535,65055,65527, 3339,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  22.651 //63470,35840,    1,47104,    0,10240,   62,    0,    0,    0,    0,    0,    0,    0,    0,    0};
  22.652 //
  22.653 //const UInt16 UnicodeLowerBits[] = {
  22.654 //  256,  272,  288,  304,  320,  336,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  22.655 //    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,  352,  368,
  22.656 //  384,  400,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  22.657 //    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  22.658 //    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  22.659 //    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  22.660 //    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  22.661 //    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  22.662 //    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  22.663 //    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  22.664 //    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  22.665 //    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  22.666 //    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  22.667 //    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  22.668 //    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  22.669 //    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,  416,    0,    0,    0,  432,
  22.670 //    0,    0,    0,    0,    0,    0,65534, 2047,    0,    0,    0,    0,    0,32768,65535,65407,
  22.671 //43690,43690,43690,21930,43861,43690,43690,54442,12585,20004,11562,58961,23392,46421,43690,43565,
  22.672 //43690,43690,43688,   10,    0,65535,65535,65535,65535,65535,16383,    0,    0,    0,    0,    0,
  22.673 //    0,    0,    0,    0,    0,    0,    0,    0,    0,    1,61440,65535,32767,43235,43690,   15,
  22.674 //    0,    0,    0,65535,65535,65535,43690,43690,40962,43690,43690,43690, 4372,43690,43690,  554,
  22.675 //    0,    0,    0,    0,    0,    0,65534,65535,  255,    0,    0,    0,    0,    0,    0,    0,
  22.676 //43690,43690,43690,43690,43690,43690,43690,43690,43690, 4074,43690,43690,43690,43690,43690,  682,
  22.677 //  255,   63,  255,  255,   63,  255,  255,16383,65535,65535,65535,20703, 4316,  207,  255, 4316,
  22.678 //    0,    0,    0,    0,    0,    0,    0,32768,    0,    0,    0,    0,    0,    0,    0,    0,
  22.679 //50176,    8,32768,  528,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  22.680 //  127,  248,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  22.681 //    0,    0,    0,    0,65534, 2047,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0};
  22.682 //
  22.683 //const UInt16 UnicodeUpperBits[] = {
  22.684 //  256,  272,  288,  304,  320,  336,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  22.685 //  352,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,  368,  384,
  22.686 //    0,  400,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  22.687 //    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  22.688 //    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  22.689 //    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  22.690 //    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  22.691 //    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  22.692 //    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  22.693 //    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  22.694 //    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  22.695 //    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  22.696 //    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  22.697 //    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  22.698 //    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  22.699 //    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,  416,
  22.700 //    0,    0,    0,    0,65534, 2047,    0,    0,    0,    0,    0,    0,65535,32639,    0,    0,
  22.701 //21845,21845,21845,43605,21674,21845,21845,11093,52950,45531,53973, 4526,44464,19114,21845,21974,
  22.702 //21845,21845,21844,    5,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  22.703 //    0,    0,    0,    0,    0,    0,    0,    0,55104,65534, 4091,    0,    0,21532,21845,    0,
  22.704 //65535,65535,65535,    0,    0,    0,21845,21845,20481,21845,21845,21845, 2187,21845,21845,  277,
  22.705 //    0,    0,    0,65534,65535,  127,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  22.706 //    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,65535,65535,   63,    0,    0,    0,
  22.707 //21845,21845,21845,21845,21845,21845,21845,21845,21845,   21,21845,21845,21845,21845,21845,  341,
  22.708 //65280,16128,65280,65280,16128,43520,65280,    0,65280,65280,65280, 7936, 7936, 3840, 7936, 7936,
  22.709 //14468,15911,15696,   11,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  22.710 //    0,    0,65534, 2047,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0};
  22.711 
  22.712 
  22.713 // MA: March 19, 2010
  22.714 // Modified ToUpper and ToLower tables to match values expected by AS3 tests.
  22.715 // ToLower modifications:
  22.716 //    304 ->  105
  22.717 //   1024 -> 1104 *
  22.718 //   1037 -> 1117 * 
  22.719 // UoUpper modifications:
  22.720 //    255 ->  376
  22.721 //    305 ->   73
  22.722 //    383 ->   83
  22.723 //   1104 -> 1024 *
  22.724 //   1117 -> 1037 *
  22.725 // Entries marked with a '*' don't make complete sense based on Unicode manual, although
  22.726 // they match AS3.
  22.727 
  22.728 
  22.729 static const UInt16 UnicodeToUpperBits[] = {
  22.730   256,  272,  288,  304,  320,  336,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  22.731     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,  352,  368,
  22.732     0,  384,    0,    0,  400,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  22.733     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  22.734     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  22.735     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  22.736     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  22.737     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  22.738     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  22.739     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  22.740     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  22.741     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  22.742     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  22.743     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  22.744     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  22.745     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,  416,
  22.746     0,    0,    0,    0,    0,    0,65534, 2047,    0,    0,    0,    0,    0,    0,65535,65407,
  22.747 43690,43690,43690,21674,43349,43690,43690,54442, 4392,  516, 8490, 8785,21056,46421,43690,43048, // MA: Modified for AS3.
  22.748 43690,  170,    0,    0,    0, 2776,33545,   36, 3336,    4,    0,    0,    0,    0,    0,    0,
  22.749     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,61440,65534,32767,    0,43688,    0,
  22.750     0,    0,    0,65535,65535,65535,43690,43690,    2,43690,43690,43690, 4372,43690,35498,  554, // MA: Modified for AS3.
  22.751     0,    0,    0,    0,    0,    0,65534,65535,  127,    0,    0,    0,    0,    0,    0,    0,
  22.752 43690,43690,43690,43690,43690,43690,43690,43690,43690,   42,43690,43690,43690,43690,43690,  682,
  22.753   255,   63,  255,  255,   63,  170,  255,16383,    0,    0,    0,    3,    0,    3,   35,    0,
  22.754     0,    0,    0,    0,    0,    0,    0,65535,    0,    0,    0,    0,    0,    0,    0,    0,
  22.755     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,65535, 1023,    0,
  22.756     0,    0,    0,    0,65534, 2047,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0};
  22.757 
  22.758 static const UInt16 UnicodeToLowerBits[] = {
  22.759   256,  272,  288,  304,  320,  336,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  22.760   352,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,  368,  384,
  22.761     0,  400,    0,    0,  416,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  22.762     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  22.763     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  22.764     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  22.765     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  22.766     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  22.767     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  22.768     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  22.769     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  22.770     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  22.771     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  22.772     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  22.773     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  22.774     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,  432,
  22.775     0,    0,    0,    0,65534, 2047,    0,    0,    0,    0,    0,    0,65535,32639,    0,    0,
  22.776 21845,21845,21845,43605,21674,21845,21845,11093,52950,45531,53909, 4526,42128,19114,21845,21522,// MA: Modidied for AS3.
  22.777 21845,   85,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  22.778     0,    0,    0,    0,    0,    0,    0,    0,55104,65534, 4091,    0,    0,    0,21844,    0,
  22.779 65535,65535,65535,    0,    0,    0,21845,21845,    1,21845,21845,21845, 2186,21845,17749,  277,
  22.780     0,    0,    0,65534,65535,  127,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  22.781     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,65535,65535,   63,    0,    0,    0,
  22.782 21845,21845,21845,21845,21845,21845,21845,21845,21845,   21,21845,21845,21845,21845,21845,  341,
  22.783 65280,16128,65280,65280,16128,43520,65280,    0,    0,    0,    0, 3840, 3840, 3840, 7936, 3840,
  22.784     0,    0,    0,    0,    0,    0,65535,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  22.785     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,65472,65535,    0,    0,    0,
  22.786     0,    0,65534, 2047,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0};
  22.787 
  22.788 struct GUnicodePairType
  22.789 {
  22.790     UInt16 Key, Value;
  22.791 };
  22.792 
  22.793 static inline bool CmpUnicodeKey(const GUnicodePairType& a, UInt16 key)
  22.794 {
  22.795     return a.Key < key;
  22.796 }
  22.797 
  22.798 static const GUnicodePairType UnicodeToUpperTable[] = {
  22.799 {   97,   65}, {   98,   66}, {   99,   67}, {  100,   68}, {  101,   69}, {  102,   70}, {  103,   71},
  22.800 {  104,   72}, {  105,   73}, {  106,   74}, {  107,   75}, {  108,   76}, {  109,   77}, {  110,   78},
  22.801 {  111,   79}, {  112,   80}, {  113,   81}, {  114,   82}, {  115,   83}, {  116,   84}, {  117,   85},
  22.802 {  118,   86}, {  119,   87}, {  120,   88}, {  121,   89}, {  122,   90}, {  224,  192}, {  225,  193},
  22.803 {  226,  194}, {  227,  195}, {  228,  196}, {  229,  197}, {  230,  198}, {  231,  199}, {  232,  200},
  22.804 {  233,  201}, {  234,  202}, {  235,  203}, {  236,  204}, {  237,  205}, {  238,  206}, {  239,  207},
  22.805 {  240,  208}, {  241,  209}, {  242,  210}, {  243,  211}, {  244,  212}, {  245,  213}, {  246,  214},
  22.806 {  248,  216}, {  249,  217}, {  250,  218}, {  251,  219}, {  252,  220}, {  253,  221}, {  254,  222},
  22.807 {  255,  376}, {  257,  256}, {  259,  258}, {  261,  260}, {  263,  262}, {  265,  264}, {  267,  266},
  22.808 {  269,  268}, {  271,  270}, {  273,  272}, {  275,  274}, {  277,  276}, {  279,  278}, {  281,  280},
  22.809 {  283,  282}, {  285,  284}, {  287,  286}, {  289,  288}, {  291,  290}, {  293,  292}, {  295,  294},
  22.810 {  297,  296}, {  299,  298}, {  301,  300}, {  303,  302}, {  305,   73}, {  307,  306}, {  309,  308}, {  311,  310},
  22.811 {  314,  313}, {  316,  315}, {  318,  317}, {  320,  319}, {  322,  321}, {  324,  323}, {  326,  325},
  22.812 {  328,  327}, {  331,  330}, {  333,  332}, {  335,  334}, {  337,  336}, {  339,  338}, {  341,  340},
  22.813 {  343,  342}, {  345,  344}, {  347,  346}, {  349,  348}, {  351,  350}, {  353,  352}, {  355,  354},
  22.814 {  357,  356}, {  359,  358}, {  361,  360}, {  363,  362}, {  365,  364}, {  367,  366}, {  369,  368},
  22.815 {  371,  370}, {  373,  372}, {  375,  374}, {  378,  377}, {  380,  379}, {  382,  381}, {  383,   83}, {  387,  386},
  22.816 {  389,  388}, {  392,  391}, {  396,  395}, {  402,  401}, {  409,  408}, {  417,  416}, {  419,  418},
  22.817 {  421,  420}, {  424,  423}, {  429,  428}, {  432,  431}, {  436,  435}, {  438,  437}, {  441,  440},
  22.818 {  445,  444}, {  454,  452}, {  457,  455}, {  460,  458}, {  462,  461}, {  464,  463}, {  466,  465},
  22.819 {  468,  467}, {  470,  469}, {  472,  471}, {  474,  473}, {  476,  475}, {  477,  398}, {  479,  478},
  22.820 {  481,  480}, {  483,  482}, {  485,  484}, {  487,  486}, {  489,  488}, {  491,  490}, {  493,  492},
  22.821 {  495,  494}, {  499,  497}, {  501,  500}, {  507,  506}, {  509,  508}, {  511,  510}, {  513,  512},
  22.822 {  515,  514}, {  517,  516}, {  519,  518}, {  521,  520}, {  523,  522}, {  525,  524}, {  527,  526},
  22.823 {  529,  528}, {  531,  530}, {  533,  532}, {  535,  534}, {  595,  385}, {  596,  390}, {  598,  393},
  22.824 {  599,  394}, {  601,  399}, {  603,  400}, {  608,  403}, {  611,  404}, {  616,  407}, {  617,  406},
  22.825 {  623,  412}, {  626,  413}, {  629,  415}, {  643,  425}, {  648,  430}, {  650,  433}, {  651,  434},
  22.826 {  658,  439}, {  940,  902}, {  941,  904}, {  942,  905}, {  943,  906}, {  945,  913}, {  946,  914},
  22.827 {  947,  915}, {  948,  916}, {  949,  917}, {  950,  918}, {  951,  919}, {  952,  920}, {  953,  921},
  22.828 {  954,  922}, {  955,  923}, {  956,  924}, {  957,  925}, {  958,  926}, {  959,  927}, {  960,  928},
  22.829 {  961,  929}, {  962,  931}, {  963,  931}, {  964,  932}, {  965,  933}, {  966,  934}, {  967,  935},
  22.830 {  968,  936}, {  969,  937}, {  970,  938}, {  971,  939}, {  972,  908}, {  973,  910}, {  974,  911},
  22.831 {  995,  994}, {  997,  996}, {  999,  998}, { 1001, 1000}, { 1003, 1002}, { 1005, 1004}, { 1007, 1006},
  22.832 { 1072, 1040}, { 1073, 1041}, { 1074, 1042}, { 1075, 1043}, { 1076, 1044}, { 1077, 1045}, { 1078, 1046},
  22.833 { 1079, 1047}, { 1080, 1048}, { 1081, 1049}, { 1082, 1050}, { 1083, 1051}, { 1084, 1052}, { 1085, 1053},
  22.834 { 1086, 1054}, { 1087, 1055}, { 1088, 1056}, { 1089, 1057}, { 1090, 1058}, { 1091, 1059}, { 1092, 1060},
  22.835 { 1093, 1061}, { 1094, 1062}, { 1095, 1063}, { 1096, 1064}, { 1097, 1065}, { 1098, 1066}, { 1099, 1067},
  22.836 { 1100, 1068}, { 1101, 1069}, { 1102, 1070}, { 1103, 1071}, { 1104, 1024}, { 1105, 1025}, { 1106, 1026}, { 1107, 1027},
  22.837 { 1108, 1028}, { 1109, 1029}, { 1110, 1030}, { 1111, 1031}, { 1112, 1032}, { 1113, 1033}, { 1114, 1034},
  22.838 { 1115, 1035}, { 1116, 1036}, { 1117, 1037}, { 1118, 1038}, { 1119, 1039}, { 1121, 1120}, { 1123, 1122}, { 1125, 1124},
  22.839 { 1127, 1126}, { 1129, 1128}, { 1131, 1130}, { 1133, 1132}, { 1135, 1134}, { 1137, 1136}, { 1139, 1138},
  22.840 { 1141, 1140}, { 1143, 1142}, { 1145, 1144}, { 1147, 1146}, { 1149, 1148}, { 1151, 1150}, { 1153, 1152},
  22.841 { 1169, 1168}, { 1171, 1170}, { 1173, 1172}, { 1175, 1174}, { 1177, 1176}, { 1179, 1178}, { 1181, 1180},
  22.842 { 1183, 1182}, { 1185, 1184}, { 1187, 1186}, { 1189, 1188}, { 1191, 1190}, { 1193, 1192}, { 1195, 1194},
  22.843 { 1197, 1196}, { 1199, 1198}, { 1201, 1200}, { 1203, 1202}, { 1205, 1204}, { 1207, 1206}, { 1209, 1208},
  22.844 { 1211, 1210}, { 1213, 1212}, { 1215, 1214}, { 1218, 1217}, { 1220, 1219}, { 1224, 1223}, { 1228, 1227},
  22.845 { 1233, 1232}, { 1235, 1234}, { 1237, 1236}, { 1239, 1238}, { 1241, 1240}, { 1243, 1242}, { 1245, 1244},
  22.846 { 1247, 1246}, { 1249, 1248}, { 1251, 1250}, { 1253, 1252}, { 1255, 1254}, { 1257, 1256}, { 1259, 1258},
  22.847 { 1263, 1262}, { 1265, 1264}, { 1267, 1266}, { 1269, 1268}, { 1273, 1272}, { 1377, 1329}, { 1378, 1330},
  22.848 { 1379, 1331}, { 1380, 1332}, { 1381, 1333}, { 1382, 1334}, { 1383, 1335}, { 1384, 1336}, { 1385, 1337},
  22.849 { 1386, 1338}, { 1387, 1339}, { 1388, 1340}, { 1389, 1341}, { 1390, 1342}, { 1391, 1343}, { 1392, 1344},
  22.850 { 1393, 1345}, { 1394, 1346}, { 1395, 1347}, { 1396, 1348}, { 1397, 1349}, { 1398, 1350}, { 1399, 1351},
  22.851 { 1400, 1352}, { 1401, 1353}, { 1402, 1354}, { 1403, 1355}, { 1404, 1356}, { 1405, 1357}, { 1406, 1358},
  22.852 { 1407, 1359}, { 1408, 1360}, { 1409, 1361}, { 1410, 1362}, { 1411, 1363}, { 1412, 1364}, { 1413, 1365},
  22.853 { 1414, 1366}, { 7681, 7680}, { 7683, 7682}, { 7685, 7684}, { 7687, 7686}, { 7689, 7688}, { 7691, 7690},
  22.854 { 7693, 7692}, { 7695, 7694}, { 7697, 7696}, { 7699, 7698}, { 7701, 7700}, { 7703, 7702}, { 7705, 7704},
  22.855 { 7707, 7706}, { 7709, 7708}, { 7711, 7710}, { 7713, 7712}, { 7715, 7714}, { 7717, 7716}, { 7719, 7718},
  22.856 { 7721, 7720}, { 7723, 7722}, { 7725, 7724}, { 7727, 7726}, { 7729, 7728}, { 7731, 7730}, { 7733, 7732},
  22.857 { 7735, 7734}, { 7737, 7736}, { 7739, 7738}, { 7741, 7740}, { 7743, 7742}, { 7745, 7744}, { 7747, 7746},
  22.858 { 7749, 7748}, { 7751, 7750}, { 7753, 7752}, { 7755, 7754}, { 7757, 7756}, { 7759, 7758}, { 7761, 7760},
  22.859 { 7763, 7762}, { 7765, 7764}, { 7767, 7766}, { 7769, 7768}, { 7771, 7770}, { 7773, 7772}, { 7775, 7774},
  22.860 { 7777, 7776}, { 7779, 7778}, { 7781, 7780}, { 7783, 7782}, { 7785, 7784}, { 7787, 7786}, { 7789, 7788},
  22.861 { 7791, 7790}, { 7793, 7792}, { 7795, 7794}, { 7797, 7796}, { 7799, 7798}, { 7801, 7800}, { 7803, 7802},
  22.862 { 7805, 7804}, { 7807, 7806}, { 7809, 7808}, { 7811, 7810}, { 7813, 7812}, { 7815, 7814}, { 7817, 7816},
  22.863 { 7819, 7818}, { 7821, 7820}, { 7823, 7822}, { 7825, 7824}, { 7827, 7826}, { 7829, 7828}, { 7841, 7840},
  22.864 { 7843, 7842}, { 7845, 7844}, { 7847, 7846}, { 7849, 7848}, { 7851, 7850}, { 7853, 7852}, { 7855, 7854},
  22.865 { 7857, 7856}, { 7859, 7858}, { 7861, 7860}, { 7863, 7862}, { 7865, 7864}, { 7867, 7866}, { 7869, 7868},
  22.866 { 7871, 7870}, { 7873, 7872}, { 7875, 7874}, { 7877, 7876}, { 7879, 7878}, { 7881, 7880}, { 7883, 7882},
  22.867 { 7885, 7884}, { 7887, 7886}, { 7889, 7888}, { 7891, 7890}, { 7893, 7892}, { 7895, 7894}, { 7897, 7896},
  22.868 { 7899, 7898}, { 7901, 7900}, { 7903, 7902}, { 7905, 7904}, { 7907, 7906}, { 7909, 7908}, { 7911, 7910},
  22.869 { 7913, 7912}, { 7915, 7914}, { 7917, 7916}, { 7919, 7918}, { 7921, 7920}, { 7923, 7922}, { 7925, 7924},
  22.870 { 7927, 7926}, { 7929, 7928}, { 7936, 7944}, { 7937, 7945}, { 7938, 7946}, { 7939, 7947}, { 7940, 7948},
  22.871 { 7941, 7949}, { 7942, 7950}, { 7943, 7951}, { 7952, 7960}, { 7953, 7961}, { 7954, 7962}, { 7955, 7963},
  22.872 { 7956, 7964}, { 7957, 7965}, { 7968, 7976}, { 7969, 7977}, { 7970, 7978}, { 7971, 7979}, { 7972, 7980},
  22.873 { 7973, 7981}, { 7974, 7982}, { 7975, 7983}, { 7984, 7992}, { 7985, 7993}, { 7986, 7994}, { 7987, 7995},
  22.874 { 7988, 7996}, { 7989, 7997}, { 7990, 7998}, { 7991, 7999}, { 8000, 8008}, { 8001, 8009}, { 8002, 8010},
  22.875 { 8003, 8011}, { 8004, 8012}, { 8005, 8013}, { 8017, 8025}, { 8019, 8027}, { 8021, 8029}, { 8023, 8031},
  22.876 { 8032, 8040}, { 8033, 8041}, { 8034, 8042}, { 8035, 8043}, { 8036, 8044}, { 8037, 8045}, { 8038, 8046},
  22.877 { 8039, 8047}, { 8048, 8122}, { 8049, 8123}, { 8050, 8136}, { 8051, 8137}, { 8052, 8138}, { 8053, 8139},
  22.878 { 8054, 8154}, { 8055, 8155}, { 8056, 8184}, { 8057, 8185}, { 8058, 8170}, { 8059, 8171}, { 8060, 8186},
  22.879 { 8061, 8187}, { 8112, 8120}, { 8113, 8121}, { 8144, 8152}, { 8145, 8153}, { 8160, 8168}, { 8161, 8169},
  22.880 { 8165, 8172}, { 8560, 8544}, { 8561, 8545}, { 8562, 8546}, { 8563, 8547}, { 8564, 8548}, { 8565, 8549},
  22.881 { 8566, 8550}, { 8567, 8551}, { 8568, 8552}, { 8569, 8553}, { 8570, 8554}, { 8571, 8555}, { 8572, 8556},
  22.882 { 8573, 8557}, { 8574, 8558}, { 8575, 8559}, { 9424, 9398}, { 9425, 9399}, { 9426, 9400}, { 9427, 9401},
  22.883 { 9428, 9402}, { 9429, 9403}, { 9430, 9404}, { 9431, 9405}, { 9432, 9406}, { 9433, 9407}, { 9434, 9408},
  22.884 { 9435, 9409}, { 9436, 9410}, { 9437, 9411}, { 9438, 9412}, { 9439, 9413}, { 9440, 9414}, { 9441, 9415},
  22.885 { 9442, 9416}, { 9443, 9417}, { 9444, 9418}, { 9445, 9419}, { 9446, 9420}, { 9447, 9421}, { 9448, 9422},
  22.886 { 9449, 9423}, {65345,65313}, {65346,65314}, {65347,65315}, {65348,65316}, {65349,65317}, {65350,65318},
  22.887 {65351,65319}, {65352,65320}, {65353,65321}, {65354,65322}, {65355,65323}, {65356,65324}, {65357,65325},
  22.888 {65358,65326}, {65359,65327}, {65360,65328}, {65361,65329}, {65362,65330}, {65363,65331}, {65364,65332},
  22.889 {65365,65333}, {65366,65334}, {65367,65335}, {65368,65336}, {65369,65337}, {65370,65338}, {65535,    0}};
  22.890 
  22.891 static const GUnicodePairType UnicodeToLowerTable[] = {
  22.892 {   65,   97}, {   66,   98}, {   67,   99}, {   68,  100}, {   69,  101}, {   70,  102}, {   71,  103},
  22.893 {   72,  104}, {   73,  105}, {   74,  106}, {   75,  107}, {   76,  108}, {   77,  109}, {   78,  110},
  22.894 {   79,  111}, {   80,  112}, {   81,  113}, {   82,  114}, {   83,  115}, {   84,  116}, {   85,  117},
  22.895 {   86,  118}, {   87,  119}, {   88,  120}, {   89,  121}, {   90,  122}, {  192,  224}, {  193,  225},
  22.896 {  194,  226}, {  195,  227}, {  196,  228}, {  197,  229}, {  198,  230}, {  199,  231}, {  200,  232},
  22.897 {  201,  233}, {  202,  234}, {  203,  235}, {  204,  236}, {  205,  237}, {  206,  238}, {  207,  239},
  22.898 {  208,  240}, {  209,  241}, {  210,  242}, {  211,  243}, {  212,  244}, {  213,  245}, {  214,  246},
  22.899 {  216,  248}, {  217,  249}, {  218,  250}, {  219,  251}, {  220,  252}, {  221,  253}, {  222,  254},
  22.900 {  256,  257}, {  258,  259}, {  260,  261}, {  262,  263}, {  264,  265}, {  266,  267}, {  268,  269},
  22.901 {  270,  271}, {  272,  273}, {  274,  275}, {  276,  277}, {  278,  279}, {  280,  281}, {  282,  283},
  22.902 {  284,  285}, {  286,  287}, {  288,  289}, {  290,  291}, {  292,  293}, {  294,  295}, {  296,  297},
  22.903 {  298,  299}, {  300,  301}, {  302,  303}, {  304,  105}, {  306,  307}, {  308,  309}, {  310,  311}, {  313,  314},
  22.904 {  315,  316}, {  317,  318}, {  319,  320}, {  321,  322}, {  323,  324}, {  325,  326}, {  327,  328},
  22.905 {  330,  331}, {  332,  333}, {  334,  335}, {  336,  337}, {  338,  339}, {  340,  341}, {  342,  343},
  22.906 {  344,  345}, {  346,  347}, {  348,  349}, {  350,  351}, {  352,  353}, {  354,  355}, {  356,  357},
  22.907 {  358,  359}, {  360,  361}, {  362,  363}, {  364,  365}, {  366,  367}, {  368,  369}, {  370,  371},
  22.908 {  372,  373}, {  374,  375}, {  376,  255}, {  377,  378}, {  379,  380}, {  381,  382}, {  385,  595},
  22.909 {  386,  387}, {  388,  389}, {  390,  596}, {  391,  392}, {  393,  598}, {  394,  599}, {  395,  396},
  22.910 {  398,  477}, {  399,  601}, {  400,  603}, {  401,  402}, {  403,  608}, {  404,  611}, {  406,  617},
  22.911 {  407,  616}, {  408,  409}, {  412,  623}, {  413,  626}, {  415,  629}, {  416,  417}, {  418,  419},
  22.912 {  420,  421}, {  423,  424}, {  425,  643}, {  428,  429}, {  430,  648}, {  431,  432}, {  433,  650},
  22.913 {  434,  651}, {  435,  436}, {  437,  438}, {  439,  658}, {  440,  441}, {  444,  445}, {  452,  454},
  22.914 {  455,  457}, {  458,  460}, {  461,  462}, {  463,  464}, {  465,  466}, {  467,  468}, {  469,  470},
  22.915 {  471,  472}, {  473,  474}, {  475,  476}, {  478,  479}, {  480,  481}, {  482,  483}, {  484,  485},
  22.916 {  486,  487}, {  488,  489}, {  490,  491}, {  492,  493}, {  494,  495}, {  497,  499}, {  500,  501},
  22.917 {  506,  507}, {  508,  509}, {  510,  511}, {  512,  513}, {  514,  515}, {  516,  517}, {  518,  519},
  22.918 {  520,  521}, {  522,  523}, {  524,  525}, {  526,  527}, {  528,  529}, {  530,  531}, {  532,  533},
  22.919 {  534,  535}, {  902,  940}, {  904,  941}, {  905,  942}, {  906,  943}, {  908,  972}, {  910,  973},
  22.920 {  911,  974}, {  913,  945}, {  914,  946}, {  915,  947}, {  916,  948}, {  917,  949}, {  918,  950},
  22.921 {  919,  951}, {  920,  952}, {  921,  953}, {  922,  954}, {  923,  955}, {  924,  956}, {  925,  957},
  22.922 {  926,  958}, {  927,  959}, {  928,  960}, {  929,  961}, {  931,  963}, {  932,  964}, {  933,  965},
  22.923 {  934,  966}, {  935,  967}, {  936,  968}, {  937,  969}, {  938,  970}, {  939,  971}, {  994,  995},
  22.924 {  996,  997}, {  998,  999}, { 1000, 1001}, { 1002, 1003}, { 1004, 1005}, { 1006, 1007}, { 1024, 1104}, { 1025, 1105},
  22.925 { 1026, 1106}, { 1027, 1107}, { 1028, 1108}, { 1029, 1109}, { 1030, 1110}, { 1031, 1111}, { 1032, 1112},
  22.926 { 1033, 1113}, { 1034, 1114}, { 1035, 1115}, { 1036, 1116}, { 1037, 1117}, { 1038, 1118}, { 1039, 1119}, { 1040, 1072},
  22.927 { 1041, 1073}, { 1042, 1074}, { 1043, 1075}, { 1044, 1076}, { 1045, 1077}, { 1046, 1078}, { 1047, 1079},
  22.928 { 1048, 1080}, { 1049, 1081}, { 1050, 1082}, { 1051, 1083}, { 1052, 1084}, { 1053, 1085}, { 1054, 1086},
  22.929 { 1055, 1087}, { 1056, 1088}, { 1057, 1089}, { 1058, 1090}, { 1059, 1091}, { 1060, 1092}, { 1061, 1093},
  22.930 { 1062, 1094}, { 1063, 1095}, { 1064, 1096}, { 1065, 1097}, { 1066, 1098}, { 1067, 1099}, { 1068, 1100},
  22.931 { 1069, 1101}, { 1070, 1102}, { 1071, 1103}, { 1120, 1121}, { 1122, 1123}, { 1124, 1125}, { 1126, 1127},
  22.932 { 1128, 1129}, { 1130, 1131}, { 1132, 1133}, { 1134, 1135}, { 1136, 1137}, { 1138, 1139}, { 1140, 1141},
  22.933 { 1142, 1143}, { 1144, 1145}, { 1146, 1147}, { 1148, 1149}, { 1150, 1151}, { 1152, 1153}, { 1168, 1169},
  22.934 { 1170, 1171}, { 1172, 1173}, { 1174, 1175}, { 1176, 1177}, { 1178, 1179}, { 1180, 1181}, { 1182, 1183},
  22.935 { 1184, 1185}, { 1186, 1187}, { 1188, 1189}, { 1190, 1191}, { 1192, 1193}, { 1194, 1195}, { 1196, 1197},
  22.936 { 1198, 1199}, { 1200, 1201}, { 1202, 1203}, { 1204, 1205}, { 1206, 1207}, { 1208, 1209}, { 1210, 1211},
  22.937 { 1212, 1213}, { 1214, 1215}, { 1217, 1218}, { 1219, 1220}, { 1223, 1224}, { 1227, 1228}, { 1232, 1233},
  22.938 { 1234, 1235}, { 1236, 1237}, { 1238, 1239}, { 1240, 1241}, { 1242, 1243}, { 1244, 1245}, { 1246, 1247},
  22.939 { 1248, 1249}, { 1250, 1251}, { 1252, 1253}, { 1254, 1255}, { 1256, 1257}, { 1258, 1259}, { 1262, 1263},
  22.940 { 1264, 1265}, { 1266, 1267}, { 1268, 1269}, { 1272, 1273}, { 1329, 1377}, { 1330, 1378}, { 1331, 1379},
  22.941 { 1332, 1380}, { 1333, 1381}, { 1334, 1382}, { 1335, 1383}, { 1336, 1384}, { 1337, 1385}, { 1338, 1386},
  22.942 { 1339, 1387}, { 1340, 1388}, { 1341, 1389}, { 1342, 1390}, { 1343, 1391}, { 1344, 1392}, { 1345, 1393},
  22.943 { 1346, 1394}, { 1347, 1395}, { 1348, 1396}, { 1349, 1397}, { 1350, 1398}, { 1351, 1399}, { 1352, 1400},
  22.944 { 1353, 1401}, { 1354, 1402}, { 1355, 1403}, { 1356, 1404}, { 1357, 1405}, { 1358, 1406}, { 1359, 1407},
  22.945 { 1360, 1408}, { 1361, 1409}, { 1362, 1410}, { 1363, 1411}, { 1364, 1412}, { 1365, 1413}, { 1366, 1414},
  22.946 { 4256, 4304}, { 4257, 4305}, { 4258, 4306}, { 4259, 4307}, { 4260, 4308}, { 4261, 4309}, { 4262, 4310},
  22.947 { 4263, 4311}, { 4264, 4312}, { 4265, 4313}, { 4266, 4314}, { 4267, 4315}, { 4268, 4316}, { 4269, 4317},
  22.948 { 4270, 4318}, { 4271, 4319}, { 4272, 4320}, { 4273, 4321}, { 4274, 4322}, { 4275, 4323}, { 4276, 4324},
  22.949 { 4277, 4325}, { 4278, 4326}, { 4279, 4327}, { 4280, 4328}, { 4281, 4329}, { 4282, 4330}, { 4283, 4331},
  22.950 { 4284, 4332}, { 4285, 4333}, { 4286, 4334}, { 4287, 4335}, { 4288, 4336}, { 4289, 4337}, { 4290, 4338},
  22.951 { 4291, 4339}, { 4292, 4340}, { 4293, 4341}, { 7680, 7681}, { 7682, 7683}, { 7684, 7685}, { 7686, 7687},
  22.952 { 7688, 7689}, { 7690, 7691}, { 7692, 7693}, { 7694, 7695}, { 7696, 7697}, { 7698, 7699}, { 7700, 7701},
  22.953 { 7702, 7703}, { 7704, 7705}, { 7706, 7707}, { 7708, 7709}, { 7710, 7711}, { 7712, 7713}, { 7714, 7715},
  22.954 { 7716, 7717}, { 7718, 7719}, { 7720, 7721}, { 7722, 7723}, { 7724, 7725}, { 7726, 7727}, { 7728, 7729},
  22.955 { 7730, 7731}, { 7732, 7733}, { 7734, 7735}, { 7736, 7737}, { 7738, 7739}, { 7740, 7741}, { 7742, 7743},
  22.956 { 7744, 7745}, { 7746, 7747}, { 7748, 7749}, { 7750, 7751}, { 7752, 7753}, { 7754, 7755}, { 7756, 7757},
  22.957 { 7758, 7759}, { 7760, 7761}, { 7762, 7763}, { 7764, 7765}, { 7766, 7767}, { 7768, 7769}, { 7770, 7771},
  22.958 { 7772, 7773}, { 7774, 7775}, { 7776, 7777}, { 7778, 7779}, { 7780, 7781}, { 7782, 7783}, { 7784, 7785},
  22.959 { 7786, 7787}, { 7788, 7789}, { 7790, 7791}, { 7792, 7793}, { 7794, 7795}, { 7796, 7797}, { 7798, 7799},
  22.960 { 7800, 7801}, { 7802, 7803}, { 7804, 7805}, { 7806, 7807}, { 7808, 7809}, { 7810, 7811}, { 7812, 7813},
  22.961 { 7814, 7815}, { 7816, 7817}, { 7818, 7819}, { 7820, 7821}, { 7822, 7823}, { 7824, 7825}, { 7826, 7827},
  22.962 { 7828, 7829}, { 7840, 7841}, { 7842, 7843}, { 7844, 7845}, { 7846, 7847}, { 7848, 7849}, { 7850, 7851},
  22.963 { 7852, 7853}, { 7854, 7855}, { 7856, 7857}, { 7858, 7859}, { 7860, 7861}, { 7862, 7863}, { 7864, 7865},
  22.964 { 7866, 7867}, { 7868, 7869}, { 7870, 7871}, { 7872, 7873}, { 7874, 7875}, { 7876, 7877}, { 7878, 7879},
  22.965 { 7880, 7881}, { 7882, 7883}, { 7884, 7885}, { 7886, 7887}, { 7888, 7889}, { 7890, 7891}, { 7892, 7893},
  22.966 { 7894, 7895}, { 7896, 7897}, { 7898, 7899}, { 7900, 7901}, { 7902, 7903}, { 7904, 7905}, { 7906, 7907},
  22.967 { 7908, 7909}, { 7910, 7911}, { 7912, 7913}, { 7914, 7915}, { 7916, 7917}, { 7918, 7919}, { 7920, 7921},
  22.968 { 7922, 7923}, { 7924, 7925}, { 7926, 7927}, { 7928, 7929}, { 7944, 7936}, { 7945, 7937}, { 7946, 7938},
  22.969 { 7947, 7939}, { 7948, 7940}, { 7949, 7941}, { 7950, 7942}, { 7951, 7943}, { 7960, 7952}, { 7961, 7953},
  22.970 { 7962, 7954}, { 7963, 7955}, { 7964, 7956}, { 7965, 7957}, { 7976, 7968}, { 7977, 7969}, { 7978, 7970},
  22.971 { 7979, 7971}, { 7980, 7972}, { 7981, 7973}, { 7982, 7974}, { 7983, 7975}, { 7992, 7984}, { 7993, 7985},
  22.972 { 7994, 7986}, { 7995, 7987}, { 7996, 7988}, { 7997, 7989}, { 7998, 7990}, { 7999, 7991}, { 8008, 8000},
  22.973 { 8009, 8001}, { 8010, 8002}, { 8011, 8003}, { 8012, 8004}, { 8013, 8005}, { 8025, 8017}, { 8027, 8019},
  22.974 { 8029, 8021}, { 8031, 8023}, { 8040, 8032}, { 8041, 8033}, { 8042, 8034}, { 8043, 8035}, { 8044, 8036},
  22.975 { 8045, 8037}, { 8046, 8038}, { 8047, 8039}, { 8120, 8112}, { 8121, 8113}, { 8122, 8048}, { 8123, 8049},
  22.976 { 8136, 8050}, { 8137, 8051}, { 8138, 8052}, { 8139, 8053}, { 8152, 8144}, { 8153, 8145}, { 8154, 8054},
  22.977 { 8155, 8055}, { 8168, 8160}, { 8169, 8161}, { 8170, 8058}, { 8171, 8059}, { 8172, 8165}, { 8184, 8056},
  22.978 { 8185, 8057}, { 8186, 8060}, { 8187, 8061}, { 8544, 8560}, { 8545, 8561}, { 8546, 8562}, { 8547, 8563},
  22.979 { 8548, 8564}, { 8549, 8565}, { 8550, 8566}, { 8551, 8567}, { 8552, 8568}, { 8553, 8569}, { 8554, 8570},
  22.980 { 8555, 8571}, { 8556, 8572}, { 8557, 8573}, { 8558, 8574}, { 8559, 8575}, { 9398, 9424}, { 9399, 9425},
  22.981 { 9400, 9426}, { 9401, 9427}, { 9402, 9428}, { 9403, 9429}, { 9404, 9430}, { 9405, 9431}, { 9406, 9432},
  22.982 { 9407, 9433}, { 9408, 9434}, { 9409, 9435}, { 9410, 9436}, { 9411, 9437}, { 9412, 9438}, { 9413, 9439},
  22.983 { 9414, 9440}, { 9415, 9441}, { 9416, 9442}, { 9417, 9443}, { 9418, 9444}, { 9419, 9445}, { 9420, 9446},
  22.984 { 9421, 9447}, { 9422, 9448}, { 9423, 9449}, {65313,65345}, {65314,65346}, {65315,65347}, {65316,65348},
  22.985 {65317,65349}, {65318,65350}, {65319,65351}, {65320,65352}, {65321,65353}, {65322,65354}, {65323,65355},
  22.986 {65324,65356}, {65325,65357}, {65326,65358}, {65327,65359}, {65328,65360}, {65329,65361}, {65330,65362},
  22.987 {65331,65363}, {65332,65364}, {65333,65365}, {65334,65366}, {65335,65367}, {65336,65368}, {65337,65369},
  22.988 {65338,65370}, {65535,    0}};
  22.989 
  22.990 int OVR_CDECL OVR_towupper(wchar_t charCode)
  22.991 {
  22.992     // Don't use UnicodeUpperBits! It differs from UnicodeToUpperBits.
  22.993     if (UnicodeCharIs(UnicodeToUpperBits, charCode))
  22.994     {
  22.995         // To protect from memory overrun in case the character is not found
  22.996         // we use one extra fake element in the table {65536, 0}.
  22.997         UPInt idx = Alg::LowerBoundSliced(
  22.998             UnicodeToUpperTable,
  22.999             0,
 22.1000             sizeof(UnicodeToUpperTable) / sizeof(UnicodeToUpperTable[0]) - 1,
 22.1001             (UInt16)charCode,
 22.1002             CmpUnicodeKey);
 22.1003         return UnicodeToUpperTable[idx].Value;
 22.1004     }
 22.1005     return charCode;
 22.1006 }
 22.1007 
 22.1008 int OVR_CDECL OVR_towlower(wchar_t charCode)
 22.1009 {
 22.1010     // Don't use UnicodeLowerBits! It differs from UnicodeToLowerBits.
 22.1011     if (UnicodeCharIs(UnicodeToLowerBits, charCode))
 22.1012     {
 22.1013         // To protect from memory overrun in case the character is not found
 22.1014         // we use one extra fake element in the table {65536, 0}.
 22.1015         UPInt idx = Alg::LowerBoundSliced(
 22.1016             UnicodeToLowerTable,
 22.1017             0,
 22.1018             sizeof(UnicodeToLowerTable) / sizeof(UnicodeToLowerTable[0]) - 1,
 22.1019             (UInt16)charCode,
 22.1020             CmpUnicodeKey);
 22.1021         return UnicodeToLowerTable[idx].Value;
 22.1022     }
 22.1023     return charCode;
 22.1024 }
 22.1025 
 22.1026 #endif //OVR_NO_WCTYPE
 22.1027 
 22.1028 } // OVR
 22.1029 \ No newline at end of file
 22.1030 +/************************************************************************************
 22.1031 +
 22.1032 +Filename    :   OVR_Std.cpp
 22.1033 +Content     :   Standard C function implementation
 22.1034 +Created     :   September 19, 2012
 22.1035 +Notes       : 
 22.1036 +
 22.1037 +Copyright   :   Copyright 2012 Oculus VR, Inc. All Rights reserved.
 22.1038 +
 22.1039 +Use of this software is subject to the terms of the Oculus license
 22.1040 +agreement provided at the time of installation or download, or which
 22.1041 +otherwise accompanies this software in either electronic or hard copy form.
 22.1042 +
 22.1043 +************************************************************************************/
 22.1044 +
 22.1045 +#include "OVR_Std.h"
 22.1046 +#include "OVR_Alg.h"
 22.1047 +
 22.1048 +// localeconv() call in OVR_strtod()
 22.1049 +#include <locale.h>
 22.1050 +
 22.1051 +namespace OVR {
 22.1052 +
 22.1053 +// Source for functions not available on all platforms is included here.
 22.1054 +
 22.1055 +// Case insensitive compare implemented in platform-specific way.
 22.1056 +int OVR_CDECL OVR_stricmp(const char* a, const char* b)
 22.1057 +{
 22.1058 +#if defined(OVR_OS_WIN32)
 22.1059 +    #if defined(OVR_CC_MSVC) && (OVR_CC_MSVC >= 1400)
 22.1060 +        return ::_stricmp(a, b);
 22.1061 +    #else
 22.1062 +        return ::stricmp(a, b);
 22.1063 +    #endif
 22.1064 +
 22.1065 +#else
 22.1066 +    return strcasecmp(a, b);
 22.1067 +#endif
 22.1068 +}
 22.1069 +
 22.1070 +int OVR_CDECL OVR_strnicmp(const char* a, const char* b, UPInt count)
 22.1071 +{
 22.1072 +#if defined(OVR_OS_WIN32)
 22.1073 +#if defined(OVR_CC_MSVC) && (OVR_CC_MSVC >= 1400)
 22.1074 +    return ::_strnicmp(a, b, count);
 22.1075 +#else
 22.1076 +    return ::strnicmp(a, b, count);
 22.1077 +#endif
 22.1078 +
 22.1079 +#else
 22.1080 +    return strncasecmp(a, b, count);
 22.1081 +#endif
 22.1082 +}
 22.1083 +
 22.1084 +wchar_t* OVR_CDECL OVR_wcscpy(wchar_t* dest, UPInt destsize, const wchar_t* src)
 22.1085 +{
 22.1086 +#if defined(OVR_MSVC_SAFESTRING)
 22.1087 +    wcscpy_s(dest, destsize, src);
 22.1088 +    return dest;
 22.1089 +#elif defined(OVR_OS_WIN32)
 22.1090 +    OVR_UNUSED(destsize);
 22.1091 +    wcscpy(dest, src);
 22.1092 +    return dest;
 22.1093 +#else
 22.1094 +    UPInt l = OVR_wcslen(src) + 1; // incl term null
 22.1095 +    l = (l < destsize) ? l : destsize;
 22.1096 +    memcpy(dest, src, l * sizeof(wchar_t));
 22.1097 +    return dest;
 22.1098 +#endif
 22.1099 +}
 22.1100 +
 22.1101 +wchar_t* OVR_CDECL OVR_wcsncpy(wchar_t* dest, UPInt destsize, const wchar_t* src, UPInt count)
 22.1102 +{
 22.1103 +#if defined(OVR_MSVC_SAFESTRING)
 22.1104 +    wcsncpy_s(dest, destsize, src, count);
 22.1105 +    return dest;
 22.1106 +#else
 22.1107 +    UPInt srclen = OVR_wcslen(src);
 22.1108 +    UPInt l = Alg::Min(srclen, count);
 22.1109 +    l = (l < destsize) ? l : destsize;
 22.1110 +    memcpy(dest, src, l * sizeof(wchar_t));
 22.1111 +    if (count > srclen)
 22.1112 +    {
 22.1113 +        UPInt remLen = Alg::Min(destsize - l, (count - srclen));
 22.1114 +        memset(&dest[l], 0, sizeof(wchar_t)*remLen);
 22.1115 +    }
 22.1116 +    else if (l < destsize)
 22.1117 +        dest[l] = 0;
 22.1118 +    return dest;
 22.1119 +#endif
 22.1120 +}
 22.1121 +
 22.1122 +
 22.1123 +wchar_t* OVR_CDECL OVR_wcscat(wchar_t* dest, UPInt destsize, const wchar_t* src)
 22.1124 +{
 22.1125 +#if defined(OVR_MSVC_SAFESTRING)
 22.1126 +    wcscat_s(dest, destsize, src);
 22.1127 +    return dest;
 22.1128 +#elif defined(OVR_OS_WIN32)
 22.1129 +    OVR_UNUSED(destsize);
 22.1130 +    wcscat(dest, src);
 22.1131 +    return dest;
 22.1132 +#else
 22.1133 +    UPInt dstlen = OVR_wcslen(dest); // do not incl term null
 22.1134 +    UPInt srclen = OVR_wcslen(src) + 1; // incl term null
 22.1135 +    UPInt copylen = (dstlen + srclen < destsize) ? srclen : destsize - dstlen;
 22.1136 +    memcpy(dest + dstlen, src, copylen * sizeof(wchar_t));
 22.1137 +    return dest;
 22.1138 +#endif
 22.1139 +}
 22.1140 +
 22.1141 +UPInt   OVR_CDECL OVR_wcslen(const wchar_t* str)
 22.1142 +{
 22.1143 +#if defined(OVR_OS_WIN32)
 22.1144 +    return wcslen(str);
 22.1145 +#else
 22.1146 +    UPInt i = 0;
 22.1147 +    while(str[i] != '\0')
 22.1148 +        ++i;
 22.1149 +    return i;
 22.1150 +#endif
 22.1151 +}
 22.1152 +
 22.1153 +int OVR_CDECL OVR_wcscmp(const wchar_t* a, const wchar_t* b)
 22.1154 +{
 22.1155 +#if defined(OVR_OS_WIN32) || defined(OVR_OS_LINUX)
 22.1156 +    return wcscmp(a, b);
 22.1157 +#else
 22.1158 +    // not supported, use custom implementation
 22.1159 +    const wchar_t *pa = a, *pb = b;
 22.1160 +    while (*pa && *pb)
 22.1161 +    {
 22.1162 +        wchar_t ca = *pa;
 22.1163 +        wchar_t cb = *pb;
 22.1164 +        if (ca < cb)
 22.1165 +            return -1;
 22.1166 +        else if (ca > cb)
 22.1167 +            return 1;
 22.1168 +        pa++;
 22.1169 +        pb++;
 22.1170 +    }
 22.1171 +    if (*pa)
 22.1172 +        return 1;
 22.1173 +    else if (*pb)
 22.1174 +        return -1;
 22.1175 +    else
 22.1176 +        return 0;
 22.1177 +#endif
 22.1178 +}
 22.1179 +
 22.1180 +int OVR_CDECL OVR_wcsicmp(const wchar_t* a, const wchar_t* b)
 22.1181 +{
 22.1182 +#if defined(OVR_OS_WIN32)
 22.1183 +#if defined(OVR_CC_MSVC) && (OVR_CC_MSVC >= 1400)
 22.1184 +    return ::_wcsicmp(a, b);
 22.1185 +#else
 22.1186 +    return ::wcsicmp(a, b);
 22.1187 +#endif
 22.1188 +#elif defined(OVR_OS_MAC) || defined(__CYGWIN__) || defined(OVR_OS_ANDROID) || defined(OVR_OS_IPHONE)
 22.1189 +    // not supported, use custom implementation
 22.1190 +    const wchar_t *pa = a, *pb = b;
 22.1191 +    while (*pa && *pb)
 22.1192 +    {
 22.1193 +        wchar_t ca = OVR_towlower(*pa);
 22.1194 +        wchar_t cb = OVR_towlower(*pb);
 22.1195 +        if (ca < cb)
 22.1196 +            return -1;
 22.1197 +        else if (ca > cb)
 22.1198 +            return 1;
 22.1199 +        pa++;
 22.1200 +        pb++;
 22.1201 +    }
 22.1202 +    if (*pa)
 22.1203 +        return 1;
 22.1204 +    else if (*pb)
 22.1205 +        return -1;
 22.1206 +    else
 22.1207 +        return 0;
 22.1208 +#else
 22.1209 +    return wcscasecmp(a, b);
 22.1210 +#endif
 22.1211 +}
 22.1212 +
 22.1213 +// This function is not inline because of dependency on <locale.h>
 22.1214 +double OVR_CDECL OVR_strtod(const char* string, char** tailptr)
 22.1215 +{
 22.1216 +#if !defined(OVR_OS_ANDROID)
 22.1217 +    const char s = *localeconv()->decimal_point;
 22.1218 +
 22.1219 +    if (s != '.')
 22.1220 +    {
 22.1221 +        char buffer[347 + 1];
 22.1222 +
 22.1223 +        OVR_strcpy(buffer, sizeof(buffer), string);
 22.1224 +
 22.1225 +        for (char* c = buffer; *c != '\0'; ++c)
 22.1226 +        {
 22.1227 +            if (*c == '.')
 22.1228 +            {
 22.1229 +                *c = s;
 22.1230 +                break;
 22.1231 +            }
 22.1232 +        }
 22.1233 +
 22.1234 +        return strtod(buffer, tailptr);
 22.1235 +    }
 22.1236 +#endif
 22.1237 +
 22.1238 +    return strtod(string, tailptr);
 22.1239 +}
 22.1240 +
 22.1241 +
 22.1242 +#ifndef OVR_NO_WCTYPE
 22.1243 +
 22.1244 +//// Use this class to generate Unicode bitsets. For example:
 22.1245 +////
 22.1246 +//// UnicodeBitSet bitSet;
 22.1247 +//// for(unsigned i = 0; i < 65536; ++i)
 22.1248 +//// {
 22.1249 +////     if (iswalpha(i))
 22.1250 +////         bitSet.Set(i);
 22.1251 +//// }
 22.1252 +//// bitSet.Dump();
 22.1253 +////
 22.1254 +////---------------------------------------------------------------
 22.1255 +//class UnicodeBitSet
 22.1256 +//{
 22.1257 +//public:
 22.1258 +//    UnicodeBitSet()
 22.1259 +//    {
 22.1260 +//        memset(Offsets, 0, sizeof(Offsets));
 22.1261 +//        memset(Bits,    0, sizeof(Bits));
 22.1262 +//    }
 22.1263 +//
 22.1264 +//    void Set(unsigned bit) { Bits[bit >> 8][(bit >> 4) & 15] |= 1 << (bit & 15); }
 22.1265 +//
 22.1266 +//    void Dump()
 22.1267 +//    {
 22.1268 +//        unsigned i, j;
 22.1269 +//        unsigned offsetCount = 0;
 22.1270 +//        for(i = 0; i < 256; ++i)
 22.1271 +//        {
 22.1272 +//            if (isNull(i)) Offsets[i] = 0;
 22.1273 +//            else
 22.1274 +//            if (isFull(i)) Offsets[i] = 1;
 22.1275 +//            else           Offsets[i] = UInt16(offsetCount++ * 16 + 256);
 22.1276 +//        }
 22.1277 +//        for(i = 0; i < 16; ++i)
 22.1278 +//        {
 22.1279 +//            for(j = 0; j < 16; ++j)
 22.1280 +//            {
 22.1281 +//                printf("%5u,", Offsets[i*16+j]);
 22.1282 +//            }
 22.1283 +//            printf("\n");
 22.1284 +//        }
 22.1285 +//        for(i = 0; i < 256; ++i)
 22.1286 +//        {
 22.1287 +//            if (Offsets[i] > 255)
 22.1288 +//            {
 22.1289 +//                for(j = 0; j < 16; j++)
 22.1290 +//                {
 22.1291 +//                    printf("%5u,", Bits[i][j]);
 22.1292 +//                }
 22.1293 +//                printf("\n");
 22.1294 +//            }
 22.1295 +//        }
 22.1296 +//    }
 22.1297 +//
 22.1298 +//private:
 22.1299 +//    bool isNull(unsigned n) const
 22.1300 +//    {
 22.1301 +//        const UInt16* p = Bits[n];
 22.1302 +//        for(unsigned i = 0; i < 16; ++i)
 22.1303 +//            if (p[i] != 0) return false;
 22.1304 +//        return true;
 22.1305 +//    }
 22.1306 +//
 22.1307 +//    bool isFull(unsigned n) const
 22.1308 +//    {
 22.1309 +//        const UInt16* p = Bits[n];
 22.1310 +//        for(unsigned i = 0; i < 16; ++i)
 22.1311 +//            if (p[i] != 0xFFFF) return false;
 22.1312 +//        return true;
 22.1313 +//    }
 22.1314 +//
 22.1315 +//    UInt16 Offsets[256];
 22.1316 +//    UInt16 Bits[256][16];
 22.1317 +//};
 22.1318 +
 22.1319 +
 22.1320 +const UInt16 UnicodeAlnumBits[] = {
 22.1321 +  256,    1,  272,  288,  304,  320,  336,  352,    0,  368,  384,  400,  416,  432,  448,  464,
 22.1322 +  480,  496,  512,  528,  544,    1,  560,  576,  592,    0,    0,    0,    0,    0,  608,  624,
 22.1323 +  640,  656,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
 22.1324 +  672,  688,    0,    0,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
 22.1325 +    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,  704,    1,    1,
 22.1326 +    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
 22.1327 +    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
 22.1328 +    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
 22.1329 +    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
 22.1330 +    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,  720,
 22.1331 +    1,    1,    1,    1,  736,    0,    0,    0,    0,    0,    0,    0,    1,    1,    1,    1,
 22.1332 +    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
 22.1333 +    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
 22.1334 +    1,    1,    1,    1,    1,    1,    1,  752,    0,    0,    0,    0,    0,    0,    0,    0,
 22.1335 +    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
 22.1336 +    0,    0,    0,    0,    0,    0,    0,    0,    0,    1,  768,  784,    1,  800,  816,  832,
 22.1337 +    0,    0,    0, 1023,65534, 2047,65534, 2047,    0,    0,    0,  524,65535,65407,65535,65407,
 22.1338 +65535,65535,65532,   15,    0,65535,65535,65535,65535,65535,16383,63999,    3,    0,16415,    0,
 22.1339 +    0,    0,    0,    0,   32,    0,    0, 1024,55104,65535,65531,65535,32767,64767,65535,   15,
 22.1340 +65535,65535,65535,65535,65535,65535,65535,65535,61443,65535,65535,65535, 6559,65535,65535,  831,
 22.1341 +    0,    0,    0,65534,65535,  639,65534,65535,  255,    0,    0,    0,    0,65535, 2047,    7,
 22.1342 +    0,    0,65534, 2047,65534,   63, 1023,65535,65535,65535,65535,65535,65535, 8175, 8702, 8191,
 22.1343 +    0,65535, 8191,65535,    0,    0,    0,    0,65535,65535,65535,    1,    0,    0,    0,    0,
 22.1344 +65518,65535,65535,58367, 8191,65281,65487,    0,40942,65529,65023,50117, 6559,45184,65487,    3,
 22.1345 +34788,65529,65023,50029, 6535,24064,65472,   31,45038,65531,65023,58349, 7103,    1,65473,    0,
 22.1346 +40942,65529,65023,58317, 6543,45248,65475,    0,51180,54845,50968,50111, 7623,  128,65408,    0,
 22.1347 +57326,65533,65023,50159, 7647,   96,65475,    0,57324,65533,65023,50159, 7647,16480,65475,    0,
 22.1348 +57324,65533,65023,50175, 7631,  128,65475,    0,65516,64639,65535,12283,32895,65375,    0,   12,
 22.1349 +65534,65535,65535, 2047,32767, 1023,    0,    0, 9622,65264,60590,15359, 8223,13311,    0,    0,
 22.1350 +    1,    0, 1023,    0,65279,65535, 2047,65534, 3843,65279,65535, 8191,    0,    0,    0,    0,
 22.1351 +65535,65535,63227,  327, 1023, 1023,    0,    0,    0,    0,65535,65535,   63,65535,65535,  127,
 22.1352 +65535,65535,65535,65535,65535,33791,65535,65535,65535,65535,65287,65535,65535,65535,65535, 1023,
 22.1353 +65407,65535,65535,65535,15743,15743,65535,65535,15743,65535,32767,32573,32573,65407,32767,65535,
 22.1354 +32767,32573,65535,65535,65407, 2047,65024,    3,    0,    0,65535,65535,65535,65535,65535,   31,
 22.1355 +65534,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,
 22.1356 +65535,65535,65535,65535,65535,65535,40959,  127,65534, 2047,65535,65535,65535,65535, 2047,    0,
 22.1357 +    0,    0,    0,    0,    0,    0,    0,    0,65535,65535,65535,65535,  511,    0, 1023,    0,
 22.1358 +    0, 1023,65535,65535,65527,65535,65535,  255,65535,65535, 1023,    0,    0,    0,    0,    0,
 22.1359 +65535,65535,65535,65535,65535,65535,65535,65535,65535, 4095,65535,65535,65535,65535,65535, 1023,
 22.1360 +65535,16191,65535,65535,16191,43775,65535,16383,65535,65535,65535,24543, 8156, 4047, 8191, 8156,
 22.1361 +    0,    0,    0,    0,    0,    0,    0,32768,    0,    0,    0,    0,    0,    0,    0,    0,
 22.1362 +64644,15919,48464, 1019,    0,    0,65535,65535,   15,    0,    0,    0,    0,    0,    0,    0,
 22.1363 +  192,    0, 1022, 1792,65534,65535,65535,65535,65535,   31,65534,65535,65535,65535,65535, 2047,
 22.1364 +65504,65535, 8191,65534,65535,65535,65535,65535,32767,    0,65535,  255,    0,    0,    0,    0,
 22.1365 +65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,   63,    0,    0,    0,    0,
 22.1366 +65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,   63,    0,    0,    0,    0,    0,
 22.1367 +65535,65535,65535,65535,65535,65535,65535,65535, 8191,    0,    0,    0,    0,    0,    0,    0,
 22.1368 +65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,   15,    0,    0,    0,    0,    0,
 22.1369 +65535,65535,16383,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
 22.1370 +  127,41208,65023,24447,65499,65535,65535,65535,65535,65535,65535,    3,    0,65528,65535,65535,
 22.1371 +65535,65535,65535,16383,    0,65535,65535,65535,65535,65532,65535,65535,  255,    0,    0, 4095,
 22.1372 +    0,    0,    0,    0,    0,    0,    0,65495,65535,65535,65535,65535,65535,65535,65535, 8191,
 22.1373 +    0, 1023,65534, 2047,65534, 2047,65472,65534,65535,16383,65535,32767,64764, 7420,    0,    0};
 22.1374 +
 22.1375 +const UInt16 UnicodeAlphaBits[] = {
 22.1376 +  256,    1,  272,  288,  304,  320,  336,  352,    0,  368,  384,  400,  416,  432,  448,  464,
 22.1377 +  480,  496,  512,  528,  544,    1,  560,  576,  592,    0,    0,    0,    0,    0,  608,  624,
 22.1378 +  640,  656,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
 22.1379 +  672,  688,    0,    0,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
 22.1380 +    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,  704,    1,    1,
 22.1381 +    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
 22.1382 +    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
 22.1383 +    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
 22.1384 +    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
 22.1385 +    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,  720,
 22.1386 +    1,    1,    1,    1,  736,    0,    0,    0,    0,    0,    0,    0,    1,    1,    1,    1,
 22.1387 +    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
 22.1388 +    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
 22.1389 +    1,    1,    1,    1,    1,    1,    1,  752,    0,    0,    0,    0,    0,    0,    0,    0,
 22.1390 +    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
 22.1391 +    0,    0,    0,    0,    0,    0,    0,    0,    0,    1,  768,  784,    1,  800,  816,  832,
 22.1392 +    0,    0,    0,    0,65534, 2047,65534, 2047,    0,    0,    0,    0,65535,65407,65535,65407,
 22.1393 +65535,65535,65532,   15,    0,65535,65535,65535,65535,65535,16383,63999,    3,    0,16415,    0,
 22.1394 +    0,    0,    0,    0,   32,    0,    0, 1024,55104,65535,65531,65535,32767,64767,65535,   15,
 22.1395 +65535,65535,65535,65535,65535,65535,65535,65535,61443,65535,65535,65535, 6559,65535,65535,  831,
 22.1396 +    0,    0,    0,65534,65535,  639,65534,65535,  255,    0,    0,    0,    0,65535, 2047,    7,
 22.1397 +    0,    0,65534, 2047,65534,   63,    0,65535,65535,65535,65535,65535,65535, 8175, 8702, 7168,
 22.1398 +    0,65535, 8191,65535,    0,    0,    0,    0,65535,65535,65535,    1,    0,    0,    0,    0,
 22.1399 +65518,65535,65535,58367, 8191,65281,   15,    0,40942,65529,65023,50117, 6559,45184,   15,    3,
 22.1400 +34788,65529,65023,50029, 6535,24064,    0,   31,45038,65531,65023,58349, 7103,    1,    1,    0,
 22.1401 +40942,65529,65023,58317, 6543,45248,    3,    0,51180,54845,50968,50111, 7623,  128,    0,    0,
 22.1402 +57326,65533,65023,50159, 7647,   96,    3,    0,57324,65533,65023,50159, 7647,16480,    3,    0,
 22.1403 +57324,65533,65023,50175, 7631,  128,    3,    0,65516,64639,65535,12283,32895,65375,    0,   12,
 22.1404 +65534,65535,65535, 2047,32767,    0,    0,    0, 9622,65264,60590,15359, 8223,12288,    0,    0,
 22.1405 +    1,    0,    0,    0,65279,65535, 2047,65534, 3843,65279,65535, 8191,    0,    0,    0,    0,
 22.1406 +65535,65535,63227,  327,    0, 1023,    0,    0,    0,    0,65535,65535,   63,65535,65535,  127,
 22.1407 +65535,65535,65535,65535,65535,33791,65535,65535,65535,65535,65287,65535,65535,65535,65535, 1023,
 22.1408 +65407,65535,65535,65535,15743,15743,65535,65535,15743,65535,32767,32573,32573,65407,32767,65535,
 22.1409 +32767,32573,65535,65535,65407, 2047,    0,    0,    0,    0,65535,65535,65535,65535,65535,   31,
 22.1410 +65534,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,
 22.1411 +65535,65535,65535,65535,65535,65535,40959,  127,65534, 2047,65535,65535,65535,65535, 2047,    0,
 22.1412 +    0,    0,    0,    0,    0,    0,    0,    0,65535,65535,65535,65535,  511,    0,    0,    0,
 22.1413 +    0,    0,65535,65535,65527,65535,65535,  255,65535,65535, 1023,    0,    0,    0,    0,    0,
 22.1414 +65535,65535,65535,65535,65535,65535,65535,65535,65535, 4095,65535,65535,65535,65535,65535, 1023,
 22.1415 +65535,16191,65535,65535,16191,43775,65535,16383,65535,65535,65535,24543, 8156, 4047, 8191, 8156,
 22.1416 +    0,    0,    0,    0,    0,    0,    0,32768,    0,    0,    0,    0,    0,    0,    0,    0,
 22.1417 +64644,15919,48464, 1019,    0,    0,65535,65535,   15,    0,    0,    0,    0,    0,    0,    0,
 22.1418 +  192,    0, 1022, 1792,65534,65535,65535,65535,65535,   31,65534,65535,65535,65535,65535, 2047,
 22.1419 +65504,65535, 8191,65534,65535,65535,65535,65535,32767,    0,65535,  255,    0,    0,    0,    0,
 22.1420 +65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,   63,    0,    0,    0,    0,
 22.1421 +65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,   63,    0,    0,    0,    0,    0,
 22.1422 +65535,65535,65535,65535,65535,65535,65535,65535, 8191,    0,    0,    0,    0,    0,    0,    0,
 22.1423 +65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,   15,    0,    0,    0,    0,    0,
 22.1424 +65535,65535,16383,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
 22.1425 +  127,41208,65023,24447,65499,65535,65535,65535,65535,65535,65535,    3,    0,65528,65535,65535,
 22.1426 +65535,65535,65535,16383,    0,65535,65535,65535,65535,65532,65535,65535,  255,    0,    0, 4095,
 22.1427 +    0,    0,    0,    0,    0,    0,    0,65495,65535,65535,65535,65535,65535,65535,65535, 8191,
 22.1428 +    0,    0,65534, 2047,65534, 2047,65472,65534,65535,16383,65535,32767,64764, 7420,    0,    0};
 22.1429 +
 22.1430 +const UInt16 UnicodeDigitBits[] = {
 22.1431 +  256,    0,    0,    0,    0,    0,  272,    0,    0,  288,  304,  320,  336,  352,  368,  384,
 22.1432 +  400,    0,    0,  416,    0,    0,    0,  432,  448,    0,    0,    0,    0,    0,    0,    0,
 22.1433 +    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
 22.1434 +    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
 22.1435 +    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
 22.1436 +    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
 22.1437 +    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
 22.1438 +    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
 22.1439 +    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
 22.1440 +    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
 22.1441 +    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
 22.1442 +    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
 22.1443 +    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
 22.1444 +    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
 22.1445 +    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
 22.1446 +    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,  464,
 22.1447 +    0,    0,    0, 1023,    0,    0,    0,    0,    0,    0,    0,  524,    0,    0,    0,    0,
 22.1448 +    0,    0,    0,    0,    0,    0, 1023,    0,    0,    0,    0,    0,    0,    0,    0, 1023,
 22.1449 +    0,    0,    0,    0,    0,    0,65472,    0,    0,    0,    0,    0,    0,    0,65472,    0,
 22.1450 +    0,    0,    0,    0,    0,    0,65472,    0,    0,    0,    0,    0,    0,    0,65472,    0,
 22.1451 +    0,    0,    0,    0,    0,    0,65472,    0,    0,    0,    0,    0,    0,    0,65408,    0,
 22.1452 +    0,    0,    0,    0,    0,    0,65472,    0,    0,    0,    0,    0,    0,    0,65472,    0,
 22.1453 +    0,    0,    0,    0,    0,    0,65472,    0,    0,    0,    0,    0,    0,    0,    0,    0,
 22.1454 +    0,    0,    0,    0,    0, 1023,    0,    0,    0,    0,    0,    0,    0, 1023,    0,    0,
 22.1455 +    0,    0, 1023,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
 22.1456 +    0,    0,    0,    0, 1023,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
 22.1457 +    0,    0,    0,    0,    0,    0,65024,    3,    0,    0,    0,    0,    0,    0,    0,    0,
 22.1458 +    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0, 1023,    0,
 22.1459 +    0, 1023,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
 22.1460 +    0, 1023,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0};
 22.1461 +
 22.1462 +const UInt16 UnicodeSpaceBits[] = {
 22.1463 +  256,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
 22.1464 +    0,    0,    0,    0,    0,    0,  272,    0,    0,    0,    0,    0,    0,    0,    0,    0,
 22.1465 +  288,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
 22.1466 +  304,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
 22.1467 +    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
 22.1468 +    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
 22.1469 +    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
 22.1470 +    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
 22.1471 +    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
 22.1472 +    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
 22.1473 +    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
 22.1474 +    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
 22.1475 +    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
 22.1476 +    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
 22.1477 +    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
 22.1478 +    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
 22.1479 +15872,    0,    1,    0,    0,    0,    0,    0,    0,    0,    1,    0,    0,    0,    0,    0,
 22.1480 +    0,    0,    0,    0,    0,    0,    0,    0,    1,    0,    0,    0,    0,    0,    0,    0,
 22.1481 + 4095,    0,33536,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
 22.1482 +    1,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0};
 22.1483 +
 22.1484 +const UInt16 UnicodeXDigitBits[] = {
 22.1485 +  256,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
 22.1486 +    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
 22.1487 +    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
 22.1488 +    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
 22.1489 +    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
 22.1490 +    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
 22.1491 +    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
 22.1492 +    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
 22.1493 +    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
 22.1494 +    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
 22.1495 +    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
 22.1496 +    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
 22.1497 +    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
 22.1498 +    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
 22.1499 +    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
 22.1500 +    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,  272,
 22.1501 +    0,    0,    0, 1023,  126,    0,  126,    0,    0,    0,    0,    0,    0,    0,    0,    0,
 22.1502 +    0, 1023,  126,    0,  126,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0};
 22.1503 +
 22.1504 +// Uncomment if necessary
 22.1505 +//const UInt16 UnicodeCntrlBits[] = {
 22.1506 +//  256,    0,    0,    0,    0,    0,    0,  272,    0,    0,    0,    0,    0,    0,    0,    0,
 22.1507 +//    0,    0,    0,    0,    0,    0,    0,    0,  288,    0,    0,    0,    0,    0,    0,    0,
 22.1508 +//  304,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
 22.1509 +//    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
 22.1510 +//    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
 22.1511 +//    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
 22.1512 +//    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
 22.1513 +//    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
 22.1514 +//    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
 22.1515 +//    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
 22.1516 +//    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
 22.1517 +//    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
 22.1518 +//    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
 22.1519 +//    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
 22.1520 +//    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
 22.1521 +//    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,  320,  336,
 22.1522 +//65535,65535,    0,    0,    0,    0,    0,32768,65535,65535,    0,    0,    0,    0,    0,    0,
 22.1523 +//32768,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
 22.1524 +//30720,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
 22.1525 +//61440,    0,31744,    0,    0,    0,64512,    0,    0,    0,    0,    0,    0,    0,    0,    0,
 22.1526 +//    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,32768,
 22.1527 +//    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0, 3584};
 22.1528 +//
 22.1529 +//const UInt16 UnicodeGraphBits[] = {
 22.1530 +//  256,    1,  272,  288,  304,  320,  336,  352,    0,  368,  384,  400,  416,  432,  448,  464,
 22.1531 +//  480,  496,  512,  528,  544,    1,  560,  576,  592,    0,    0,    0,    0,    0,  608,  624,
 22.1532 +//  640,  656,    0,  672,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
 22.1533 +//  688,  704,    0,    0,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
 22.1534 +//    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,  720,    1,    1,
 22.1535 +//    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
 22.1536 +//    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
 22.1537 +//    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
 22.1538 +//    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
 22.1539 +//    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,  736,
 22.1540 +//    1,    1,    1,    1,  752,    0,    0,    0,    0,    0,    0,    0,    1,    1,    1,    1,
 22.1541 +//    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
 22.1542 +//    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
 22.1543 +//    1,    1,    1,    1,    1,    1,    1,  768,    0,    0,    0,    0,    0,    0,    0,    0,
 22.1544 +//    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
 22.1545 +//    0,    0,    0,    0,    0,    0,    0,    0,    0,    1,  784,  800,    1,  816,  832,  848,
 22.1546 +//    0,    0,65534,65535,65535,65535,65535,32767,    0,    0,65534,65535,65535,65535,65535,65535,
 22.1547 +//65535,65535,65532,   15,    0,65535,65535,65535,65535,65535,16383,63999,    3,    0,16415,    0,
 22.1548 +//    0,    0,    0,    0,   32,    0,    0,17408,55232,65535,65531,65535,32767,64767,65535,   15,
 22.1549 +//65535,65535,65535,65535,65535,65535,65535,65535,61443,65535,65535,65535, 6559,65535,65535,  831,
 22.1550 +//    0,    0,    0,65534,65535,65151,65534,65535, 1791,    0,    0,16384,    9,65535, 2047,   31,
 22.1551 +// 4096,34816,65534, 2047,65534,   63,16383,65535,65535,65535,65535,65535,65535, 8191, 8702, 8191,
 22.1552 +//16383,65535, 8191,65535,    0,    0,    0,    0,65535,65535,65535,    1,    0,    0,    0,    0,
 22.1553 +//65518,65535,65535,58367, 8191,65281,65535,    1,40942,65529,65023,50117, 6559,45184,65487,    3,
 22.1554 +//34788,65529,65023,50029, 6535,24064,65472,   31,45038,65531,65023,58349, 7103,    1,65473,    0,
 22.1555 +//40942,65529,65023,58317, 6543,45248,65475,    0,51180,54845,50968,50111, 7623,  128,65408,    0,
 22.1556 +//57326,65533,65023,50159, 7647,   96,65475,    0,57324,65533,65023,50159, 7647,16480,65475,    0,
 22.1557 +//57324,65533,65023,50175, 7631,  128,65475,    0,65516,64639,65535,12283,32895,65375,    0,   28,
 22.1558 +//65534,65535,65535, 2047,65535, 4095,    0,    0, 9622,65264,60590,15359, 8223,13311,    0,    0,
 22.1559 +//65521,    7, 1023,15360,65279,65535, 2047,65534, 3875,65279,65535, 8191,    0,    0,    0,    0,
 22.1560 +//65535,65535,63227,  327,65535, 1023,    0,    0,    0,    0,65535,65535,   63,65535,65535, 2175,
 22.1561 +//65535,65535,65535,65535,65535,33791,65535,65535,65535,65535,65287,65535,65535,65535,65535, 1023,
 22.1562 +//65407,65535,65535,65535,15743,15743,65535,65535,15743,65535,32767,32573,32573,65407,32767,65535,
 22.1563 +//32767,32573,65535,65535,65407, 2047,65534,    3,    0,    0,65535,65535,65535,65535,65535,   31,
 22.1564 +//65534,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,
 22.1565 +//65535,65535,65535,65535,65535,65535,65535,  127,65534, 8191,65535,65535,65535,65535,16383,    0,
 22.1566 +//    0,    0,    0,    0,    0,    0,    0,    0,65535,65535,65535,65535,  511, 6128, 1023,    0,
 22.1567 +// 2047, 1023,65535,65535,65527,65535,65535,  255,65535,65535, 1023,    0,    0,    0,    0,    0,
 22.1568 +//65535,65535,65535,65535,65535,65535,65535,65535,65535, 4095,65535,65535,65535,65535,65535, 1023,
 22.1569 +//65535,16191,65535,65535,16191,43775,65535,16383,65535,65535,65535,24543, 8156, 4047, 8191, 8156,
 22.1570 +//    0,65535,  255,65535,16239,    0,    0,57344,24576,    0,    0,    0,    0,    0,    0,    0,
 22.1571 +//64644,15919,48464, 1019,    0,    0,65535,65535,   15,    0,    0,    0,    0,    0,    0,    0,
 22.1572 +//    0,    0, 1536,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
 22.1573 +//65486,65523, 1022, 1793,65534,65535,65535,65535,65535,   31,65534,65535,65535,65535,65535, 4095,
 22.1574 +//65504,65535, 8191,65534,65535,65535,65535,65535,32767,    0,65535,  255,    0,    0,    0,    0,
 22.1575 +//65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,   63,    0,    0,    0,    0,
 22.1576 +//65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,   63,    0,    0,    0,    0,    0,
 22.1577 +//65535,65535,65535,65535,65535,65535,65535,65535, 8191,    0,    0,    0,    0,    0,    0,    0,
 22.1578 +//65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,   15,    0,    0,    0,    0,    0,
 22.1579 +//65535,65535,16383,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
 22.1580 +//  127,41208,65023,24447,65499,65535,65535,65535,65535,65535,65535,    3,    0,65528,65535,65535,
 22.1581 +//65535,65535,65535,65535,    0,65535,65535,65535,65535,65532,65535,65535,  255,    0,    0, 4095,
 22.1582 +//    0,    0,    0,65535,65055,65527, 3339,65495,65535,65535,65535,65535,65535,65535,65535, 8191,
 22.1583 +//63470,36863,65535,49151,65534,12287,65534,65534,65535,16383,65535,32767,64764, 7420,    0,    0};
 22.1584 +//
 22.1585 +//const UInt16 UnicodePrintBits[] = {
 22.1586 +//  256,    1,  272,  288,  304,  320,  336,  352,    0,  368,  384,  400,  416,  432,  448,  464,
 22.1587 +//  480,  496,  512,  528,  544,    1,  560,  576,  592,    0,    0,    0,    0,    0,  608,  624,
 22.1588 +//  640,  656,    0,  672,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
 22.1589 +//  688,  704,    0,    0,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
 22.1590 +//    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,  720,    1,    1,
 22.1591 +//    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
 22.1592 +//    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
 22.1593 +//    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
 22.1594 +//    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
 22.1595 +//    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,  736,
 22.1596 +//    1,    1,    1,    1,  752,    0,    0,    0,    0,    0,    0,    0,    1,    1,    1,    1,
 22.1597 +//    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
 22.1598 +//    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
 22.1599 +//    1,    1,    1,    1,    1,    1,    1,  768,    0,    0,    0,    0,    0,    0,    0,    0,
 22.1600 +//    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
 22.1601 +//    0,    0,    0,    0,    0,    0,    0,    0,    0,    1,  784,  800,    1,  816,  832,  848,
 22.1602 +//  512,    0,65535,65535,65535,65535,65535,32767,    0,    0,65535,65535,65535,65535,65535,65535,
 22.1603 +//65535,65535,65532,   15,    0,65535,65535,65535,65535,65535,16383,63999,    3,    0,16415,    0,
 22.1604 +//    0,    0,    0,    0,   32,    0,    0,17408,55232,65535,65531,65535,32767,64767,65535,   15,
 22.1605 +//65535,65535,65535,65535,65535,65535,65535,65535,61443,65535,65535,65535, 6559,65535,65535,  831,
 22.1606 +//    0,    0,    0,65534,65535,65151,65534,65535, 1791,    0,    0,16384,    9,65535, 2047,   31,
 22.1607 +// 4096,34816,65534, 2047,65534,   63,16383,65535,65535,65535,65535,65535,65535, 8191, 8702, 8191,
 22.1608 +//16383,65535, 8191,65535,    0,    0,    0,    0,65535,65535,65535,    1,    0,    0,    0,    0,
 22.1609 +//65518,65535,65535,58367, 8191,65281,65535,    1,40942,65529,65023,50117, 6559,45184,65487,    3,
 22.1610 +//34788,65529,65023,50029, 6535,24064,65472,   31,45038,65531,65023,58349, 7103,    1,65473,    0,
 22.1611 +//40942,65529,65023,58317, 6543,45248,65475,    0,51180,54845,50968,50111, 7623,  128,65408,    0,
 22.1612 +//57326,65533,65023,50159, 7647,   96,65475,    0,57324,65533,65023,50159, 7647,16480,65475,    0,
 22.1613 +//57324,65533,65023,50175, 7631,  128,65475,    0,65516,64639,65535,12283,32895,65375,    0,   28,
 22.1614 +//65534,65535,65535, 2047,65535, 4095,    0,    0, 9622,65264,60590,15359, 8223,13311,    0,    0,
 22.1615 +//65521,    7, 1023,15360,65279,65535, 2047,65534, 3875,65279,65535, 8191,    0,    0,    0,    0,
 22.1616 +//65535,65535,63227,  327,65535, 1023,    0,    0,    0,    0,65535,65535,   63,65535,65535, 2175,
 22.1617 +//65535,65535,65535,65535,65535,33791,65535,65535,65535,65535,65287,65535,65535,65535,65535, 1023,
 22.1618 +//65407,65535,65535,65535,15743,15743,65535,65535,15743,65535,32767,32573,32573,65407,32767,65535,
 22.1619 +//32767,32573,65535,65535,65407, 2047,65534,    3,    0,    0,65535,65535,65535,65535,65535,   31,
 22.1620 +//65534,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,
 22.1621 +//65535,65535,65535,65535,65535,65535,65535,  127,65534, 8191,65535,65535,65535,65535,16383,    0,
 22.1622 +//    0,    0,    0,    0,    0,    0,    0,    0,65535,65535,65535,65535,  511, 6128, 1023,    0,
 22.1623 +// 2047, 1023,65535,65535,65527,65535,65535,  255,65535,65535, 1023,    0,    0,    0,    0,    0,
 22.1624 +//65535,65535,65535,65535,65535,65535,65535,65535,65535, 4095,65535,65535,65535,65535,65535, 1023,
 22.1625 +//65535,16191,65535,65535,16191,43775,65535,16383,65535,65535,65535,24543, 8156, 4047, 8191, 8156,
 22.1626 +//    0,65535,  255,65535,16239,    0,    0,57344,24576,    0,    0,    0,    0,    0,    0,    0,
 22.1627 +//64644,15919,48464, 1019,    0,    0,65535,65535,   15,    0,    0,    0,    0,    0,    0,    0,
 22.1628 +//    0,    0, 1536,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
 22.1629 +//65487,65523, 1022, 1793,65534,65535,65535,65535,65535,   31,65534,65535,65535,65535,65535, 4095,
 22.1630 +//65504,65535, 8191,65534,65535,65535,65535,65535,32767,    0,65535,  255,    0,    0,    0,    0,
 22.1631 +//65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,   63,    0,    0,    0,    0,
 22.1632 +//65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,   63,    0,    0,    0,    0,    0,
 22.1633 +//65535,65535,65535,65535,65535,65535,65535,65535, 8191,    0,    0,    0,    0,    0,    0,    0,
 22.1634 +//65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,   15,    0,    0,    0,    0,    0,
 22.1635 +//65535,65535,16383,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
 22.1636 +//  127,41208,65023,24447,65499,65535,65535,65535,65535,65535,65535,    3,    0,65528,65535,65535,
 22.1637 +//65535,65535,65535,65535,    0,65535,65535,65535,65535,65532,65535,65535,  255,    0,    0, 4095,
 22.1638 +//    0,    0,    0,65535,65055,65527, 3339,65495,65535,65535,65535,65535,65535,65535,65535,40959,
 22.1639 +//63470,36863,65535,49151,65534,12287,65534,65534,65535,16383,65535,32767,64764, 7420,    0,    0};
 22.1640 +//
 22.1641 +//const UInt16 UnicodePunctBits[] = {
 22.1642 +//  256,    0,    0,  272,    0,  288,  304,  320,    0,  336,    0,    0,    0,  352,  368,  384,
 22.1643 +//  400,    0,    0,  416,    0,    0,  432,  448,  464,    0,    0,    0,    0,    0,    0,    0,
 22.1644 +//  480,    0,    0,  496,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
 22.1645 +//  512,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
 22.1646 +//    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
 22.1647 +//    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
 22.1648 +//    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
 22.1649 +//    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
 22.1650 +//    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
 22.1651 +//    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
 22.1652 +//    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
 22.1653 +//    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
 22.1654 +//    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
 22.1655 +//    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
 22.1656 +//    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
 22.1657 +//    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,  528,  544,  560,
 22.1658 +//    0,    0,65534,64512,    1,63488,    1,30720,    0,    0,65534,65535,    0,  128,    0,  128,
 22.1659 +//    0,    0,    0,    0,    0,    0,    0,16384,  128,    0,    0,    0,    0,    0,    0,    0,
 22.1660 +//    0,    0,    0,    0,    0,64512,    0,    0, 1536,    0,    0,16384,    9,    0,    0,   24,
 22.1661 +// 4096,34816,    0,    0,    0,    0,15360,    0,    0,    0,    0,    0,    0,   16,    0,    0,
 22.1662 +//16383,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
 22.1663 +//    0,    0,    0,    0,    0,    0,   48,    1,    0,    0,    0,    0,    0,    0,    0,    0,
 22.1664 +//    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,   16,
 22.1665 +//    0,    0,    0,    0,32768, 3072,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
 22.1666 +//65520,    7,    0,15360,    0,    0,    0,    0,   32,    0,    0,    0,    0,    0,    0,    0,
 22.1667 +//    0,    0,    0,    0,64512,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0, 2048,
 22.1668 +//    0,    0,    0,    0,    0,    0,  510,    0,    0,    0,    0,    0,    0,    0,    0,    0,
 22.1669 +//    0,    0,    0,    0,    0,    0,24576,    0,    0, 6144,    0,    0,    0,    0,14336,    0,
 22.1670 +//    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0, 6128,    0,    0,
 22.1671 +// 2047,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
 22.1672 +//    0,65535,  255,65535,16239,    0,    0,24576,24576,    0,    0,    0,    0,    0,    0,    0,
 22.1673 +//    0,    0, 1536,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
 22.1674 +//65294,65523,    0,    1,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0, 2048,
 22.1675 +//    0,    0,    0,49152,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
 22.1676 +//    0,    0,    0,65535,65055,65527, 3339,    0,    0,    0,    0,    0,    0,    0,    0,    0,
 22.1677 +//63470,35840,    1,47104,    0,10240,   62,    0,    0,    0,    0,    0,    0,    0,    0,    0};
 22.1678 +//
 22.1679 +//const UInt16 UnicodeLowerBits[] = {
 22.1680 +//  256,  272,  288,  304,  320,  336,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
 22.1681 +//    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,  352,  368,
 22.1682 +//  384,  400,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
 22.1683 +//    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
 22.1684 +//    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
 22.1685 +//    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
 22.1686 +//    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
 22.1687 +//    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
 22.1688 +//    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
 22.1689 +//    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
 22.1690 +//    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
 22.1691 +//    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
 22.1692 +//    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
 22.1693 +//    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
 22.1694 +//    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
 22.1695 +//    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,  416,    0,    0,    0,  432,
 22.1696 +//    0,    0,    0,    0,    0,    0,65534, 2047,    0,    0,    0,    0,    0,32768,65535,65407,
 22.1697 +//43690,43690,43690,21930,43861,43690,43690,54442,12585,20004,11562,58961,23392,46421,43690,43565,
 22.1698 +//43690,43690,43688,   10,    0,65535,65535,65535,65535,65535,16383,    0,    0,    0,    0,    0,
 22.1699 +//    0,    0,    0,    0,    0,    0,    0,    0,    0,    1,61440,65535,32767,43235,43690,   15,
 22.1700 +//    0,    0,    0,65535,65535,65535,43690,43690,40962,43690,43690,43690, 4372,43690,43690,  554,
 22.1701 +//    0,    0,    0,    0,    0,    0,65534,65535,  255,    0,    0,    0,    0,    0,    0,    0,
 22.1702 +//43690,43690,43690,43690,43690,43690,43690,43690,43690, 4074,43690,43690,43690,43690,43690,  682,
 22.1703 +//  255,   63,  255,  255,   63,  255,  255,16383,65535,65535,65535,20703, 4316,  207,  255, 4316,
 22.1704 +//    0,    0,    0,    0,    0,    0,    0,32768,    0,    0,    0,    0,    0,    0,    0,    0,
 22.1705 +//50176,    8,32768,  528,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
 22.1706 +//  127,  248,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
 22.1707 +//    0,    0,    0,    0,65534, 2047,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0};
 22.1708 +//
 22.1709 +//const UInt16 UnicodeUpperBits[] = {
 22.1710 +//  256,  272,  288,  304,  320,  336,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
 22.1711 +//  352,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,  368,  384,
 22.1712 +//    0,  400,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
 22.1713 +//    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
 22.1714 +//    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
 22.1715 +//    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
 22.1716 +//    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
 22.1717 +//    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
 22.1718 +//    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
 22.1719 +//    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
 22.1720 +//    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
 22.1721 +//    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
 22.1722 +//    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
 22.1723 +//    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
 22.1724 +//    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
 22.1725 +//    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,  416,
 22.1726 +//    0,    0,    0,    0,65534, 2047,    0,    0,    0,    0,    0,    0,65535,32639,    0,    0,
 22.1727 +//21845,21845,21845,43605,21674,21845,21845,11093,52950,45531,53973, 4526,44464,19114,21845,21974,
 22.1728 +//21845,21845,21844,    5,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
 22.1729 +//    0,    0,    0,    0,    0,    0,    0,    0,55104,65534, 4091,    0,    0,21532,21845,    0,
 22.1730 +//65535,65535,65535,    0,    0,    0,21845,21845,20481,21845,21845,21845, 2187,21845,21845,  277,
 22.1731 +//    0,    0,    0,65534,65535,  127,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
 22.1732 +//    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,65535,65535,   63,    0,    0,    0,
 22.1733 +//21845,21845,21845,21845,21845,21845,21845,21845,21845,   21,21845,21845,21845,21845,21845,  341,
 22.1734 +//65280,16128,65280,65280,16128,43520,65280,    0,65280,65280,65280, 7936, 7936, 3840, 7936, 7936,
 22.1735 +//14468,15911,15696,   11,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
 22.1736 +//    0,    0,65534, 2047,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0};
 22.1737 +
 22.1738 +
 22.1739 +// MA: March 19, 2010
 22.1740 +// Modified ToUpper and ToLower tables to match values expected by AS3 tests.
 22.1741 +// ToLower modifications:
 22.1742 +//    304 ->  105
 22.1743 +//   1024 -> 1104 *
 22.1744 +//   1037 -> 1117 * 
 22.1745 +// UoUpper modifications:
 22.1746 +//    255 ->  376
 22.1747 +//    305 ->   73
 22.1748 +//    383 ->   83
 22.1749 +//   1104 -> 1024 *
 22.1750 +//   1117 -> 1037 *
 22.1751 +// Entries marked with a '*' don't make complete sense based on Unicode manual, although
 22.1752 +// they match AS3.
 22.1753 +
 22.1754 +
 22.1755 +static const UInt16 UnicodeToUpperBits[] = {
 22.1756 +  256,  272,  288,  304,  320,  336,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
 22.1757 +    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,  352,  368,
 22.1758 +    0,  384,    0,    0,  400,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
 22.1759 +    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
 22.1760 +    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
 22.1761 +    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
 22.1762 +    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
 22.1763 +    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
 22.1764 +    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
 22.1765 +    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
 22.1766 +    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
 22.1767 +    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
 22.1768 +    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
 22.1769 +    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
 22.1770 +    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
 22.1771 +    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,  416,
 22.1772 +    0,    0,    0,    0,    0,    0,65534, 2047,    0,    0,    0,    0,    0,    0,65535,65407,
 22.1773 +43690,43690,43690,21674,43349,43690,43690,54442, 4392,  516, 8490, 8785,21056,46421,43690,43048, // MA: Modified for AS3.
 22.1774 +43690,  170,    0,    0,    0, 2776,33545,   36, 3336,    4,    0,    0,    0,    0,    0,    0,
 22.1775 +    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,61440,65534,32767,    0,43688,    0,
 22.1776 +    0,    0,    0,65535,65535,65535,43690,43690,    2,43690,43690,43690, 4372,43690,35498,  554, // MA: Modified for AS3.
 22.1777 +    0,    0,    0,    0,    0,    0,65534,65535,  127,    0,    0,    0,    0,    0,    0,    0,
 22.1778 +43690,43690,43690,43690,43690,43690,43690,43690,43690,   42,43690,43690,43690,43690,43690,  682,
 22.1779 +  255,   63,  255,  255,   63,  170,  255,16383,    0,    0,    0,    3,    0,    3,   35,    0,
 22.1780 +    0,    0,    0,    0,    0,    0,    0,65535,    0,    0,    0,    0,    0,    0,    0,    0,
 22.1781 +    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,65535, 1023,    0,
 22.1782 +    0,    0,    0,    0,65534, 2047,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0};
 22.1783 +
 22.1784 +static const UInt16 UnicodeToLowerBits[] = {
 22.1785 +  256,  272,  288,  304,  320,  336,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
 22.1786 +  352,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,  368,  384,
 22.1787 +    0,  400,    0,    0,  416,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
 22.1788 +    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
 22.1789 +    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
 22.1790 +    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
 22.1791 +    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
 22.1792 +    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
 22.1793 +    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
 22.1794 +    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
 22.1795 +    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
 22.1796 +    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
 22.1797 +    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
 22.1798 +    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
 22.1799 +    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
 22.1800 +    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,  432,
 22.1801 +    0,    0,    0,    0,65534, 2047,    0,    0,    0,    0,    0,    0,65535,32639,    0,    0,
 22.1802 +21845,21845,21845,43605,21674,21845,21845,11093,52950,45531,53909, 4526,42128,19114,21845,21522,// MA: Modidied for AS3.
 22.1803 +21845,   85,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
 22.1804 +    0,    0,    0,    0,    0,    0,    0,    0,55104,65534, 4091,    0,    0,    0,21844,    0,
 22.1805 +65535,65535,65535,    0,    0,    0,21845,21845,    1,21845,21845,21845, 2186,21845,17749,  277,
 22.1806 +    0,    0,    0,65534,65535,  127,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
 22.1807 +    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,65535,65535,   63,    0,    0,    0,
 22.1808 +21845,21845,21845,21845,21845,21845,21845,21845,21845,   21,21845,21845,21845,21845,21845,  341,
 22.1809 +65280,16128,65280,65280,16128,43520,65280,    0,    0,    0,    0, 3840, 3840, 3840, 7936, 3840,
 22.1810 +    0,    0,    0,    0,    0,    0,65535,    0,    0,    0,    0,    0,    0,    0,    0,    0,
 22.1811 +    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,65472,65535,    0,    0,    0,
 22.1812 +    0,    0,65534, 2047,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0};
 22.1813 +
 22.1814 +struct GUnicodePairType
 22.1815 +{
 22.1816 +    UInt16 Key, Value;
 22.1817 +};
 22.1818 +
 22.1819 +static inline bool CmpUnicodeKey(const GUnicodePairType& a, UInt16 key)
 22.1820 +{
 22.1821 +    return a.Key < key;
 22.1822 +}
 22.1823 +
 22.1824 +static const GUnicodePairType UnicodeToUpperTable[] = {
 22.1825 +{   97,   65}, {   98,   66}, {   99,   67}, {  100,   68}, {  101,   69}, {  102,   70}, {  103,   71},
 22.1826 +{  104,   72}, {  105,   73}, {  106,   74}, {  107,   75}, {  108,   76}, {  109,   77}, {  110,   78},
 22.1827 +{  111,   79}, {  112,   80}, {  113,   81}, {  114,   82}, {  115,   83}, {  116,   84}, {  117,   85},
 22.1828 +{  118,   86}, {  119,   87}, {  120,   88}, {  121,   89}, {  122,   90}, {  224,  192}, {  225,  193},
 22.1829 +{  226,  194}, {  227,  195}, {  228,  196}, {  229,  197}, {  230,  198}, {  231,  199}, {  232,  200},
 22.1830 +{  233,  201}, {  234,  202}, {  235,  203}, {  236,  204}, {  237,  205}, {  238,  206}, {  239,  207},
 22.1831 +{  240,  208}, {  241,  209}, {  242,  210}, {  243,  211}, {  244,  212}, {  245,  213}, {  246,  214},
 22.1832 +{  248,  216}, {  249,  217}, {  250,  218}, {  251,  219}, {  252,  220}, {  253,  221}, {  254,  222},
 22.1833 +{  255,  376}, {  257,  256}, {  259,  258}, {  261,  260}, {  263,  262}, {  265,  264}, {  267,  266},
 22.1834 +{  269,  268}, {  271,  270}, {  273,  272}, {  275,  274}, {  277,  276}, {  279,  278}, {  281,  280},
 22.1835 +{  283,  282}, {  285,  284}, {  287,  286}, {  289,  288}, {  291,  290}, {  293,  292}, {  295,  294},
 22.1836 +{  297,  296}, {  299,  298}, {  301,  300}, {  303,  302}, {  305,   73}, {  307,  306}, {  309,  308}, {  311,  310},
 22.1837 +{  314,  313}, {  316,  315}, {  318,  317}, {  320,  319}, {  322,  321}, {  324,  323}, {  326,  325},
 22.1838 +{  328,  327}, {  331,  330}, {  333,  332}, {  335,  334}, {  337,  336}, {  339,  338}, {  341,  340},
 22.1839 +{  343,  342}, {  345,  344}, {  347,  346}, {  349,  348}, {  351,  350}, {  353,  352}, {  355,  354},
 22.1840 +{  357,  356}, {  359,  358}, {  361,  360}, {  363,  362}, {  365,  364}, {  367,  366}, {  369,  368},
 22.1841 +{  371,  370}, {  373,  372}, {  375,  374}, {  378,  377}, {  380,  379}, {  382,  381}, {  383,   83}, {  387,  386},
 22.1842 +{  389,  388}, {  392,  391}, {  396,  395}, {  402,  401}, {  409,  408}, {  417,  416}, {  419,  418},
 22.1843 +{  421,  420}, {  424,  423}, {  429,  428}, {  432,  431}, {  436,  435}, {  438,  437}, {  441,  440},
 22.1844 +{  445,  444}, {  454,  452}, {  457,  455}, {  460,  458}, {  462,  461}, {  464,  463}, {  466,  465},
 22.1845 +{  468,  467}, {  470,  469}, {  472,  471}, {  474,  473}, {  476,  475}, {  477,  398}, {  479,  478},
 22.1846 +{  481,  480}, {  483,  482}, {  485,  484}, {  487,  486}, {  489,  488}, {  491,  490}, {  493,  492},
 22.1847 +{  495,  494}, {  499,  497}, {  501,  500}, {  507,  506}, {  509,  508}, {  511,  510}, {  513,  512},
 22.1848 +{  515,  514}, {  517,  516}, {  519,  518}, {  521,  520}, {  523,  522}, {  525,  524}, {  527,  526},
 22.1849 +{  529,  528}, {  531,  530}, {  533,  532}, {  535,  534}, {  595,  385}, {  596,  390}, {  598,  393},
 22.1850 +{  599,  394}, {  601,  399}, {  603,  400}, {  608,  403}, {  611,  404}, {  616,  407}, {  617,  406},
 22.1851 +{  623,  412}, {  626,  413}, {  629,  415}, {  643,  425}, {  648,  430}, {  650,  433}, {  651,  434},
 22.1852 +{  658,  439}, {  940,  902}, {  941,  904}, {  942,  905}, {  943,  906}, {  945,  913}, {  946,  914},
 22.1853 +{  947,  915}, {  948,  916}, {  949,  917}, {  950,  918}, {  951,  919}, {  952,  920}, {  953,  921},
 22.1854 +{  954,  922}, {  955,  923}, {  956,  924}, {  957,  925}, {  958,  926}, {  959,  927}, {  960,  928},
 22.1855 +{  961,  929}, {  962,  931}, {  963,  931}, {  964,  932}, {  965,  933}, {  966,  934}, {  967,  935},
 22.1856 +{  968,  936}, {  969,  937}, {  970,  938}, {  971,  939}, {  972,  908}, {  973,  910}, {  974,  911},
 22.1857 +{  995,  994}, {  997,  996}, {  999,  998}, { 1001, 1000}, { 1003, 1002}, { 1005, 1004}, { 1007, 1006},
 22.1858 +{ 1072, 1040}, { 1073, 1041}, { 1074, 1042}, { 1075, 1043}, { 1076, 1044}, { 1077, 1045}, { 1078, 1046},
 22.1859 +{ 1079, 1047}, { 1080, 1048}, { 1081, 1049}, { 1082, 1050}, { 1083, 1051}, { 1084, 1052}, { 1085, 1053},
 22.1860 +{ 1086, 1054}, { 1087, 1055}, { 1088, 1056}, { 1089, 1057}, { 1090, 1058}, { 1091, 1059}, { 1092, 1060},
 22.1861 +{ 1093, 1061}, { 1094, 1062}, { 1095, 1063}, { 1096, 1064}, { 1097, 1065}, { 1098, 1066}, { 1099, 1067},
 22.1862 +{ 1100, 1068}, { 1101, 1069}, { 1102, 1070}, { 1103, 1071}, { 1104, 1024}, { 1105, 1025}, { 1106, 1026}, { 1107, 1027},
 22.1863 +{ 1108, 1028}, { 1109, 1029}, { 1110, 1030}, { 1111, 1031}, { 1112, 1032}, { 1113, 1033}, { 1114, 1034},
 22.1864 +{ 1115, 1035}, { 1116, 1036}, { 1117, 1037}, { 1118, 1038}, { 1119, 1039}, { 1121, 1120}, { 1123, 1122}, { 1125, 1124},
 22.1865 +{ 1127, 1126}, { 1129, 1128}, { 1131, 1130}, { 1133, 1132}, { 1135, 1134}, { 1137, 1136}, { 1139, 1138},
 22.1866 +{ 1141, 1140}, { 1143, 1142}, { 1145, 1144}, { 1147, 1146}, { 1149, 1148}, { 1151, 1150}, { 1153, 1152},
 22.1867 +{ 1169, 1168}, { 1171, 1170}, { 1173, 1172}, { 1175, 1174}, { 1177, 1176}, { 1179, 1178}, { 1181, 1180},
 22.1868 +{ 1183, 1182}, { 1185, 1184}, { 1187, 1186}, { 1189, 1188}, { 1191, 1190}, { 1193, 1192}, { 1195, 1194},
 22.1869 +{ 1197, 1196}, { 1199, 1198}, { 1201, 1200}, { 1203, 1202}, { 1205, 1204}, { 1207, 1206}, { 1209, 1208},
 22.1870 +{ 1211, 1210}, { 1213, 1212}, { 1215, 1214}, { 1218, 1217}, { 1220, 1219}, { 1224, 1223}, { 1228, 1227},
 22.1871 +{ 1233, 1232}, { 1235, 1234}, { 1237, 1236}, { 1239, 1238}, { 1241, 1240}, { 1243, 1242}, { 1245, 1244},
 22.1872 +{ 1247, 1246}, { 1249, 1248}, { 1251, 1250}, { 1253, 1252}, { 1255, 1254}, { 1257, 1256}, { 1259, 1258},
 22.1873 +{ 1263, 1262}, { 1265, 1264}, { 1267, 1266}, { 1269, 1268}, { 1273, 1272}, { 1377, 1329}, { 1378, 1330},
 22.1874 +{ 1379, 1331}, { 1380, 1332}, { 1381, 1333}, { 1382, 1334}, { 1383, 1335}, { 1384, 1336}, { 1385, 1337},
 22.1875 +{ 1386, 1338}, { 1387, 1339}, { 1388, 1340}, { 1389, 1341}, { 1390, 1342}, { 1391, 1343}, { 1392, 1344},
 22.1876 +{ 1393, 1345}, { 1394, 1346}, { 1395, 1347}, { 1396, 1348}, { 1397, 1349}, { 1398, 1350}, { 1399, 1351},
 22.1877 +{ 1400, 1352}, { 1401, 1353}, { 1402, 1354}, { 1403, 1355}, { 1404, 1356}, { 1405, 1357}, { 1406, 1358},
 22.1878 +{ 1407, 1359}, { 1408, 1360}, { 1409, 1361}, { 1410, 1362}, { 1411, 1363}, { 1412, 1364}, { 1413, 1365},
 22.1879 +{ 1414, 1366}, { 7681, 7680}, { 7683, 7682}, { 7685, 7684}, { 7687, 7686}, { 7689, 7688}, { 7691, 7690},
 22.1880 +{ 7693, 7692}, { 7695, 7694}, { 7697, 7696}, { 7699, 7698}, { 7701, 7700}, { 7703, 7702}, { 7705, 7704},
 22.1881 +{ 7707, 7706}, { 7709, 7708}, { 7711, 7710}, { 7713, 7712}, { 7715, 7714}, { 7717, 7716}, { 7719, 7718},
 22.1882 +{ 7721, 7720}, { 7723, 7722}, { 7725, 7724}, { 7727, 7726}, { 7729, 7728}, { 7731, 7730}, { 7733, 7732},
 22.1883 +{ 7735, 7734}, { 7737, 7736}, { 7739, 7738}, { 7741, 7740}, { 7743, 7742}, { 7745, 7744}, { 7747, 7746},
 22.1884 +{ 7749, 7748}, { 7751, 7750}, { 7753, 7752}, { 7755, 7754}, { 7757, 7756}, { 7759, 7758}, { 7761, 7760},
 22.1885 +{ 7763, 7762}, { 7765, 7764}, { 7767, 7766}, { 7769, 7768}, { 7771, 7770}, { 7773, 7772}, { 7775, 7774},
 22.1886 +{ 7777, 7776}, { 7779, 7778}, { 7781, 7780}, { 7783, 7782}, { 7785, 7784}, { 7787, 7786}, { 7789, 7788},
 22.1887 +{ 7791, 7790}, { 7793, 7792}, { 7795, 7794}, { 7797, 7796}, { 7799, 7798}, { 7801, 7800}, { 7803, 7802},
 22.1888 +{ 7805, 7804}, { 7807, 7806}, { 7809, 7808}, { 7811, 7810}, { 7813, 7812}, { 7815, 7814}, { 7817, 7816},
 22.1889 +{ 7819, 7818}, { 7821, 7820}, { 7823, 7822}, { 7825, 7824}, { 7827, 7826}, { 7829, 7828}, { 7841, 7840},
 22.1890 +{ 7843, 7842}, { 7845, 7844}, { 7847, 7846}, { 7849, 7848}, { 7851, 7850}, { 7853, 7852}, { 7855, 7854},
 22.1891 +{ 7857, 7856}, { 7859, 7858}, { 7861, 7860}, { 7863, 7862}, { 7865, 7864}, { 7867, 7866}, { 7869, 7868},
 22.1892 +{ 7871, 7870}, { 7873, 7872}, { 7875, 7874}, { 7877, 7876}, { 7879, 7878}, { 7881, 7880}, { 7883, 7882},
 22.1893 +{ 7885, 7884}, { 7887, 7886}, { 7889, 7888}, { 7891, 7890}, { 7893, 7892}, { 7895, 7894}, { 7897, 7896},
 22.1894 +{ 7899, 7898}, { 7901, 7900}, { 7903, 7902}, { 7905, 7904}, { 7907, 7906}, { 7909, 7908}, { 7911, 7910},
 22.1895 +{ 7913, 7912}, { 7915, 7914}, { 7917, 7916}, { 7919, 7918}, { 7921, 7920}, { 7923, 7922}, { 7925, 7924},
 22.1896 +{ 7927, 7926}, { 7929, 7928}, { 7936, 7944}, { 7937, 7945}, { 7938, 7946}, { 7939, 7947}, { 7940, 7948},
 22.1897 +{ 7941, 7949}, { 7942, 7950}, { 7943, 7951}, { 7952, 7960}, { 7953, 7961}, { 7954, 7962}, { 7955, 7963},
 22.1898 +{ 7956, 7964}, { 7957, 7965}, { 7968, 7976}, { 7969, 7977}, { 7970, 7978}, { 7971, 7979}, { 7972, 7980},
 22.1899 +{ 7973, 7981}, { 7974, 7982}, { 7975, 7983}, { 7984, 7992}, { 7985, 7993}, { 7986, 7994}, { 7987, 7995},
 22.1900 +{ 7988, 7996}, { 7989, 7997}, { 7990, 7998}, { 7991, 7999}, { 8000, 8008}, { 8001, 8009}, { 8002, 8010},
 22.1901 +{ 8003, 8011}, { 8004, 8012}, { 8005, 8013}, { 8017, 8025}, { 8019, 8027}, { 8021, 8029}, { 8023, 8031},
 22.1902 +{ 8032, 8040}, { 8033, 8041}, { 8034, 8042}, { 8035, 8043}, { 8036, 8044}, { 8037, 8045}, { 8038, 8046},
 22.1903 +{ 8039, 8047}, { 8048, 8122}, { 8049, 8123}, { 8050, 8136}, { 8051, 8137}, { 8052, 8138}, { 8053, 8139},
 22.1904 +{ 8054, 8154}, { 8055, 8155}, { 8056, 8184}, { 8057, 8185}, { 8058, 8170}, { 8059, 8171}, { 8060, 8186},
 22.1905 +{ 8061, 8187}, { 8112, 8120}, { 8113, 8121}, { 8144, 8152}, { 8145, 8153}, { 8160, 8168}, { 8161, 8169},
 22.1906 +{ 8165, 8172}, { 8560, 8544}, { 8561, 8545}, { 8562, 8546}, { 8563, 8547}, { 8564, 8548}, { 8565, 8549},
 22.1907 +{ 8566, 8550}, { 8567, 8551}, { 8568, 8552}, { 8569, 8553}, { 8570, 8554}, { 8571, 8555}, { 8572, 8556},
 22.1908 +{ 8573, 8557}, { 8574, 8558}, { 8575, 8559}, { 9424, 9398}, { 9425, 9399}, { 9426, 9400}, { 9427, 9401},
 22.1909 +{ 9428, 9402}, { 9429, 9403}, { 9430, 9404}, { 9431, 9405}, { 9432, 9406}, { 9433, 9407}, { 9434, 9408},
 22.1910 +{ 9435, 9409}, { 9436, 9410}, { 9437, 9411}, { 9438, 9412}, { 9439, 9413}, { 9440, 9414}, { 9441, 9415},
 22.1911 +{ 9442, 9416}, { 9443, 9417}, { 9444, 9418}, { 9445, 9419}, { 9446, 9420}, { 9447, 9421}, { 9448, 9422},
 22.1912 +{ 9449, 9423}, {65345,65313}, {65346,65314}, {65347,65315}, {65348,65316}, {65349,65317}, {65350,65318},
 22.1913 +{65351,65319}, {65352,65320}, {65353,65321}, {65354,65322}, {65355,65323}, {65356,65324}, {65357,65325},
 22.1914 +{65358,65326}, {65359,65327}, {65360,65328}, {65361,65329}, {65362,65330}, {65363,65331}, {65364,65332},
 22.1915 +{65365,65333}, {65366,65334}, {65367,65335}, {65368,65336}, {65369,65337}, {65370,65338}, {65535,    0}};
 22.1916 +
 22.1917 +static const GUnicodePairType UnicodeToLowerTable[] = {
 22.1918 +{   65,   97}, {   66,   98}, {   67,   99}, {   68,  100}, {   69,  101}, {   70,  102}, {   71,  103},
 22.1919 +{   72,  104}, {   73,  105}, {   74,  106}, {   75,  107}, {   76,  108}, {   77,  109}, {   78,  110},
 22.1920 +{   79,  111}, {   80,  112}, {   81,  113}, {   82,  114}, {   83,  115}, {   84,  116}, {   85,  117},
 22.1921 +{   86,  118}, {   87,  119}, {   88,  120}, {   89,  121}, {   90,  122}, {  192,  224}, {  193,  225},
 22.1922 +{  194,  226}, {  195,  227}, {  196,  228}, {  197,  229}, {  198,  230}, {  199,  231}, {  200,  232},
 22.1923 +{  201,  233}, {  202,  234}, {  203,  235}, {  204,  236}, {  205,  237}, {  206,  238}, {  207,  239},
 22.1924 +{  208,  240}, {  209,  241}, {  210,  242}, {  211,  243}, {  212,  244}, {  213,  245}, {  214,  246},
 22.1925 +{  216,  248}, {  217,  249}, {  218,  250}, {  219,  251}, {  220,  252}, {  221,  253}, {  222,  254},
 22.1926 +{  256,  257}, {  258,  259}, {  260,  261}, {  262,  263}, {  264,  265}, {  266,  267}, {  268,  269},
 22.1927 +{  270,  271}, {  272,  273}, {  274,  275}, {  276,  277}, {  278,  279}, {  280,  281}, {  282,  283},
 22.1928 +{  284,  285}, {  286,  287}, {  288,  289}, {  290,  291}, {  292,  293}, {  294,  295}, {  296,  297},
 22.1929 +{  298,  299}, {  300,  301}, {  302,  303}, {  304,  105}, {  306,  307}, {  308,  309}, {  310,  311}, {  313,  314},
 22.1930 +{  315,  316}, {  317,  318}, {  319,  320}, {  321,  322}, {  323,  324}, {  325,  326}, {  327,  328},
 22.1931 +{  330,  331}, {  332,  333}, {  334,  335}, {  336,  337}, {  338,  339}, {  340,  341}, {  342,  343},
 22.1932 +{  344,  345}, {  346,  347}, {  348,  349}, {  350,  351}, {  352,  353}, {  354,  355}, {  356,  357},
 22.1933 +{  358,  359}, {  360,  361}, {  362,  363}, {  364,  365}, {  366,  367}, {  368,  369}, {  370,  371},
 22.1934 +{  372,  373}, {  374,  375}, {  376,  255}, {  377,  378}, {  379,  380}, {  381,  382}, {  385,  595},
 22.1935 +{  386,  387}, {  388,  389}, {  390,  596}, {  391,  392}, {  393,  598}, {  394,  599}, {  395,  396},
 22.1936 +{  398,  477}, {  399,  601}, {  400,  603}, {  401,  402}, {  403,  608}, {  404,  611}, {  406,  617},
 22.1937 +{  407,  616}, {  408,  409}, {  412,  623}, {  413,  626}, {  415,  629}, {  416,  417}, {  418,  419},
 22.1938 +{  420,  421}, {  423,  424}, {  425,  643}, {  428,  429}, {  430,  648}, {  431,  432}, {  433,  650},
 22.1939 +{  434,  651}, {  435,  436}, {  437,  438}, {  439,  658}, {  440,  441}, {  444,  445}, {  452,  454},
 22.1940 +{  455,  457}, {  458,  460}, {  461,  462}, {  463,  464}, {  465,  466}, {  467,  468}, {  469,  470},
 22.1941 +{  471,  472}, {  473,  474}, {  475,  476}, {  478,  479}, {  480,  481}, {  482,  483}, {  484,  485},
 22.1942 +{  486,  487}, {  488,  489}, {  490,  491}, {  492,  493}, {  494,  495}, {  497,  499}, {  500,  501},
 22.1943 +{  506,  507}, {  508,  509}, {  510,  511}, {  512,  513}, {  514,  515}, {  516,  517}, {  518,  519},
 22.1944 +{  520,  521}, {  522,  523}, {  524,  525}, {  526,  527}, {  528,  529}, {  530,  531}, {  532,  533},
 22.1945 +{  534,  535}, {  902,  940}, {  904,  941}, {  905,  942}, {  906,  943}, {  908,  972}, {  910,  973},
 22.1946 +{  911,  974}, {  913,  945}, {  914,  946}, {  915,  947}, {  916,  948}, {  917,  949}, {  918,  950},
 22.1947 +{  919,  951}, {  920,  952}, {  921,  953}, {  922,  954}, {  923,  955}, {  924,  956}, {  925,  957},
 22.1948 +{  926,  958}, {  927,  959}, {  928,  960}, {  929,  961}, {  931,  963}, {  932,  964}, {  933,  965},
 22.1949 +{  934,  966}, {  935,  967}, {  936,  968}, {  937,  969}, {  938,  970}, {  939,  971}, {  994,  995},
 22.1950 +{  996,  997}, {  998,  999}, { 1000, 1001}, { 1002, 1003}, { 1004, 1005}, { 1006, 1007}, { 1024, 1104}, { 1025, 1105},
 22.1951 +{ 1026, 1106}, { 1027, 1107}, { 1028, 1108}, { 1029, 1109}, { 1030, 1110}, { 1031, 1111}, { 1032, 1112},
 22.1952 +{ 1033, 1113}, { 1034, 1114}, { 1035, 1115}, { 1036, 1116}, { 1037, 1117}, { 1038, 1118}, { 1039, 1119}, { 1040, 1072},
 22.1953 +{ 1041, 1073}, { 1042, 1074}, { 1043, 1075}, { 1044, 1076}, { 1045, 1077}, { 1046, 1078}, { 1047, 1079},
 22.1954 +{ 1048, 1080}, { 1049, 1081}, { 1050, 1082}, { 1051, 1083}, { 1052, 1084}, { 1053, 1085}, { 1054, 1086},
 22.1955 +{ 1055, 1087}, { 1056, 1088}, { 1057, 1089}, { 1058, 1090}, { 1059, 1091}, { 1060, 1092}, { 1061, 1093},
 22.1956 +{ 1062, 1094}, { 1063, 1095}, { 1064, 1096}, { 1065, 1097}, { 1066, 1098}, { 1067, 1099}, { 1068, 1100},
 22.1957 +{ 1069, 1101}, { 1070, 1102}, { 1071, 1103}, { 1120, 1121}, { 1122, 1123}, { 1124, 1125}, { 1126, 1127},
 22.1958 +{ 1128, 1129}, { 1130, 1131}, { 1132, 1133}, { 1134, 1135}, { 1136, 1137}, { 1138, 1139}, { 1140, 1141},
 22.1959 +{ 1142, 1143}, { 1144, 1145}, { 1146, 1147}, { 1148, 1149}, { 1150, 1151}, { 1152, 1153}, { 1168, 1169},
 22.1960 +{ 1170, 1171}, { 1172, 1173}, { 1174, 1175}, { 1176, 1177}, { 1178, 1179}, { 1180, 1181}, { 1182, 1183},
 22.1961 +{ 1184, 1185}, { 1186, 1187}, { 1188, 1189}, { 1190, 1191}, { 1192, 1193}, { 1194, 1195}, { 1196, 1197},
 22.1962 +{ 1198, 1199}, { 1200, 1201}, { 1202, 1203}, { 1204, 1205}, { 1206, 1207}, { 1208, 1209}, { 1210, 1211},
 22.1963 +{ 1212, 1213}, { 1214, 1215}, { 1217, 1218}, { 1219, 1220}, { 1223, 1224}, { 1227, 1228}, { 1232, 1233},
 22.1964 +{ 1234, 1235}, { 1236, 1237}, { 1238, 1239}, { 1240, 1241}, { 1242, 1243}, { 1244, 1245}, { 1246, 1247},
 22.1965 +{ 1248, 1249}, { 1250, 1251}, { 1252, 1253}, { 1254, 1255}, { 1256, 1257}, { 1258, 1259}, { 1262, 1263},
 22.1966 +{ 1264, 1265}, { 1266, 1267}, { 1268, 1269}, { 1272, 1273}, { 1329, 1377}, { 1330, 1378}, { 1331, 1379},
 22.1967 +{ 1332, 1380}, { 1333, 1381}, { 1334, 1382}, { 1335, 1383}, { 1336, 1384}, { 1337, 1385}, { 1338, 1386},
 22.1968 +{ 1339, 1387}, { 1340, 1388}, { 1341, 1389}, { 1342, 1390}, { 1343, 1391}, { 1344, 1392}, { 1345, 1393},
 22.1969 +{ 1346, 1394}, { 1347, 1395}, { 1348, 1396}, { 1349, 1397}, { 1350, 1398}, { 1351, 1399}, { 1352, 1400},
 22.1970 +{ 1353, 1401}, { 1354, 1402}, { 1355, 1403}, { 1356, 1404}, { 1357, 1405}, { 1358, 1406}, { 1359, 1407},
 22.1971 +{ 1360, 1408}, { 1361, 1409}, { 1362, 1410}, { 1363, 1411}, { 1364, 1412}, { 1365, 1413}, { 1366, 1414},
 22.1972 +{ 4256, 4304}, { 4257, 4305}, { 4258, 4306}, { 4259, 4307}, { 4260, 4308}, { 4261, 4309}, { 4262, 4310},
 22.1973 +{ 4263, 4311}, { 4264, 4312}, { 4265, 4313}, { 4266, 4314}, { 4267, 4315}, { 4268, 4316}, { 4269, 4317},
 22.1974 +{ 4270, 4318}, { 4271, 4319}, { 4272, 4320}, { 4273, 4321}, { 4274, 4322}, { 4275, 4323}, { 4276, 4324},
 22.1975 +{ 4277, 4325}, { 4278, 4326}, { 4279, 4327}, { 4280, 4328}, { 4281, 4329}, { 4282, 4330}, { 4283, 4331},
 22.1976 +{ 4284, 4332}, { 4285, 4333}, { 4286, 4334}, { 4287, 4335}, { 4288, 4336}, { 4289, 4337}, { 4290, 4338},
 22.1977 +{ 4291, 4339}, { 4292, 4340}, { 4293, 4341}, { 7680, 7681}, { 7682, 7683}, { 7684, 7685}, { 7686, 7687},
 22.1978 +{ 7688, 7689}, { 7690, 7691}, { 7692, 7693}, { 7694, 7695}, { 7696, 7697}, { 7698, 7699}, { 7700, 7701},
 22.1979 +{ 7702, 7703}, { 7704, 7705}, { 7706, 7707}, { 7708, 7709}, { 7710, 7711}, { 7712, 7713}, { 7714, 7715},
 22.1980 +{ 7716, 7717}, { 7718, 7719}, { 7720, 7721}, { 7722, 7723}, { 7724, 7725}, { 7726, 7727}, { 7728, 7729},
 22.1981 +{ 7730, 7731}, { 7732, 7733}, { 7734, 7735}, { 7736, 7737}, { 7738, 7739}, { 7740, 7741}, { 7742, 7743},
 22.1982 +{ 7744, 7745}, { 7746, 7747}, { 7748, 7749}, { 7750, 7751}, { 7752, 7753}, { 7754, 7755}, { 7756, 7757},
 22.1983 +{ 7758, 7759}, { 7760, 7761}, { 7762, 7763}, { 7764, 7765}, { 7766, 7767}, { 7768, 7769}, { 7770, 7771},
 22.1984 +{ 7772, 7773}, { 7774, 7775}, { 7776, 7777}, { 7778, 7779}, { 7780, 7781}, { 7782, 7783}, { 7784, 7785},
 22.1985 +{ 7786, 7787}, { 7788, 7789}, { 7790, 7791}, { 7792, 7793}, { 7794, 7795}, { 7796, 7797}, { 7798, 7799},
 22.1986 +{ 7800, 7801}, { 7802, 7803}, { 7804, 7805}, { 7806, 7807}, { 7808, 7809}, { 7810, 7811}, { 7812, 7813},
 22.1987 +{ 7814, 7815}, { 7816, 7817}, { 7818, 7819}, { 7820, 7821}, { 7822, 7823}, { 7824, 7825}, { 7826, 7827},
 22.1988 +{ 7828, 7829}, { 7840, 7841}, { 7842, 7843}, { 7844, 7845}, { 7846, 7847}, { 7848, 7849}, { 7850, 7851},
 22.1989 +{ 7852, 7853}, { 7854, 7855}, { 7856, 7857}, { 7858, 7859}, { 7860, 7861}, { 7862, 7863}, { 7864, 7865},
 22.1990 +{ 7866, 7867}, { 7868, 7869}, { 7870, 7871}, { 7872, 7873}, { 7874, 7875}, { 7876, 7877}, { 7878, 7879},
 22.1991 +{ 7880, 7881}, { 7882, 7883}, { 7884, 7885}, { 7886, 7887}, { 7888, 7889}, { 7890, 7891}, { 7892, 7893},
 22.1992 +{ 7894, 7895}, { 7896, 7897}, { 7898, 7899}, { 7900, 7901}, { 7902, 7903}, { 7904, 7905}, { 7906, 7907},
 22.1993 +{ 7908, 7909}, { 7910, 7911}, { 7912, 7913}, { 7914, 7915}, { 7916, 7917}, { 7918, 7919}, { 7920, 7921},
 22.1994 +{ 7922, 7923}, { 7924, 7925}, { 7926, 7927}, { 7928, 7929}, { 7944, 7936}, { 7945, 7937}, { 7946, 7938},
 22.1995 +{ 7947, 7939}, { 7948, 7940}, { 7949, 7941}, { 7950, 7942}, { 7951, 7943}, { 7960, 7952}, { 7961, 7953},
 22.1996 +{ 7962, 7954}, { 7963, 7955}, { 7964, 7956}, { 7965, 7957}, { 7976, 7968}, { 7977, 7969}, { 7978, 7970},
 22.1997 +{ 7979, 7971}, { 7980, 7972}, { 7981, 7973}, { 7982, 7974}, { 7983, 7975}, { 7992, 7984}, { 7993, 7985},
 22.1998 +{ 7994, 7986}, { 7995, 7987}, { 7996, 7988}, { 7997, 7989}, { 7998, 7990}, { 7999, 7991}, { 8008, 8000},
 22.1999 +{ 8009, 8001}, { 8010, 8002}, { 8011, 8003}, { 8012, 8004}, { 8013, 8005}, { 8025, 8017}, { 8027, 8019},
 22.2000 +{ 8029, 8021}, { 8031, 8023}, { 8040, 8032}, { 8041, 8033}, { 8042, 8034}, { 8043, 8035}, { 8044, 8036},
 22.2001 +{ 8045, 8037}, { 8046, 8038}, { 8047, 8039}, { 8120, 8112}, { 8121, 8113}, { 8122, 8048}, { 8123, 8049},
 22.2002 +{ 8136, 8050}, { 8137, 8051}, { 8138, 8052}, { 8139, 8053}, { 8152, 8144}, { 8153, 8145}, { 8154, 8054},
 22.2003 +{ 8155, 8055}, { 8168, 8160}, { 8169, 8161}, { 8170, 8058}, { 8171, 8059}, { 8172, 8165}, { 8184, 8056},
 22.2004 +{ 8185, 8057}, { 8186, 8060}, { 8187, 8061}, { 8544, 8560}, { 8545, 8561}, { 8546, 8562}, { 8547, 8563},
 22.2005 +{ 8548, 8564}, { 8549, 8565}, { 8550, 8566}, { 8551, 8567}, { 8552, 8568}, { 8553, 8569}, { 8554, 8570},
 22.2006 +{ 8555, 8571}, { 8556, 8572}, { 8557, 8573}, { 8558, 8574}, { 8559, 8575}, { 9398, 9424}, { 9399, 9425},
 22.2007 +{ 9400, 9426}, { 9401, 9427}, { 9402, 9428}, { 9403, 9429}, { 9404, 9430}, { 9405, 9431}, { 9406, 9432},
 22.2008 +{ 9407, 9433}, { 9408, 9434}, { 9409, 9435}, { 9410, 9436}, { 9411, 9437}, { 9412, 9438}, { 9413, 9439},
 22.2009 +{ 9414, 9440}, { 9415, 9441}, { 9416, 9442}, { 9417, 9443}, { 9418, 9444}, { 9419, 9445}, { 9420, 9446},
 22.2010 +{ 9421, 9447}, { 9422, 9448}, { 9423, 9449}, {65313,65345}, {65314,65346}, {65315,65347}, {65316,65348},
 22.2011 +{65317,65349}, {65318,65350}, {65319,65351}, {65320,65352}, {65321,65353}, {65322,65354}, {65323,65355},
 22.2012 +{65324,65356}, {65325,65357}, {65326,65358}, {65327,65359}, {65328,65360}, {65329,65361}, {65330,65362},
 22.2013 +{65331,65363}, {65332,65364}, {65333,65365}, {65334,65366}, {65335,65367}, {65336,65368}, {65337,65369},
 22.2014 +{65338,65370}, {65535,    0}};
 22.2015 +
 22.2016 +int OVR_CDECL OVR_towupper(wchar_t charCode)
 22.2017 +{
 22.2018 +    // Don't use UnicodeUpperBits! It differs from UnicodeToUpperBits.
 22.2019 +    if (UnicodeCharIs(UnicodeToUpperBits, charCode))
 22.2020 +    {
 22.2021 +        // To protect from memory overrun in case the character is not found
 22.2022 +        // we use one extra fake element in the table {65536, 0}.
 22.2023 +        UPInt idx = Alg::LowerBoundSliced(
 22.2024 +            UnicodeToUpperTable,
 22.2025 +            0,
 22.2026 +            sizeof(UnicodeToUpperTable) / sizeof(UnicodeToUpperTable[0]) - 1,
 22.2027 +            (UInt16)charCode,
 22.2028 +            CmpUnicodeKey);
 22.2029 +        return UnicodeToUpperTable[idx].Value;
 22.2030 +    }
 22.2031 +    return charCode;
 22.2032 +}
 22.2033 +
 22.2034 +int OVR_CDECL OVR_towlower(wchar_t charCode)
 22.2035 +{
 22.2036 +    // Don't use UnicodeLowerBits! It differs from UnicodeToLowerBits.
 22.2037 +    if (UnicodeCharIs(UnicodeToLowerBits, charCode))
 22.2038 +    {
 22.2039 +        // To protect from memory overrun in case the character is not found
 22.2040 +        // we use one extra fake element in the table {65536, 0}.
 22.2041 +        UPInt idx = Alg::LowerBoundSliced(
 22.2042 +            UnicodeToLowerTable,
 22.2043 +            0,
 22.2044 +            sizeof(UnicodeToLowerTable) / sizeof(UnicodeToLowerTable[0]) - 1,
 22.2045 +            (UInt16)charCode,
 22.2046 +            CmpUnicodeKey);
 22.2047 +        return UnicodeToLowerTable[idx].Value;
 22.2048 +    }
 22.2049 +    return charCode;
 22.2050 +}
 22.2051 +
 22.2052 +#endif //OVR_NO_WCTYPE
 22.2053 +
 22.2054 +} // OVR
    23.1 --- a/libovr/Src/Kernel/OVR_Std.h	Sat Sep 14 17:51:03 2013 +0300
    23.2 +++ b/libovr/Src/Kernel/OVR_Std.h	Sun Sep 15 04:10:05 2013 +0300
    23.3 @@ -1,1 +1,503 @@
    23.4 -/************************************************************************************
    23.5 
    23.6 PublicHeader:   OVR.h
    23.7 Filename    :   OVR_Std.h
    23.8 Content     :   Standard C function interface
    23.9 Created     :   September 19, 2012
   23.10 Notes       : 
   23.11 
   23.12 Copyright   :   Copyright 2012 Oculus VR, Inc. All Rights reserved.
   23.13 
   23.14 Use of this software is subject to the terms of the Oculus license
   23.15 agreement provided at the time of installation or download, or which
   23.16 otherwise accompanies this software in either electronic or hard copy form.
   23.17 
   23.18 ************************************************************************************/
   23.19 
   23.20 #ifndef OVR_Std_h
   23.21 #define OVR_Std_h
   23.22 
   23.23 #include "OVR_Types.h"
   23.24 #include <stdarg.h> // for va_list args
   23.25 #include <string.h>
   23.26 #include <stdio.h>
   23.27 #include <stdlib.h>
   23.28 #include <ctype.h>
   23.29 
   23.30 #if !defined(OVR_OS_WINCE) && defined(OVR_CC_MSVC) && (OVR_CC_MSVC >= 1400)
   23.31 #define OVR_MSVC_SAFESTRING
   23.32 #include <errno.h>
   23.33 #endif
   23.34 
   23.35 // Wide-char funcs
   23.36 #include <wchar.h>
   23.37 #include <wctype.h>
   23.38 
   23.39 namespace OVR {
   23.40 
   23.41 #if defined(OVR_OS_WIN32)
   23.42 inline char* OVR_CDECL OVR_itoa(int val, char *dest, UPInt destsize, int radix)
   23.43 {
   23.44 #if defined(OVR_MSVC_SAFESTRING)
   23.45     _itoa_s(val, dest, destsize, radix);
   23.46     return dest;
   23.47 #else
   23.48     OVR_UNUSED(destsize);
   23.49     return itoa(val, dest, radix);
   23.50 #endif
   23.51 }
   23.52 #else // OVR_OS_WIN32
   23.53 inline char* OVR_itoa(int val, char* dest, unsigned int len, int radix)
   23.54 {
   23.55     if (val == 0)
   23.56     {
   23.57         if (len > 1)
   23.58         {
   23.59             dest[0] = '0';
   23.60             dest[1] = '\0';  
   23.61         }
   23.62         return dest;
   23.63     }
   23.64 
   23.65     int cur = val;
   23.66     unsigned int i    = 0; 
   23.67     unsigned int sign = 0;
   23.68 
   23.69     if (val < 0)
   23.70     {
   23.71         val = -val;
   23.72         sign = 1;
   23.73     }
   23.74 
   23.75     while ((val != 0) && (i < (len - 1 - sign)))        
   23.76     {
   23.77         cur    = val % radix;
   23.78         val   /= radix;
   23.79 
   23.80         if (radix == 16)
   23.81         {
   23.82             switch(cur)
   23.83             {
   23.84             case 10:
   23.85                 dest[i] = 'a';
   23.86                 break;
   23.87             case 11:
   23.88                 dest[i] = 'b';
   23.89                 break;
   23.90             case 12:
   23.91                 dest[i] = 'c';
   23.92                 break;
   23.93             case 13:
   23.94                 dest[i] = 'd';
   23.95                 break;
   23.96             case 14:
   23.97                 dest[i] = 'e';
   23.98                 break;
   23.99             case 15:
  23.100                 dest[i] = 'f';
  23.101                 break;
  23.102             default:
  23.103                 dest[i] = (char)('0' + cur);
  23.104                 break;
  23.105             }
  23.106         } 
  23.107         else
  23.108         {
  23.109             dest[i] = (char)('0' + cur);
  23.110         }
  23.111         ++i;
  23.112     }
  23.113 
  23.114     if (sign)
  23.115     {
  23.116         dest[i++] = '-';
  23.117     }
  23.118 
  23.119     for (unsigned int j = 0; j < i / 2; ++j)
  23.120     {
  23.121         char tmp        = dest[j];
  23.122         dest[j]         = dest[i - 1 - j];
  23.123         dest[i - 1 - j] = tmp;
  23.124     }
  23.125     dest[i] = '\0';
  23.126 
  23.127     return dest;
  23.128 }
  23.129 
  23.130 #endif
  23.131 
  23.132 
  23.133 // String functions
  23.134 
  23.135 inline UPInt OVR_CDECL OVR_strlen(const char* str)
  23.136 {
  23.137     return strlen(str);
  23.138 }
  23.139 
  23.140 inline char* OVR_CDECL OVR_strcpy(char* dest, UPInt destsize, const char* src)
  23.141 {
  23.142 #if defined(OVR_MSVC_SAFESTRING)
  23.143     strcpy_s(dest, destsize, src);
  23.144     return dest;
  23.145 #else
  23.146     OVR_UNUSED(destsize);
  23.147     return strcpy(dest, src);
  23.148 #endif
  23.149 }
  23.150 
  23.151 inline char* OVR_CDECL OVR_strncpy(char* dest, UPInt destsize, const char* src, UPInt count)
  23.152 {
  23.153 #if defined(OVR_MSVC_SAFESTRING)
  23.154     strncpy_s(dest, destsize, src, count);
  23.155     return dest;
  23.156 #else
  23.157     OVR_UNUSED(destsize);
  23.158     return strncpy(dest, src, count);
  23.159 #endif
  23.160 }
  23.161 
  23.162 inline char * OVR_CDECL OVR_strcat(char* dest, UPInt destsize, const char* src)
  23.163 {
  23.164 #if defined(OVR_MSVC_SAFESTRING)
  23.165     strcat_s(dest, destsize, src);
  23.166     return dest;
  23.167 #else
  23.168     OVR_UNUSED(destsize);
  23.169     return strcat(dest, src);
  23.170 #endif
  23.171 }
  23.172 
  23.173 inline int OVR_CDECL OVR_strcmp(const char* dest, const char* src)
  23.174 {
  23.175     return strcmp(dest, src);
  23.176 }
  23.177 
  23.178 inline const char* OVR_CDECL OVR_strchr(const char* str, char c)
  23.179 {
  23.180     return strchr(str, c);
  23.181 }
  23.182 
  23.183 inline char* OVR_CDECL OVR_strchr(char* str, char c)
  23.184 {
  23.185     return strchr(str, c);
  23.186 }
  23.187 
  23.188 inline const char* OVR_strrchr(const char* str, char c)
  23.189 {
  23.190     UPInt len = OVR_strlen(str);
  23.191     for (UPInt i=len; i>0; i--)     
  23.192         if (str[i]==c) 
  23.193             return str+i;
  23.194     return 0;
  23.195 }
  23.196 
  23.197 inline const UByte* OVR_CDECL OVR_memrchr(const UByte* str, UPInt size, UByte c)
  23.198 {
  23.199     for (SPInt i = (SPInt)size - 1; i >= 0; i--)     
  23.200     {
  23.201         if (str[i] == c) 
  23.202             return str + i;
  23.203     }
  23.204     return 0;
  23.205 }
  23.206 
  23.207 inline char* OVR_CDECL OVR_strrchr(char* str, char c)
  23.208 {
  23.209     UPInt len = OVR_strlen(str);
  23.210     for (UPInt i=len; i>0; i--)     
  23.211         if (str[i]==c) 
  23.212             return str+i;
  23.213     return 0;
  23.214 }
  23.215 
  23.216 
  23.217 double OVR_CDECL OVR_strtod(const char* string, char** tailptr);
  23.218 
  23.219 inline long OVR_CDECL OVR_strtol(const char* string, char** tailptr, int radix)
  23.220 {
  23.221     return strtol(string, tailptr, radix);
  23.222 }
  23.223 
  23.224 inline long OVR_CDECL OVR_strtoul(const char* string, char** tailptr, int radix)
  23.225 {
  23.226     return strtoul(string, tailptr, radix);
  23.227 }
  23.228 
  23.229 inline int OVR_CDECL OVR_strncmp(const char* ws1, const char* ws2, UPInt size)
  23.230 {
  23.231     return strncmp(ws1, ws2, size);
  23.232 }
  23.233 
  23.234 inline UInt64 OVR_CDECL OVR_strtouq(const char *nptr, char **endptr, int base)
  23.235 {
  23.236 #if defined(OVR_CC_MSVC) && !defined(OVR_OS_WINCE)
  23.237     return _strtoui64(nptr, endptr, base);
  23.238 #else
  23.239     return strtoull(nptr, endptr, base);
  23.240 #endif
  23.241 }
  23.242 
  23.243 inline SInt64 OVR_CDECL OVR_strtoq(const char *nptr, char **endptr, int base)
  23.244 {
  23.245 #if defined(OVR_CC_MSVC) && !defined(OVR_OS_WINCE)
  23.246     return _strtoi64(nptr, endptr, base);
  23.247 #else
  23.248     return strtoll(nptr, endptr, base);
  23.249 #endif
  23.250 }
  23.251 
  23.252 
  23.253 inline SInt64 OVR_CDECL OVR_atoq(const char* string)
  23.254 {
  23.255 #if defined(OVR_CC_MSVC) && !defined(OVR_OS_WINCE)
  23.256     return _atoi64(string);
  23.257 #else
  23.258     return atoll(string);
  23.259 #endif
  23.260 }
  23.261 
  23.262 inline UInt64 OVR_CDECL OVR_atouq(const char* string)
  23.263 {
  23.264   return OVR_strtouq(string, NULL, 10);
  23.265 }
  23.266 
  23.267 
  23.268 // Implemented in GStd.cpp in platform-specific manner.
  23.269 int OVR_CDECL OVR_stricmp(const char* dest, const char* src);
  23.270 int OVR_CDECL OVR_strnicmp(const char* dest, const char* src, UPInt count);
  23.271 
  23.272 inline UPInt OVR_CDECL OVR_sprintf(char *dest, UPInt destsize, const char* format, ...)
  23.273 {
  23.274     va_list argList;
  23.275     va_start(argList,format);
  23.276     UPInt ret;
  23.277 #if defined(OVR_CC_MSVC)
  23.278     #if defined(OVR_MSVC_SAFESTRING)
  23.279         ret = _vsnprintf_s(dest, destsize, _TRUNCATE, format, argList);
  23.280         OVR_ASSERT(ret != -1);
  23.281     #else
  23.282         OVR_UNUSED(destsize);
  23.283         ret = _vsnprintf(dest, destsize - 1, format, argList); // -1 for space for the null character
  23.284         OVR_ASSERT(ret != -1);
  23.285         dest[destsize-1] = 0;
  23.286     #endif
  23.287 #else
  23.288     OVR_UNUSED(destsize);
  23.289     ret = vsprintf(dest, format, argList);
  23.290     OVR_ASSERT(ret < destsize);
  23.291 #endif
  23.292     va_end(argList);
  23.293     return ret;
  23.294 }
  23.295 
  23.296 inline UPInt OVR_CDECL OVR_vsprintf(char *dest, UPInt destsize, const char * format, va_list argList)
  23.297 {
  23.298     UPInt ret;
  23.299 #if defined(OVR_CC_MSVC)
  23.300     #if defined(OVR_MSVC_SAFESTRING)
  23.301         dest[0] = '\0';
  23.302         int rv = vsnprintf_s(dest, destsize, _TRUNCATE, format, argList);
  23.303         if (rv == -1)
  23.304         {
  23.305             dest[destsize - 1] = '\0';
  23.306             ret = destsize - 1;
  23.307         }
  23.308         else
  23.309             ret = (UPInt)rv;
  23.310     #else
  23.311         OVR_UNUSED(destsize);
  23.312         int rv = _vsnprintf(dest, destsize - 1, format, argList);
  23.313         OVR_ASSERT(rv != -1);
  23.314         ret = (UPInt)rv;
  23.315         dest[destsize-1] = 0;
  23.316     #endif
  23.317 #else
  23.318     OVR_UNUSED(destsize);
  23.319     ret = (UPInt)vsprintf(dest, format, argList);
  23.320     OVR_ASSERT(ret < destsize);
  23.321 #endif
  23.322     return ret;
  23.323 }
  23.324 
  23.325 // Returns the number of characters in the formatted string.
  23.326 inline UPInt OVR_CDECL OVR_vscprintf(const char * format, va_list argList)
  23.327 {
  23.328     UPInt ret;
  23.329 #if defined(OVR_CC_MSVC)
  23.330     ret = (UPInt) _vscprintf(format, argList);
  23.331 #else    
  23.332     ret = (UPInt) vsnprintf(NULL, 0, format, argList);
  23.333 #endif
  23.334     return ret;       
  23.335 }
  23.336 
  23.337 
  23.338 wchar_t* OVR_CDECL OVR_wcscpy(wchar_t* dest, UPInt destsize, const wchar_t* src);
  23.339 wchar_t* OVR_CDECL OVR_wcsncpy(wchar_t* dest, UPInt destsize, const wchar_t* src, UPInt count);
  23.340 wchar_t* OVR_CDECL OVR_wcscat(wchar_t* dest, UPInt destsize, const wchar_t* src);
  23.341 UPInt    OVR_CDECL OVR_wcslen(const wchar_t* str);
  23.342 int      OVR_CDECL OVR_wcscmp(const wchar_t* a, const wchar_t* b);
  23.343 int      OVR_CDECL OVR_wcsicmp(const wchar_t* a, const wchar_t* b);
  23.344 
  23.345 inline int OVR_CDECL OVR_wcsicoll(const wchar_t* a, const wchar_t* b)
  23.346 {
  23.347 #if defined(OVR_OS_WIN32)
  23.348 #if defined(OVR_CC_MSVC) && (OVR_CC_MSVC >= 1400)
  23.349     return ::_wcsicoll(a, b);
  23.350 #else
  23.351     return ::wcsicoll(a, b);
  23.352 #endif
  23.353 #else
  23.354     // not supported, use regular wcsicmp
  23.355     return OVR_wcsicmp(a, b);
  23.356 #endif
  23.357 }
  23.358 
  23.359 inline int OVR_CDECL OVR_wcscoll(const wchar_t* a, const wchar_t* b)
  23.360 {
  23.361 #if defined(OVR_OS_WIN32) || defined(OVR_OS_LINUX)
  23.362     return wcscoll(a, b);
  23.363 #else
  23.364     // not supported, use regular wcscmp
  23.365     return OVR_wcscmp(a, b);
  23.366 #endif
  23.367 }
  23.368 
  23.369 #ifndef OVR_NO_WCTYPE
  23.370 
  23.371 inline int OVR_CDECL UnicodeCharIs(const UInt16* table, wchar_t charCode)
  23.372 {
  23.373     unsigned offset = table[charCode >> 8];
  23.374     if (offset == 0) return 0;
  23.375     if (offset == 1) return 1;
  23.376     return (table[offset + ((charCode >> 4) & 15)] & (1 << (charCode & 15))) != 0;
  23.377 }
  23.378 
  23.379 extern const UInt16 UnicodeAlnumBits[];
  23.380 extern const UInt16 UnicodeAlphaBits[];
  23.381 extern const UInt16 UnicodeDigitBits[];
  23.382 extern const UInt16 UnicodeSpaceBits[];
  23.383 extern const UInt16 UnicodeXDigitBits[];
  23.384 
  23.385 // Uncomment if necessary
  23.386 //extern const UInt16 UnicodeCntrlBits[];
  23.387 //extern const UInt16 UnicodeGraphBits[];
  23.388 //extern const UInt16 UnicodeLowerBits[];
  23.389 //extern const UInt16 UnicodePrintBits[];
  23.390 //extern const UInt16 UnicodePunctBits[];
  23.391 //extern const UInt16 UnicodeUpperBits[];
  23.392 
  23.393 inline int OVR_CDECL OVR_iswalnum (wchar_t charCode) { return UnicodeCharIs(UnicodeAlnumBits,  charCode); }
  23.394 inline int OVR_CDECL OVR_iswalpha (wchar_t charCode) { return UnicodeCharIs(UnicodeAlphaBits,  charCode); }
  23.395 inline int OVR_CDECL OVR_iswdigit (wchar_t charCode) { return UnicodeCharIs(UnicodeDigitBits,  charCode); }
  23.396 inline int OVR_CDECL OVR_iswspace (wchar_t charCode) { return UnicodeCharIs(UnicodeSpaceBits,  charCode); }
  23.397 inline int OVR_CDECL OVR_iswxdigit(wchar_t charCode) { return UnicodeCharIs(UnicodeXDigitBits, charCode); }
  23.398 
  23.399 // Uncomment if necessary
  23.400 //inline int OVR_CDECL OVR_iswcntrl (wchar_t charCode) { return UnicodeCharIs(UnicodeCntrlBits,  charCode); }
  23.401 //inline int OVR_CDECL OVR_iswgraph (wchar_t charCode) { return UnicodeCharIs(UnicodeGraphBits,  charCode); }
  23.402 //inline int OVR_CDECL OVR_iswlower (wchar_t charCode) { return UnicodeCharIs(UnicodeLowerBits,  charCode); }
  23.403 //inline int OVR_CDECL OVR_iswprint (wchar_t charCode) { return UnicodeCharIs(UnicodePrintBits,  charCode); }
  23.404 //inline int OVR_CDECL OVR_iswpunct (wchar_t charCode) { return UnicodeCharIs(UnicodePunctBits,  charCode); }
  23.405 //inline int OVR_CDECL OVR_iswupper (wchar_t charCode) { return UnicodeCharIs(UnicodeUpperBits,  charCode); }
  23.406 
  23.407 int OVR_CDECL OVR_towupper(wchar_t charCode);
  23.408 int OVR_CDECL OVR_towlower(wchar_t charCode);
  23.409 
  23.410 #else // OVR_NO_WCTYPE
  23.411 
  23.412 inline int OVR_CDECL OVR_iswspace(wchar_t c)
  23.413 {
  23.414     return iswspace(c);
  23.415 }
  23.416 
  23.417 inline int OVR_CDECL OVR_iswdigit(wchar_t c)
  23.418 {
  23.419     return iswdigit(c);
  23.420 }
  23.421 
  23.422 inline int OVR_CDECL OVR_iswxdigit(wchar_t c)
  23.423 {
  23.424     return iswxdigit(c);
  23.425 }
  23.426 
  23.427 inline int OVR_CDECL OVR_iswalpha(wchar_t c)
  23.428 {
  23.429     return iswalpha(c);
  23.430 }
  23.431 
  23.432 inline int OVR_CDECL OVR_iswalnum(wchar_t c)
  23.433 {
  23.434     return iswalnum(c);
  23.435 }
  23.436 
  23.437 inline wchar_t OVR_CDECL OVR_towlower(wchar_t c)
  23.438 {
  23.439     return (wchar_t)towlower(c);
  23.440 }
  23.441 
  23.442 inline wchar_t OVR_towupper(wchar_t c)
  23.443 {
  23.444     return (wchar_t)towupper(c);
  23.445 }
  23.446 
  23.447 #endif // OVR_NO_WCTYPE
  23.448 
  23.449 // ASCII versions of tolower and toupper. Don't use "char"
  23.450 inline int OVR_CDECL OVR_tolower(int c)
  23.451 {
  23.452     return (c >= 'A' && c <= 'Z') ? c - 'A' + 'a' : c;
  23.453 }
  23.454 
  23.455 inline int OVR_CDECL OVR_toupper(int c)
  23.456 {
  23.457     return (c >= 'a' && c <= 'z') ? c - 'a' + 'A' : c;
  23.458 }
  23.459 
  23.460 
  23.461 
  23.462 inline double OVR_CDECL OVR_wcstod(const wchar_t* string, wchar_t** tailptr)
  23.463 {
  23.464 #if defined(OVR_OS_OTHER)
  23.465     OVR_UNUSED(tailptr);
  23.466     char buffer[64];
  23.467     char* tp = NULL;
  23.468     UPInt max = OVR_wcslen(string);
  23.469     if (max > 63) max = 63;
  23.470     unsigned char c = 0;
  23.471     for (UPInt i=0; i < max; i++)
  23.472     {
  23.473         c = (unsigned char)string[i];
  23.474         buffer[i] = ((c) < 128 ? (char)c : '!');
  23.475     }
  23.476     buffer[max] = 0;
  23.477     return OVR_strtod(buffer, &tp);
  23.478 #else
  23.479     return wcstod(string, tailptr);
  23.480 #endif
  23.481 }
  23.482 
  23.483 inline long OVR_CDECL OVR_wcstol(const wchar_t* string, wchar_t** tailptr, int radix)
  23.484 {
  23.485 #if defined(OVR_OS_OTHER)
  23.486     OVR_UNUSED(tailptr);
  23.487     char buffer[64];
  23.488     char* tp = NULL;
  23.489     UPInt max = OVR_wcslen(string);
  23.490     if (max > 63) max = 63;
  23.491     unsigned char c = 0;
  23.492     for (UPInt i=0; i < max; i++)
  23.493     {
  23.494         c = (unsigned char)string[i];
  23.495         buffer[i] = ((c) < 128 ? (char)c : '!');
  23.496     }
  23.497     buffer[max] = 0;
  23.498     return strtol(buffer, &tp, radix);
  23.499 #else
  23.500     return wcstol(string, tailptr, radix);
  23.501 #endif
  23.502 }
  23.503 
  23.504 } // OVR
  23.505 
  23.506 #endif // OVR_Std_h
  23.507 \ No newline at end of file
  23.508 +/************************************************************************************
  23.509 +
  23.510 +PublicHeader:   OVR.h
  23.511 +Filename    :   OVR_Std.h
  23.512 +Content     :   Standard C function interface
  23.513 +Created     :   September 19, 2012
  23.514 +Notes       : 
  23.515 +
  23.516 +Copyright   :   Copyright 2012 Oculus VR, Inc. All Rights reserved.
  23.517 +
  23.518 +Use of this software is subject to the terms of the Oculus license
  23.519 +agreement provided at the time of installation or download, or which
  23.520 +otherwise accompanies this software in either electronic or hard copy form.
  23.521 +
  23.522 +************************************************************************************/
  23.523 +
  23.524 +#ifndef OVR_Std_h
  23.525 +#define OVR_Std_h
  23.526 +
  23.527 +#include "OVR_Types.h"
  23.528 +#include <stdarg.h> // for va_list args
  23.529 +#include <string.h>
  23.530 +#include <stdio.h>
  23.531 +#include <stdlib.h>
  23.532 +#include <ctype.h>
  23.533 +
  23.534 +#if !defined(OVR_OS_WINCE) && defined(OVR_CC_MSVC) && (OVR_CC_MSVC >= 1400)
  23.535 +#define OVR_MSVC_SAFESTRING
  23.536 +#include <errno.h>
  23.537 +#endif
  23.538 +
  23.539 +// Wide-char funcs
  23.540 +#include <wchar.h>
  23.541 +#include <wctype.h>
  23.542 +
  23.543 +namespace OVR {
  23.544 +
  23.545 +#if defined(OVR_OS_WIN32)
  23.546 +inline char* OVR_CDECL OVR_itoa(int val, char *dest, UPInt destsize, int radix)
  23.547 +{
  23.548 +#if defined(OVR_MSVC_SAFESTRING)
  23.549 +    _itoa_s(val, dest, destsize, radix);
  23.550 +    return dest;
  23.551 +#else
  23.552 +    OVR_UNUSED(destsize);
  23.553 +    return itoa(val, dest, radix);
  23.554 +#endif
  23.555 +}
  23.556 +#else // OVR_OS_WIN32
  23.557 +inline char* OVR_itoa(int val, char* dest, unsigned int len, int radix)
  23.558 +{
  23.559 +    if (val == 0)
  23.560 +    {
  23.561 +        if (len > 1)
  23.562 +        {
  23.563 +            dest[0] = '0';
  23.564 +            dest[1] = '\0';  
  23.565 +        }
  23.566 +        return dest;
  23.567 +    }
  23.568 +
  23.569 +    int cur = val;
  23.570 +    unsigned int i    = 0; 
  23.571 +    unsigned int sign = 0;
  23.572 +
  23.573 +    if (val < 0)
  23.574 +    {
  23.575 +        val = -val;
  23.576 +        sign = 1;
  23.577 +    }
  23.578 +
  23.579 +    while ((val != 0) && (i < (len - 1 - sign)))        
  23.580 +    {
  23.581 +        cur    = val % radix;
  23.582 +        val   /= radix;
  23.583 +
  23.584 +        if (radix == 16)
  23.585 +        {
  23.586 +            switch(cur)
  23.587 +            {
  23.588 +            case 10:
  23.589 +                dest[i] = 'a';
  23.590 +                break;
  23.591 +            case 11:
  23.592 +                dest[i] = 'b';
  23.593 +                break;
  23.594 +            case 12:
  23.595 +                dest[i] = 'c';
  23.596 +                break;
  23.597 +            case 13:
  23.598 +                dest[i] = 'd';
  23.599 +                break;
  23.600 +            case 14:
  23.601 +                dest[i] = 'e';
  23.602 +                break;
  23.603 +            case 15:
  23.604 +                dest[i] = 'f';
  23.605 +                break;
  23.606 +            default:
  23.607 +                dest[i] = (char)('0' + cur);
  23.608 +                break;
  23.609 +            }
  23.610 +        } 
  23.611 +        else
  23.612 +        {
  23.613 +            dest[i] = (char)('0' + cur);
  23.614 +        }
  23.615 +        ++i;
  23.616 +    }
  23.617 +
  23.618 +    if (sign)
  23.619 +    {
  23.620 +        dest[i++] = '-';
  23.621 +    }
  23.622 +
  23.623 +    for (unsigned int j = 0; j < i / 2; ++j)
  23.624 +    {
  23.625 +        char tmp        = dest[j];
  23.626 +        dest[j]         = dest[i - 1 - j];
  23.627 +        dest[i - 1 - j] = tmp;
  23.628 +    }
  23.629 +    dest[i] = '\0';
  23.630 +
  23.631 +    return dest;
  23.632 +}
  23.633 +
  23.634 +#endif
  23.635 +
  23.636 +
  23.637 +// String functions
  23.638 +
  23.639 +inline UPInt OVR_CDECL OVR_strlen(const char* str)
  23.640 +{
  23.641 +    return strlen(str);
  23.642 +}
  23.643 +
  23.644 +inline char* OVR_CDECL OVR_strcpy(char* dest, UPInt destsize, const char* src)
  23.645 +{
  23.646 +#if defined(OVR_MSVC_SAFESTRING)
  23.647 +    strcpy_s(dest, destsize, src);
  23.648 +    return dest;
  23.649 +#else
  23.650 +    OVR_UNUSED(destsize);
  23.651 +    return strcpy(dest, src);
  23.652 +#endif
  23.653 +}
  23.654 +
  23.655 +inline char* OVR_CDECL OVR_strncpy(char* dest, UPInt destsize, const char* src, UPInt count)
  23.656 +{
  23.657 +#if defined(OVR_MSVC_SAFESTRING)
  23.658 +    strncpy_s(dest, destsize, src, count);
  23.659 +    return dest;
  23.660 +#else
  23.661 +    OVR_UNUSED(destsize);
  23.662 +    return strncpy(dest, src, count);
  23.663 +#endif
  23.664 +}
  23.665 +
  23.666 +inline char * OVR_CDECL OVR_strcat(char* dest, UPInt destsize, const char* src)
  23.667 +{
  23.668 +#if defined(OVR_MSVC_SAFESTRING)
  23.669 +    strcat_s(dest, destsize, src);
  23.670 +    return dest;
  23.671 +#else
  23.672 +    OVR_UNUSED(destsize);
  23.673 +    return strcat(dest, src);
  23.674 +#endif
  23.675 +}
  23.676 +
  23.677 +inline int OVR_CDECL OVR_strcmp(const char* dest, const char* src)
  23.678 +{
  23.679 +    return strcmp(dest, src);
  23.680 +}
  23.681 +
  23.682 +inline const char* OVR_CDECL OVR_strchr(const char* str, char c)
  23.683 +{
  23.684 +    return strchr(str, c);
  23.685 +}
  23.686 +
  23.687 +inline char* OVR_CDECL OVR_strchr(char* str, char c)
  23.688 +{
  23.689 +    return strchr(str, c);
  23.690 +}
  23.691 +
  23.692 +inline const char* OVR_strrchr(const char* str, char c)
  23.693 +{
  23.694 +    UPInt len = OVR_strlen(str);
  23.695 +    for (UPInt i=len; i>0; i--)     
  23.696 +        if (str[i]==c) 
  23.697 +            return str+i;
  23.698 +    return 0;
  23.699 +}
  23.700 +
  23.701 +inline const UByte* OVR_CDECL OVR_memrchr(const UByte* str, UPInt size, UByte c)
  23.702 +{
  23.703 +    for (SPInt i = (SPInt)size - 1; i >= 0; i--)     
  23.704 +    {
  23.705 +        if (str[i] == c) 
  23.706 +            return str + i;
  23.707 +    }
  23.708 +    return 0;
  23.709 +}
  23.710 +
  23.711 +inline char* OVR_CDECL OVR_strrchr(char* str, char c)
  23.712 +{
  23.713 +    UPInt len = OVR_strlen(str);
  23.714 +    for (UPInt i=len; i>0; i--)     
  23.715 +        if (str[i]==c) 
  23.716 +            return str+i;
  23.717 +    return 0;
  23.718 +}
  23.719 +
  23.720 +
  23.721 +double OVR_CDECL OVR_strtod(const char* string, char** tailptr);
  23.722 +
  23.723 +inline long OVR_CDECL OVR_strtol(const char* string, char** tailptr, int radix)
  23.724 +{
  23.725 +    return strtol(string, tailptr, radix);
  23.726 +}
  23.727 +
  23.728 +inline long OVR_CDECL OVR_strtoul(const char* string, char** tailptr, int radix)
  23.729 +{
  23.730 +    return strtoul(string, tailptr, radix);
  23.731 +}
  23.732 +
  23.733 +inline int OVR_CDECL OVR_strncmp(const char* ws1, const char* ws2, UPInt size)
  23.734 +{
  23.735 +    return strncmp(ws1, ws2, size);
  23.736 +}
  23.737 +
  23.738 +inline UInt64 OVR_CDECL OVR_strtouq(const char *nptr, char **endptr, int base)
  23.739 +{
  23.740 +#if defined(OVR_CC_MSVC) && !defined(OVR_OS_WINCE)
  23.741 +    return _strtoui64(nptr, endptr, base);
  23.742 +#else
  23.743 +    return strtoull(nptr, endptr, base);
  23.744 +#endif
  23.745 +}
  23.746 +
  23.747 +inline SInt64 OVR_CDECL OVR_strtoq(const char *nptr, char **endptr, int base)
  23.748 +{
  23.749 +#if defined(OVR_CC_MSVC) && !defined(OVR_OS_WINCE)
  23.750 +    return _strtoi64(nptr, endptr, base);
  23.751 +#else
  23.752 +    return strtoll(nptr, endptr, base);
  23.753 +#endif
  23.754 +}
  23.755 +
  23.756 +
  23.757 +inline SInt64 OVR_CDECL OVR_atoq(const char* string)
  23.758 +{
  23.759 +#if defined(OVR_CC_MSVC) && !defined(OVR_OS_WINCE)
  23.760 +    return _atoi64(string);
  23.761 +#else
  23.762 +    return atoll(string);
  23.763 +#endif
  23.764 +}
  23.765 +
  23.766 +inline UInt64 OVR_CDECL OVR_atouq(const char* string)
  23.767 +{
  23.768 +  return OVR_strtouq(string, NULL, 10);
  23.769 +}
  23.770 +
  23.771 +
  23.772 +// Implemented in GStd.cpp in platform-specific manner.
  23.773 +int OVR_CDECL OVR_stricmp(const char* dest, const char* src);
  23.774 +int OVR_CDECL OVR_strnicmp(const char* dest, const char* src, UPInt count);
  23.775 +
  23.776 +inline UPInt OVR_CDECL OVR_sprintf(char *dest, UPInt destsize, const char* format, ...)
  23.777 +{
  23.778 +    va_list argList;
  23.779 +    va_start(argList,format);
  23.780 +    UPInt ret;
  23.781 +#if defined(OVR_CC_MSVC)
  23.782 +    #if defined(OVR_MSVC_SAFESTRING)
  23.783 +        ret = _vsnprintf_s(dest, destsize, _TRUNCATE, format, argList);
  23.784 +        OVR_ASSERT(ret != -1);
  23.785 +    #else
  23.786 +        OVR_UNUSED(destsize);
  23.787 +        ret = _vsnprintf(dest, destsize - 1, format, argList); // -1 for space for the null character
  23.788 +        OVR_ASSERT(ret != -1);
  23.789 +        dest[destsize-1] = 0;
  23.790 +    #endif
  23.791 +#else
  23.792 +    OVR_UNUSED(destsize);
  23.793 +    ret = vsprintf(dest, format, argList);
  23.794 +    OVR_ASSERT(ret < destsize);
  23.795 +#endif
  23.796 +    va_end(argList);
  23.797 +    return ret;
  23.798 +}
  23.799 +
  23.800 +inline UPInt OVR_CDECL OVR_vsprintf(char *dest, UPInt destsize, const char * format, va_list argList)
  23.801 +{
  23.802 +    UPInt ret;
  23.803 +#if defined(OVR_CC_MSVC)
  23.804 +    #if defined(OVR_MSVC_SAFESTRING)
  23.805 +        dest[0] = '\0';
  23.806 +        int rv = vsnprintf_s(dest, destsize, _TRUNCATE, format, argList);
  23.807 +        if (rv == -1)
  23.808 +        {
  23.809 +            dest[destsize - 1] = '\0';
  23.810 +            ret = destsize - 1;
  23.811 +        }
  23.812 +        else
  23.813 +            ret = (UPInt)rv;
  23.814 +    #else
  23.815 +        OVR_UNUSED(destsize);
  23.816 +        int rv = _vsnprintf(dest, destsize - 1, format, argList);
  23.817 +        OVR_ASSERT(rv != -1);
  23.818 +        ret = (UPInt)rv;
  23.819 +        dest[destsize-1] = 0;
  23.820 +    #endif
  23.821 +#else
  23.822 +    OVR_UNUSED(destsize);
  23.823 +    ret = (UPInt)vsprintf(dest, format, argList);
  23.824 +    OVR_ASSERT(ret < destsize);
  23.825 +#endif
  23.826 +    return ret;
  23.827 +}
  23.828 +
  23.829 +// Returns the number of characters in the formatted string.
  23.830 +inline UPInt OVR_CDECL OVR_vscprintf(const char * format, va_list argList)
  23.831 +{
  23.832 +    UPInt ret;
  23.833 +#if defined(OVR_CC_MSVC)
  23.834 +    ret = (UPInt) _vscprintf(format, argList);
  23.835 +#else    
  23.836 +    ret = (UPInt) vsnprintf(NULL, 0, format, argList);
  23.837 +#endif
  23.838 +    return ret;       
  23.839 +}
  23.840 +
  23.841 +
  23.842 +wchar_t* OVR_CDECL OVR_wcscpy(wchar_t* dest, UPInt destsize, const wchar_t* src);
  23.843 +wchar_t* OVR_CDECL OVR_wcsncpy(wchar_t* dest, UPInt destsize, const wchar_t* src, UPInt count);
  23.844 +wchar_t* OVR_CDECL OVR_wcscat(wchar_t* dest, UPInt destsize, const wchar_t* src);
  23.845 +UPInt    OVR_CDECL OVR_wcslen(const wchar_t* str);
  23.846 +int      OVR_CDECL OVR_wcscmp(const wchar_t* a, const wchar_t* b);
  23.847 +int      OVR_CDECL OVR_wcsicmp(const wchar_t* a, const wchar_t* b);
  23.848 +
  23.849 +inline int OVR_CDECL OVR_wcsicoll(const wchar_t* a, const wchar_t* b)
  23.850 +{
  23.851 +#if defined(OVR_OS_WIN32)
  23.852 +#if defined(OVR_CC_MSVC) && (OVR_CC_MSVC >= 1400)
  23.853 +    return ::_wcsicoll(a, b);
  23.854 +#else
  23.855 +    return ::wcsicoll(a, b);
  23.856 +#endif
  23.857 +#else
  23.858 +    // not supported, use regular wcsicmp
  23.859 +    return OVR_wcsicmp(a, b);
  23.860 +#endif
  23.861 +}
  23.862 +
  23.863 +inline int OVR_CDECL OVR_wcscoll(const wchar_t* a, const wchar_t* b)
  23.864 +{
  23.865 +#if defined(OVR_OS_WIN32) || defined(OVR_OS_LINUX)
  23.866 +    return wcscoll(a, b);
  23.867 +#else
  23.868 +    // not supported, use regular wcscmp
  23.869 +    return OVR_wcscmp(a, b);
  23.870 +#endif
  23.871 +}
  23.872 +
  23.873 +#ifndef OVR_NO_WCTYPE
  23.874 +
  23.875 +inline int OVR_CDECL UnicodeCharIs(const UInt16* table, wchar_t charCode)
  23.876 +{
  23.877 +    unsigned offset = table[charCode >> 8];
  23.878 +    if (offset == 0) return 0;
  23.879 +    if (offset == 1) return 1;
  23.880 +    return (table[offset + ((charCode >> 4) & 15)] & (1 << (charCode & 15))) != 0;
  23.881 +}
  23.882 +
  23.883 +extern const UInt16 UnicodeAlnumBits[];
  23.884 +extern const UInt16 UnicodeAlphaBits[];
  23.885 +extern const UInt16 UnicodeDigitBits[];
  23.886 +extern const UInt16 UnicodeSpaceBits[];
  23.887 +extern const UInt16 UnicodeXDigitBits[];
  23.888 +
  23.889 +// Uncomment if necessary
  23.890 +//extern const UInt16 UnicodeCntrlBits[];
  23.891 +//extern const UInt16 UnicodeGraphBits[];
  23.892 +//extern const UInt16 UnicodeLowerBits[];
  23.893 +//extern const UInt16 UnicodePrintBits[];
  23.894 +//extern const UInt16 UnicodePunctBits[];
  23.895 +//extern const UInt16 UnicodeUpperBits[];
  23.896 +
  23.897 +inline int OVR_CDECL OVR_iswalnum (wchar_t charCode) { return UnicodeCharIs(UnicodeAlnumBits,  charCode); }
  23.898 +inline int OVR_CDECL OVR_iswalpha (wchar_t charCode) { return UnicodeCharIs(UnicodeAlphaBits,  charCode); }
  23.899 +inline int OVR_CDECL OVR_iswdigit (wchar_t charCode) { return UnicodeCharIs(UnicodeDigitBits,  charCode); }
  23.900 +inline int OVR_CDECL OVR_iswspace (wchar_t charCode) { return UnicodeCharIs(UnicodeSpaceBits,  charCode); }
  23.901 +inline int OVR_CDECL OVR_iswxdigit(wchar_t charCode) { return UnicodeCharIs(UnicodeXDigitBits, charCode); }
  23.902 +
  23.903 +// Uncomment if necessary
  23.904 +//inline int OVR_CDECL OVR_iswcntrl (wchar_t charCode) { return UnicodeCharIs(UnicodeCntrlBits,  charCode); }
  23.905 +//inline int OVR_CDECL OVR_iswgraph (wchar_t charCode) { return UnicodeCharIs(UnicodeGraphBits,  charCode); }
  23.906 +//inline int OVR_CDECL OVR_iswlower (wchar_t charCode) { return UnicodeCharIs(UnicodeLowerBits,  charCode); }
  23.907 +//inline int OVR_CDECL OVR_iswprint (wchar_t charCode) { return UnicodeCharIs(UnicodePrintBits,  charCode); }
  23.908 +//inline int OVR_CDECL OVR_iswpunct (wchar_t charCode) { return UnicodeCharIs(UnicodePunctBits,  charCode); }
  23.909 +//inline int OVR_CDECL OVR_iswupper (wchar_t charCode) { return UnicodeCharIs(UnicodeUpperBits,  charCode); }
  23.910 +
  23.911 +int OVR_CDECL OVR_towupper(wchar_t charCode);
  23.912 +int OVR_CDECL OVR_towlower(wchar_t charCode);
  23.913 +
  23.914 +#else // OVR_NO_WCTYPE
  23.915 +
  23.916 +inline int OVR_CDECL OVR_iswspace(wchar_t c)
  23.917 +{
  23.918 +    return iswspace(c);
  23.919 +}
  23.920 +
  23.921 +inline int OVR_CDECL OVR_iswdigit(wchar_t c)
  23.922 +{
  23.923 +    return iswdigit(c);
  23.924 +}
  23.925 +
  23.926 +inline int OVR_CDECL OVR_iswxdigit(wchar_t c)
  23.927 +{
  23.928 +    return iswxdigit(c);
  23.929 +}
  23.930 +
  23.931 +inline int OVR_CDECL OVR_iswalpha(wchar_t c)
  23.932 +{
  23.933 +    return iswalpha(c);
  23.934 +}
  23.935 +
  23.936 +inline int OVR_CDECL OVR_iswalnum(wchar_t c)
  23.937 +{
  23.938 +    return iswalnum(c);
  23.939 +}
  23.940 +
  23.941 +inline wchar_t OVR_CDECL OVR_towlower(wchar_t c)
  23.942 +{
  23.943 +    return (wchar_t)towlower(c);
  23.944 +}
  23.945 +
  23.946 +inline wchar_t OVR_towupper(wchar_t c)
  23.947 +{
  23.948 +    return (wchar_t)towupper(c);
  23.949 +}
  23.950 +
  23.951 +#endif // OVR_NO_WCTYPE
  23.952 +
  23.953 +// ASCII versions of tolower and toupper. Don't use "char"
  23.954 +inline int OVR_CDECL OVR_tolower(int c)
  23.955 +{
  23.956 +    return (c >= 'A' && c <= 'Z') ? c - 'A' + 'a' : c;
  23.957 +}
  23.958 +
  23.959 +inline int OVR_CDECL OVR_toupper(int c)
  23.960 +{
  23.961 +    return (c >= 'a' && c <= 'z') ? c - 'a' + 'A' : c;
  23.962 +}
  23.963 +
  23.964 +
  23.965 +
  23.966 +inline double OVR_CDECL OVR_wcstod(const wchar_t* string, wchar_t** tailptr)
  23.967 +{
  23.968 +#if defined(OVR_OS_OTHER)
  23.969 +    OVR_UNUSED(tailptr);
  23.970 +    char buffer[64];
  23.971 +    char* tp = NULL;
  23.972 +    UPInt max = OVR_wcslen(string);
  23.973 +    if (max > 63) max = 63;
  23.974 +    unsigned char c = 0;
  23.975 +    for (UPInt i=0; i < max; i++)
  23.976 +    {
  23.977 +        c = (unsigned char)string[i];
  23.978 +        buffer[i] = ((c) < 128 ? (char)c : '!');
  23.979 +    }
  23.980 +    buffer[max] = 0;
  23.981 +    return OVR_strtod(buffer, &tp);
  23.982 +#else
  23.983 +    return wcstod(string, tailptr);
  23.984 +#endif
  23.985 +}
  23.986 +
  23.987 +inline long OVR_CDECL OVR_wcstol(const wchar_t* string, wchar_t** tailptr, int radix)
  23.988 +{
  23.989 +#if defined(OVR_OS_OTHER)
  23.990 +    OVR_UNUSED(tailptr);
  23.991 +    char buffer[64];
  23.992 +    char* tp = NULL;
  23.993 +    UPInt max = OVR_wcslen(string);
  23.994 +    if (max > 63) max = 63;
  23.995 +    unsigned char c = 0;
  23.996 +    for (UPInt i=0; i < max; i++)
  23.997 +    {
  23.998 +        c = (unsigned char)string[i];
  23.999 +        buffer[i] = ((c) < 128 ? (char)c : '!');
 23.1000 +    }
 23.1001 +    buffer[max] = 0;
 23.1002 +    return strtol(buffer, &tp, radix);
 23.1003 +#else
 23.1004 +    return wcstol(string, tailptr, radix);
 23.1005 +#endif
 23.1006 +}
 23.1007 +
 23.1008 +} // OVR
 23.1009 +
 23.1010 +#endif // OVR_Std_h
    24.1 --- a/libovr/Src/Kernel/OVR_String.cpp	Sat Sep 14 17:51:03 2013 +0300
    24.2 +++ b/libovr/Src/Kernel/OVR_String.cpp	Sun Sep 15 04:10:05 2013 +0300
    24.3 @@ -1,1 +1,752 @@
    24.4 -/************************************************************************************
    24.5 
    24.6 Filename    :   OVR_String.cpp
    24.7 Content     :   String UTF8 string implementation with copy-on-write semantics
    24.8                 (thread-safe for assignment but not modification).
    24.9 Created     :   September 19, 2012
   24.10 Notes       : 
   24.11 
   24.12 Copyright   :   Copyright 2012 Oculus VR, Inc. All Rights reserved.
   24.13 
   24.14 Use of this software is subject to the terms of the Oculus license
   24.15 agreement provided at the time of installation or download, or which
   24.16 otherwise accompanies this software in either electronic or hard copy form.
   24.17 
   24.18 ************************************************************************************/
   24.19 
   24.20 #include "OVR_String.h"
   24.21 
   24.22 #include <stdlib.h>
   24.23 #include <ctype.h>
   24.24 
   24.25 #ifdef OVR_OS_QNX
   24.26 # include <strings.h>
   24.27 #endif
   24.28 
   24.29 namespace OVR {
   24.30 
   24.31 #define String_LengthIsSize (UPInt(1) << String::Flag_LengthIsSizeShift)
   24.32 
   24.33 String::DataDesc String::NullData = {String_LengthIsSize, 1, {0} };
   24.34 
   24.35 
   24.36 String::String()
   24.37 {
   24.38     pData = &NullData;
   24.39     pData->AddRef();
   24.40 };
   24.41 
   24.42 String::String(const char* pdata)
   24.43 {
   24.44     // Obtain length in bytes; it doesn't matter if _data is UTF8.
   24.45     UPInt size = pdata ? OVR_strlen(pdata) : 0; 
   24.46     pData = AllocDataCopy1(size, 0, pdata, size);
   24.47 };
   24.48 
   24.49 String::String(const char* pdata1, const char* pdata2, const char* pdata3)
   24.50 {
   24.51     // Obtain length in bytes; it doesn't matter if _data is UTF8.
   24.52     UPInt size1 = pdata1 ? OVR_strlen(pdata1) : 0; 
   24.53     UPInt size2 = pdata2 ? OVR_strlen(pdata2) : 0; 
   24.54     UPInt size3 = pdata3 ? OVR_strlen(pdata3) : 0; 
   24.55 
   24.56     DataDesc *pdataDesc = AllocDataCopy2(size1 + size2 + size3, 0,
   24.57                                          pdata1, size1, pdata2, size2);
   24.58     memcpy(pdataDesc->Data + size1 + size2, pdata3, size3);   
   24.59     pData = pdataDesc;    
   24.60 }
   24.61 
   24.62 String::String(const char* pdata, UPInt size)
   24.63 {
   24.64     OVR_ASSERT((size == 0) || (pdata != 0));
   24.65     pData = AllocDataCopy1(size, 0, pdata, size);
   24.66 };
   24.67 
   24.68 
   24.69 String::String(const InitStruct& src, UPInt size)
   24.70 {
   24.71     pData = AllocData(size, 0);
   24.72     src.InitString(GetData()->Data, size);
   24.73 }
   24.74 
   24.75 String::String(const String& src)
   24.76 {    
   24.77     pData = src.GetData();
   24.78     pData->AddRef();
   24.79 }
   24.80 
   24.81 String::String(const StringBuffer& src)
   24.82 {
   24.83     pData = AllocDataCopy1(src.GetSize(), 0, src.ToCStr(), src.GetSize());
   24.84 }
   24.85 
   24.86 String::String(const wchar_t* data)
   24.87 {
   24.88     pData = &NullData;
   24.89     pData->AddRef();
   24.90     // Simplified logic for wchar_t constructor.
   24.91     if (data)    
   24.92         *this = data;    
   24.93 }
   24.94 
   24.95 
   24.96 String::DataDesc* String::AllocData(UPInt size, UPInt lengthIsSize)
   24.97 {
   24.98     String::DataDesc* pdesc;
   24.99 
  24.100     if (size == 0)
  24.101     {
  24.102         pdesc = &NullData;
  24.103         pdesc->AddRef();
  24.104         return pdesc;
  24.105     }
  24.106 
  24.107     pdesc = (DataDesc*)OVR_ALLOC(sizeof(DataDesc)+ size);
  24.108     pdesc->Data[size] = 0;
  24.109     pdesc->RefCount = 1;
  24.110     pdesc->Size     = size | lengthIsSize;  
  24.111     return pdesc;
  24.112 }
  24.113 
  24.114 
  24.115 String::DataDesc* String::AllocDataCopy1(UPInt size, UPInt lengthIsSize,
  24.116                                          const char* pdata, UPInt copySize)
  24.117 {
  24.118     String::DataDesc* pdesc = AllocData(size, lengthIsSize);
  24.119     memcpy(pdesc->Data, pdata, copySize);
  24.120     return pdesc;
  24.121 }
  24.122 
  24.123 String::DataDesc* String::AllocDataCopy2(UPInt size, UPInt lengthIsSize,
  24.124                                          const char* pdata1, UPInt copySize1,
  24.125                                          const char* pdata2, UPInt copySize2)
  24.126 {
  24.127     String::DataDesc* pdesc = AllocData(size, lengthIsSize);
  24.128     memcpy(pdesc->Data, pdata1, copySize1);
  24.129     memcpy(pdesc->Data + copySize1, pdata2, copySize2);
  24.130     return pdesc;
  24.131 }
  24.132 
  24.133 
  24.134 UPInt String::GetLength() const 
  24.135 {
  24.136     // Optimize length accesses for non-UTF8 character strings. 
  24.137     DataDesc* pdata = GetData();
  24.138     UPInt     length, size = pdata->GetSize();
  24.139     
  24.140     if (pdata->LengthIsSize())
  24.141         return size;    
  24.142     
  24.143     length = (UPInt)UTF8Util::GetLength(pdata->Data, (UPInt)size);
  24.144     
  24.145     if (length == size)
  24.146         pdata->Size |= String_LengthIsSize;
  24.147     
  24.148     return length;
  24.149 }
  24.150 
  24.151 
  24.152 //static UInt32 String_CharSearch(const char* buf, )
  24.153 
  24.154 
  24.155 UInt32 String::GetCharAt(UPInt index) const 
  24.156 {  
  24.157     SPInt       i = (SPInt) index;
  24.158     DataDesc*   pdata = GetData();
  24.159     const char* buf = pdata->Data;
  24.160     UInt32      c;
  24.161     
  24.162     if (pdata->LengthIsSize())
  24.163     {
  24.164         OVR_ASSERT(index < pdata->GetSize());
  24.165         buf += i;
  24.166         return UTF8Util::DecodeNextChar_Advance0(&buf);
  24.167     }
  24.168 
  24.169     c = UTF8Util::GetCharAt(index, buf, pdata->GetSize());
  24.170     return c;
  24.171 }
  24.172 
  24.173 UInt32 String::GetFirstCharAt(UPInt index, const char** offset) const
  24.174 {
  24.175     DataDesc*   pdata = GetData();
  24.176     SPInt       i = (SPInt) index;
  24.177     const char* buf = pdata->Data;
  24.178     const char* end = buf + pdata->GetSize();
  24.179     UInt32      c;
  24.180 
  24.181     do 
  24.182     {
  24.183         c = UTF8Util::DecodeNextChar_Advance0(&buf);
  24.184         i--;
  24.185 
  24.186         if (buf >= end)
  24.187         {
  24.188             // We've hit the end of the string; don't go further.
  24.189             OVR_ASSERT(i == 0);
  24.190             return c;
  24.191         }
  24.192     } while (i >= 0);
  24.193 
  24.194     *offset = buf;
  24.195 
  24.196     return c;
  24.197 }
  24.198 
  24.199 UInt32 String::GetNextChar(const char** offset) const
  24.200 {
  24.201     return UTF8Util::DecodeNextChar(offset);
  24.202 }
  24.203 
  24.204 
  24.205 
  24.206 void String::AppendChar(UInt32 ch)
  24.207 {
  24.208     DataDesc*   pdata = GetData();
  24.209     UPInt       size = pdata->GetSize();
  24.210     char        buff[8];
  24.211     SPInt       encodeSize = 0;
  24.212 
  24.213     // Converts ch into UTF8 string and fills it into buff.   
  24.214     UTF8Util::EncodeChar(buff, &encodeSize, ch);
  24.215     OVR_ASSERT(encodeSize >= 0);
  24.216 
  24.217     SetData(AllocDataCopy2(size + (UPInt)encodeSize, 0,
  24.218                            pdata->Data, size, buff, (UPInt)encodeSize));
  24.219     pdata->Release();
  24.220 }
  24.221 
  24.222 
  24.223 void String::AppendString(const wchar_t* pstr, SPInt len)
  24.224 {
  24.225     if (!pstr)
  24.226         return;
  24.227 
  24.228     DataDesc*   pdata = GetData();
  24.229     UPInt       oldSize = pdata->GetSize();    
  24.230     UPInt       encodeSize = (UPInt)UTF8Util::GetEncodeStringSize(pstr, len);
  24.231 
  24.232     DataDesc*   pnewData = AllocDataCopy1(oldSize + (UPInt)encodeSize, 0,
  24.233                                           pdata->Data, oldSize);
  24.234     UTF8Util::EncodeString(pnewData->Data + oldSize,  pstr, len);
  24.235 
  24.236     SetData(pnewData);
  24.237     pdata->Release();
  24.238 }
  24.239 
  24.240 
  24.241 void String::AppendString(const char* putf8str, SPInt utf8StrSz)
  24.242 {
  24.243     if (!putf8str || !utf8StrSz)
  24.244         return;
  24.245     if (utf8StrSz == -1)
  24.246         utf8StrSz = (SPInt)OVR_strlen(putf8str);
  24.247 
  24.248     DataDesc*   pdata = GetData();
  24.249     UPInt       oldSize = pdata->GetSize();
  24.250 
  24.251     SetData(AllocDataCopy2(oldSize + (UPInt)utf8StrSz, 0,
  24.252                            pdata->Data, oldSize, putf8str, (UPInt)utf8StrSz));
  24.253     pdata->Release();
  24.254 }
  24.255 
  24.256 void    String::AssignString(const InitStruct& src, UPInt size)
  24.257 {
  24.258     DataDesc*   poldData = GetData();
  24.259     DataDesc*   pnewData = AllocData(size, 0);
  24.260     src.InitString(pnewData->Data, size);
  24.261     SetData(pnewData);
  24.262     poldData->Release();
  24.263 }
  24.264 
  24.265 void    String::AssignString(const char* putf8str, UPInt size)
  24.266 {
  24.267     DataDesc* poldData = GetData();
  24.268     SetData(AllocDataCopy1(size, 0, putf8str, size));
  24.269     poldData->Release();
  24.270 }
  24.271 
  24.272 void    String::operator = (const char* pstr)
  24.273 {
  24.274     AssignString(pstr, pstr ? OVR_strlen(pstr) : 0);
  24.275 }
  24.276 
  24.277 void    String::operator = (const wchar_t* pwstr)
  24.278 {
  24.279     DataDesc*   poldData = GetData();
  24.280     UPInt       size = pwstr ? (UPInt)UTF8Util::GetEncodeStringSize(pwstr) : 0;
  24.281 
  24.282     DataDesc*   pnewData = AllocData(size, 0);
  24.283     UTF8Util::EncodeString(pnewData->Data, pwstr);
  24.284     SetData(pnewData);
  24.285     poldData->Release();
  24.286 }
  24.287 
  24.288 
  24.289 void    String::operator = (const String& src)
  24.290 {     
  24.291     DataDesc*    psdata = src.GetData();
  24.292     DataDesc*    pdata = GetData();    
  24.293 
  24.294     SetData(psdata);
  24.295     psdata->AddRef();
  24.296     pdata->Release();
  24.297 }
  24.298 
  24.299 
  24.300 void    String::operator = (const StringBuffer& src)
  24.301 { 
  24.302     DataDesc* polddata = GetData();    
  24.303     SetData(AllocDataCopy1(src.GetSize(), 0, src.ToCStr(), src.GetSize()));
  24.304     polddata->Release();
  24.305 }
  24.306 
  24.307 void    String::operator += (const String& src)
  24.308 {
  24.309     DataDesc   *pourData = GetData(),
  24.310                *psrcData = src.GetData();
  24.311     UPInt       ourSize  = pourData->GetSize(),
  24.312                 srcSize  = psrcData->GetSize();
  24.313     UPInt       lflag    = pourData->GetLengthFlag() & psrcData->GetLengthFlag();
  24.314 
  24.315     SetData(AllocDataCopy2(ourSize + srcSize, lflag,
  24.316                            pourData->Data, ourSize, psrcData->Data, srcSize));
  24.317     pourData->Release();
  24.318 }
  24.319 
  24.320 
  24.321 String   String::operator + (const char* str) const
  24.322 {   
  24.323     String tmp1(*this);
  24.324     tmp1 += (str ? str : "");
  24.325     return tmp1;
  24.326 }
  24.327 
  24.328 String   String::operator + (const String& src) const
  24.329 { 
  24.330     String tmp1(*this);
  24.331     tmp1 += src;
  24.332     return tmp1;
  24.333 }
  24.334 
  24.335 void    String::Remove(UPInt posAt, SPInt removeLength)
  24.336 {
  24.337     DataDesc*   pdata = GetData();
  24.338     UPInt       oldSize = pdata->GetSize();    
  24.339     // Length indicates the number of characters to remove. 
  24.340     UPInt       length = GetLength();
  24.341 
  24.342     // If index is past the string, nothing to remove.
  24.343     if (posAt >= length)
  24.344         return;
  24.345     // Otherwise, cap removeLength to the length of the string.
  24.346     if ((posAt + removeLength) > length)
  24.347         removeLength = length - posAt;
  24.348 
  24.349     // Get the byte position of the UTF8 char at position posAt.
  24.350     SPInt bytePos    = UTF8Util::GetByteIndex(posAt, pdata->Data, oldSize);
  24.351     SPInt removeSize = UTF8Util::GetByteIndex(removeLength, pdata->Data + bytePos, oldSize-bytePos);
  24.352 
  24.353     SetData(AllocDataCopy2(oldSize - removeSize, pdata->GetLengthFlag(),
  24.354                            pdata->Data, bytePos,
  24.355                            pData->Data + bytePos + removeSize, (oldSize - bytePos - removeSize)));
  24.356     pdata->Release();
  24.357 }
  24.358 
  24.359 
  24.360 String   String::Substring(UPInt start, UPInt end) const
  24.361 {
  24.362     UPInt length = GetLength();
  24.363     if ((start >= length) || (start >= end))
  24.364         return String();   
  24.365 
  24.366     DataDesc* pdata = GetData();
  24.367     
  24.368     // If size matches, we know the exact index range.
  24.369     if (pdata->LengthIsSize())
  24.370         return String(pdata->Data + start, end - start);
  24.371     
  24.372     // Get position of starting character.
  24.373     SPInt byteStart = UTF8Util::GetByteIndex(start, pdata->Data, pdata->GetSize());
  24.374     SPInt byteSize  = UTF8Util::GetByteIndex(end - start, pdata->Data + byteStart, pdata->GetSize()-byteStart);
  24.375     return String(pdata->Data + byteStart, (UPInt)byteSize);
  24.376 }
  24.377 
  24.378 void String::Clear()
  24.379 {   
  24.380     NullData.AddRef();
  24.381     GetData()->Release();
  24.382     SetData(&NullData);
  24.383 }
  24.384 
  24.385 
  24.386 String   String::ToUpper() const 
  24.387 {       
  24.388     UInt32      c;
  24.389     const char* psource = GetData()->Data;
  24.390     const char* pend = psource + GetData()->GetSize();
  24.391     String      str;
  24.392     SPInt       bufferOffset = 0;
  24.393     char        buffer[512];
  24.394     
  24.395     while(psource < pend)
  24.396     {
  24.397         do {            
  24.398             c = UTF8Util::DecodeNextChar_Advance0(&psource);
  24.399             UTF8Util::EncodeChar(buffer, &bufferOffset, OVR_towupper(wchar_t(c)));
  24.400         } while ((psource < pend) && (bufferOffset < SPInt(sizeof(buffer)-8)));
  24.401 
  24.402         // Append string a piece at a time.
  24.403         str.AppendString(buffer, bufferOffset);
  24.404         bufferOffset = 0;
  24.405     }
  24.406 
  24.407     return str;
  24.408 }
  24.409 
  24.410 String   String::ToLower() const 
  24.411 {
  24.412     UInt32      c;
  24.413     const char* psource = GetData()->Data;
  24.414     const char* pend = psource + GetData()->GetSize();
  24.415     String      str;
  24.416     SPInt       bufferOffset = 0;
  24.417     char        buffer[512];
  24.418 
  24.419     while(psource < pend)
  24.420     {
  24.421         do {
  24.422             c = UTF8Util::DecodeNextChar_Advance0(&psource);
  24.423             UTF8Util::EncodeChar(buffer, &bufferOffset, OVR_towlower(wchar_t(c)));
  24.424         } while ((psource < pend) && (bufferOffset < SPInt(sizeof(buffer)-8)));
  24.425 
  24.426         // Append string a piece at a time.
  24.427         str.AppendString(buffer, bufferOffset);
  24.428         bufferOffset = 0;
  24.429     }
  24.430 
  24.431     return str;
  24.432 }
  24.433 
  24.434 
  24.435 
  24.436 String& String::Insert(const char* substr, UPInt posAt, SPInt strSize)
  24.437 {
  24.438     DataDesc* poldData   = GetData();
  24.439     UPInt     oldSize    = poldData->GetSize();
  24.440     UPInt     insertSize = (strSize < 0) ? OVR_strlen(substr) : (UPInt)strSize;    
  24.441     UPInt     byteIndex  =  (poldData->LengthIsSize()) ?
  24.442                             posAt : (UPInt)UTF8Util::GetByteIndex(posAt, poldData->Data, oldSize);
  24.443 
  24.444     OVR_ASSERT(byteIndex <= oldSize);
  24.445     
  24.446     DataDesc* pnewData = AllocDataCopy2(oldSize + insertSize, 0,
  24.447                                         poldData->Data, byteIndex, substr, insertSize);
  24.448     memcpy(pnewData->Data + byteIndex + insertSize,
  24.449            poldData->Data + byteIndex, oldSize - byteIndex);
  24.450     SetData(pnewData);
  24.451     poldData->Release();
  24.452     return *this;
  24.453 }
  24.454 
  24.455 /*
  24.456 String& String::Insert(const UInt32* substr, UPInt posAt, SPInt len)
  24.457 {
  24.458     for (SPInt i = 0; i < len; ++i)
  24.459     {
  24.460         UPInt charw = InsertCharAt(substr[i], posAt);
  24.461         posAt += charw;
  24.462     }
  24.463     return *this;
  24.464 }
  24.465 */
  24.466 
  24.467 UPInt String::InsertCharAt(UInt32 c, UPInt posAt)
  24.468 {
  24.469     char    buf[8];
  24.470     SPInt   index = 0;
  24.471     UTF8Util::EncodeChar(buf, &index, c);
  24.472     OVR_ASSERT(index >= 0);
  24.473     buf[(UPInt)index] = 0;
  24.474 
  24.475     Insert(buf, posAt, index);
  24.476     return (UPInt)index;
  24.477 }
  24.478 
  24.479 
  24.480 int String::CompareNoCase(const char* a, const char* b)
  24.481 {
  24.482     return OVR_stricmp(a, b);
  24.483 }
  24.484 
  24.485 int String::CompareNoCase(const char* a, const char* b, SPInt len)
  24.486 {
  24.487     if (len)
  24.488     {
  24.489         SPInt f,l;
  24.490         SPInt slen = len;
  24.491         const char *s = b;
  24.492         do {
  24.493             f = (SPInt)OVR_tolower((int)(*(a++)));
  24.494             l = (SPInt)OVR_tolower((int)(*(b++)));
  24.495         } while (--len && f && (f == l) && *b != 0);
  24.496 
  24.497         if (f == l && (len != 0 || *b != 0))
  24.498         {
  24.499             f = (SPInt)slen;
  24.500             l = (SPInt)OVR_strlen(s);
  24.501             return int(f - l);
  24.502         }
  24.503 
  24.504         return int(f - l);
  24.505     }
  24.506     else
  24.507         return (0-(int)OVR_strlen(b));
  24.508 }
  24.509 
  24.510 // ***** Implement hash static functions
  24.511 
  24.512 // Hash function
  24.513 UPInt String::BernsteinHashFunction(const void* pdataIn, UPInt size, UPInt seed)
  24.514 {
  24.515     const UByte*    pdata   = (const UByte*) pdataIn;
  24.516     UPInt           h       = seed;
  24.517     while (size > 0)
  24.518     {
  24.519         size--;
  24.520         h = ((h << 5) + h) ^ (unsigned) pdata[size];
  24.521     }
  24.522 
  24.523     return h;
  24.524 }
  24.525 
  24.526 // Hash function, case-insensitive
  24.527 UPInt String::BernsteinHashFunctionCIS(const void* pdataIn, UPInt size, UPInt seed)
  24.528 {
  24.529     const UByte*    pdata = (const UByte*) pdataIn;
  24.530     UPInt           h = seed;
  24.531     while (size > 0)
  24.532     {
  24.533         size--;
  24.534         h = ((h << 5) + h) ^ OVR_tolower(pdata[size]);
  24.535     }
  24.536 
  24.537     // Alternative: "sdbm" hash function, suggested at same web page above.
  24.538     // h = 0;
  24.539     // for bytes { h = (h << 16) + (h << 6) - hash + *p; }
  24.540     return h;
  24.541 }
  24.542 
  24.543 
  24.544 
  24.545 // ***** String Buffer used for Building Strings
  24.546 
  24.547 
  24.548 #define OVR_SBUFF_DEFAULT_GROW_SIZE 512
  24.549 // Constructors / Destructor.
  24.550 StringBuffer::StringBuffer()
  24.551     : pData(NULL), Size(0), BufferSize(0), GrowSize(OVR_SBUFF_DEFAULT_GROW_SIZE), LengthIsSize(false)
  24.552 {
  24.553 }
  24.554 
  24.555 StringBuffer::StringBuffer(UPInt growSize)
  24.556     : pData(NULL), Size(0), BufferSize(0), GrowSize(OVR_SBUFF_DEFAULT_GROW_SIZE), LengthIsSize(false)
  24.557 {
  24.558     SetGrowSize(growSize);
  24.559 }
  24.560 
  24.561 StringBuffer::StringBuffer(const char* data)
  24.562     : pData(NULL), Size(0), BufferSize(0), GrowSize(OVR_SBUFF_DEFAULT_GROW_SIZE), LengthIsSize(false)
  24.563 {
  24.564     *this = data;
  24.565 }
  24.566 
  24.567 StringBuffer::StringBuffer(const char* data, UPInt dataSize)
  24.568     : pData(NULL), Size(0), BufferSize(0), GrowSize(OVR_SBUFF_DEFAULT_GROW_SIZE), LengthIsSize(false)
  24.569 {
  24.570     AppendString(data, dataSize);
  24.571 }
  24.572 
  24.573 StringBuffer::StringBuffer(const String& src)
  24.574     : pData(NULL), Size(0), BufferSize(0), GrowSize(OVR_SBUFF_DEFAULT_GROW_SIZE), LengthIsSize(false)
  24.575 {
  24.576     AppendString(src.ToCStr(), src.GetSize());
  24.577 }
  24.578 
  24.579 StringBuffer::StringBuffer(const StringBuffer& src)
  24.580     : pData(NULL), Size(0), BufferSize(src.GetGrowSize()), GrowSize(OVR_SBUFF_DEFAULT_GROW_SIZE), LengthIsSize(false)
  24.581 {
  24.582     AppendString(src.ToCStr(), src.GetSize());
  24.583     LengthIsSize = src.LengthIsSize;
  24.584 }
  24.585 
  24.586 StringBuffer::StringBuffer(const wchar_t* data)
  24.587     : pData(NULL), Size(0), BufferSize(0), GrowSize(OVR_SBUFF_DEFAULT_GROW_SIZE), LengthIsSize(false)
  24.588 {
  24.589     *this = data;
  24.590 }
  24.591 
  24.592 StringBuffer::~StringBuffer()
  24.593 {
  24.594     if (pData)
  24.595         OVR_FREE(pData);
  24.596 }
  24.597 void StringBuffer::SetGrowSize(UPInt growSize) 
  24.598 { 
  24.599     if (growSize <= 16)
  24.600         GrowSize = 16;
  24.601     else
  24.602     {
  24.603         UByte bits = Alg::UpperBit(UInt32(growSize-1));
  24.604         UPInt size = 1<<bits;
  24.605         GrowSize = size == growSize ? growSize : size;
  24.606     }
  24.607 }
  24.608 
  24.609 UPInt StringBuffer::GetLength() const
  24.610 {
  24.611     UPInt length, size = GetSize();
  24.612     if (LengthIsSize)
  24.613         return size;
  24.614 
  24.615     length = (UPInt)UTF8Util::GetLength(pData, (UPInt)GetSize());
  24.616 
  24.617     if (length == GetSize())
  24.618         LengthIsSize = true;
  24.619     return length;
  24.620 }
  24.621 
  24.622 void    StringBuffer::Reserve(UPInt _size)
  24.623 {
  24.624     if (_size >= BufferSize) // >= because of trailing zero! (!AB)
  24.625     {
  24.626         BufferSize = (_size + 1 + GrowSize - 1)& ~(GrowSize-1);
  24.627         if (!pData)
  24.628             pData = (char*)OVR_ALLOC(BufferSize);
  24.629         else 
  24.630             pData = (char*)OVR_REALLOC(pData, BufferSize);
  24.631     }
  24.632 }
  24.633 void    StringBuffer::Resize(UPInt _size)
  24.634 {
  24.635     Reserve(_size);
  24.636     LengthIsSize = false;
  24.637     Size = _size;
  24.638     if (pData)
  24.639         pData[Size] = 0;
  24.640 }
  24.641 
  24.642 void StringBuffer::Clear()
  24.643 {
  24.644     Resize(0);
  24.645     /*
  24.646     if (pData != pEmptyNullData)
  24.647     {
  24.648         OVR_FREE(pHeap, pData);
  24.649         pData = pEmptyNullData;
  24.650         Size = BufferSize = 0;
  24.651         LengthIsSize = false;
  24.652     }
  24.653     */
  24.654 }
  24.655 // Appends a character
  24.656 void     StringBuffer::AppendChar(UInt32 ch)
  24.657 {
  24.658     char    buff[8];
  24.659     UPInt   origSize = GetSize();
  24.660 
  24.661     // Converts ch into UTF8 string and fills it into buff. Also increments index according to the number of bytes
  24.662     // in the UTF8 string.
  24.663     SPInt   srcSize = 0;
  24.664     UTF8Util::EncodeChar(buff, &srcSize, ch);
  24.665     OVR_ASSERT(srcSize >= 0);
  24.666     
  24.667     UPInt size = origSize + srcSize;
  24.668     Resize(size);
  24.669     memcpy(pData + origSize, buff, srcSize);
  24.670 }
  24.671 
  24.672 // Append a string
  24.673 void     StringBuffer::AppendString(const wchar_t* pstr, SPInt len)
  24.674 {
  24.675     if (!pstr)
  24.676         return;
  24.677 
  24.678     SPInt   srcSize     = UTF8Util::GetEncodeStringSize(pstr, len);
  24.679     UPInt   origSize    = GetSize();
  24.680     UPInt   size        = srcSize + origSize;
  24.681 
  24.682     Resize(size);
  24.683     UTF8Util::EncodeString(pData + origSize,  pstr, len);
  24.684 }
  24.685 
  24.686 void      StringBuffer::AppendString(const char* putf8str, SPInt utf8StrSz)
  24.687 {
  24.688     if (!putf8str || !utf8StrSz)
  24.689         return;
  24.690     if (utf8StrSz == -1)
  24.691         utf8StrSz = (SPInt)OVR_strlen(putf8str);
  24.692 
  24.693     UPInt   origSize    = GetSize();
  24.694     UPInt   size        = utf8StrSz + origSize;
  24.695 
  24.696     Resize(size);
  24.697     memcpy(pData + origSize, putf8str, utf8StrSz);
  24.698 }
  24.699 
  24.700 
  24.701 void      StringBuffer::operator = (const char* pstr)
  24.702 {
  24.703     pstr = pstr ? pstr : "";
  24.704     UPInt size = OVR_strlen(pstr);
  24.705     Resize(size);
  24.706     memcpy(pData, pstr, size);
  24.707 }
  24.708 
  24.709 void      StringBuffer::operator = (const wchar_t* pstr)
  24.710 {
  24.711     pstr = pstr ? pstr : L"";
  24.712     UPInt size = (UPInt)UTF8Util::GetEncodeStringSize(pstr);
  24.713     Resize(size);
  24.714     UTF8Util::EncodeString(pData, pstr);
  24.715 }
  24.716 
  24.717 void      StringBuffer::operator = (const String& src)
  24.718 {
  24.719     Resize(src.GetSize());
  24.720     memcpy(pData, src.ToCStr(), src.GetSize());
  24.721 }
  24.722 
  24.723 
  24.724 // Inserts substr at posAt
  24.725 void      StringBuffer::Insert(const char* substr, UPInt posAt, SPInt len)
  24.726 {
  24.727     UPInt     oldSize    = Size;
  24.728     UPInt     insertSize = (len < 0) ? OVR_strlen(substr) : (UPInt)len;    
  24.729     UPInt     byteIndex  = LengthIsSize ? posAt : 
  24.730                            (UPInt)UTF8Util::GetByteIndex(posAt, pData, (SPInt)Size);
  24.731 
  24.732     OVR_ASSERT(byteIndex <= oldSize);
  24.733     Reserve(oldSize + insertSize);
  24.734 
  24.735     memmove(pData + byteIndex + insertSize, pData + byteIndex, oldSize - byteIndex + 1);
  24.736     memcpy (pData + byteIndex, substr, insertSize);
  24.737     LengthIsSize = false;
  24.738     Size = oldSize + insertSize;
  24.739     pData[Size] = 0;
  24.740 }
  24.741 
  24.742 // Inserts character at posAt
  24.743 UPInt     StringBuffer::InsertCharAt(UInt32 c, UPInt posAt)
  24.744 {
  24.745     char    buf[8];
  24.746     SPInt   len = 0;
  24.747     UTF8Util::EncodeChar(buf, &len, c);
  24.748     OVR_ASSERT(len >= 0);
  24.749     buf[(UPInt)len] = 0;
  24.750 
  24.751     Insert(buf, posAt, len);
  24.752     return (UPInt)len;
  24.753 }
  24.754 
  24.755 } // OVR
  24.756 \ No newline at end of file
  24.757 +/************************************************************************************
  24.758 +
  24.759 +Filename    :   OVR_String.cpp
  24.760 +Content     :   String UTF8 string implementation with copy-on-write semantics
  24.761 +                (thread-safe for assignment but not modification).
  24.762 +Created     :   September 19, 2012
  24.763 +Notes       : 
  24.764 +
  24.765 +Copyright   :   Copyright 2012 Oculus VR, Inc. All Rights reserved.
  24.766 +
  24.767 +Use of this software is subject to the terms of the Oculus license
  24.768 +agreement provided at the time of installation or download, or which
  24.769 +otherwise accompanies this software in either electronic or hard copy form.
  24.770 +
  24.771 +************************************************************************************/
  24.772 +
  24.773 +#include "OVR_String.h"
  24.774 +
  24.775 +#include <stdlib.h>
  24.776 +#include <ctype.h>
  24.777 +
  24.778 +#ifdef OVR_OS_QNX
  24.779 +# include <strings.h>
  24.780 +#endif
  24.781 +
  24.782 +namespace OVR {
  24.783 +
  24.784 +#define String_LengthIsSize (UPInt(1) << String::Flag_LengthIsSizeShift)
  24.785 +
  24.786 +String::DataDesc String::NullData = {String_LengthIsSize, 1, {0} };
  24.787 +
  24.788 +
  24.789 +String::String()
  24.790 +{
  24.791 +    pData = &NullData;
  24.792 +    pData->AddRef();
  24.793 +};
  24.794 +
  24.795 +String::String(const char* pdata)
  24.796 +{
  24.797 +    // Obtain length in bytes; it doesn't matter if _data is UTF8.
  24.798 +    UPInt size = pdata ? OVR_strlen(pdata) : 0; 
  24.799 +    pData = AllocDataCopy1(size, 0, pdata, size);
  24.800 +};
  24.801 +
  24.802 +String::String(const char* pdata1, const char* pdata2, const char* pdata3)
  24.803 +{
  24.804 +    // Obtain length in bytes; it doesn't matter if _data is UTF8.
  24.805 +    UPInt size1 = pdata1 ? OVR_strlen(pdata1) : 0; 
  24.806 +    UPInt size2 = pdata2 ? OVR_strlen(pdata2) : 0; 
  24.807 +    UPInt size3 = pdata3 ? OVR_strlen(pdata3) : 0; 
  24.808 +
  24.809 +    DataDesc *pdataDesc = AllocDataCopy2(size1 + size2 + size3, 0,
  24.810 +                                         pdata1, size1, pdata2, size2);
  24.811 +    memcpy(pdataDesc->Data + size1 + size2, pdata3, size3);   
  24.812 +    pData = pdataDesc;    
  24.813 +}
  24.814 +
  24.815 +String::String(const char* pdata, UPInt size)
  24.816 +{
  24.817 +    OVR_ASSERT((size == 0) || (pdata != 0));
  24.818 +    pData = AllocDataCopy1(size, 0, pdata, size);
  24.819 +};
  24.820 +
  24.821 +
  24.822 +String::String(const InitStruct& src, UPInt size)
  24.823 +{
  24.824 +    pData = AllocData(size, 0);
  24.825 +    src.InitString(GetData()->Data, size);
  24.826 +}
  24.827 +
  24.828 +String::String(const String& src)
  24.829 +{    
  24.830 +    pData = src.GetData();
  24.831 +    pData->AddRef();
  24.832 +}
  24.833 +
  24.834 +String::String(const StringBuffer& src)
  24.835 +{
  24.836 +    pData = AllocDataCopy1(src.GetSize(), 0, src.ToCStr(), src.GetSize());
  24.837 +}
  24.838 +
  24.839 +String::String(const wchar_t* data)
  24.840 +{
  24.841 +    pData = &NullData;
  24.842 +    pData->AddRef();
  24.843 +    // Simplified logic for wchar_t constructor.
  24.844 +    if (data)    
  24.845 +        *this = data;    
  24.846 +}
  24.847 +
  24.848 +
  24.849 +String::DataDesc* String::AllocData(UPInt size, UPInt lengthIsSize)
  24.850 +{
  24.851 +    String::DataDesc* pdesc;
  24.852 +
  24.853 +    if (size == 0)
  24.854 +    {
  24.855 +        pdesc = &NullData;
  24.856 +        pdesc->AddRef();
  24.857 +        return pdesc;
  24.858 +    }
  24.859 +
  24.860 +    pdesc = (DataDesc*)OVR_ALLOC(sizeof(DataDesc)+ size);
  24.861 +    pdesc->Data[size] = 0;
  24.862 +    pdesc->RefCount = 1;
  24.863 +    pdesc->Size     = size | lengthIsSize;  
  24.864 +    return pdesc;
  24.865 +}
  24.866 +
  24.867 +
  24.868 +String::DataDesc* String::AllocDataCopy1(UPInt size, UPInt lengthIsSize,
  24.869 +                                         const char* pdata, UPInt copySize)
  24.870 +{
  24.871 +    String::DataDesc* pdesc = AllocData(size, lengthIsSize);
  24.872 +    memcpy(pdesc->Data, pdata, copySize);
  24.873 +    return pdesc;
  24.874 +}
  24.875 +
  24.876 +String::DataDesc* String::AllocDataCopy2(UPInt size, UPInt lengthIsSize,
  24.877 +                                         const char* pdata1, UPInt copySize1,
  24.878 +                                         const char* pdata2, UPInt copySize2)
  24.879 +{
  24.880 +    String::DataDesc* pdesc = AllocData(size, lengthIsSize);
  24.881 +    memcpy(pdesc->Data, pdata1, copySize1);
  24.882 +    memcpy(pdesc->Data + copySize1, pdata2, copySize2);
  24.883 +    return pdesc;
  24.884 +}
  24.885 +
  24.886 +
  24.887 +UPInt String::GetLength() const 
  24.888 +{
  24.889 +    // Optimize length accesses for non-UTF8 character strings. 
  24.890 +    DataDesc* pdata = GetData();
  24.891 +    UPInt     length, size = pdata->GetSize();
  24.892 +    
  24.893 +    if (pdata->LengthIsSize())
  24.894 +        return size;    
  24.895 +    
  24.896 +    length = (UPInt)UTF8Util::GetLength(pdata->Data, (UPInt)size);
  24.897 +    
  24.898 +    if (length == size)
  24.899 +        pdata->Size |= String_LengthIsSize;
  24.900 +    
  24.901 +    return length;
  24.902 +}
  24.903 +
  24.904 +
  24.905 +//static UInt32 String_CharSearch(const char* buf, )
  24.906 +
  24.907 +
  24.908 +UInt32 String::GetCharAt(UPInt index) const 
  24.909 +{  
  24.910 +    SPInt       i = (SPInt) index;
  24.911 +    DataDesc*   pdata = GetData();
  24.912 +    const char* buf = pdata->Data;
  24.913 +    UInt32      c;
  24.914 +    
  24.915 +    if (pdata->LengthIsSize())
  24.916 +    {
  24.917 +        OVR_ASSERT(index < pdata->GetSize());
  24.918 +        buf += i;
  24.919 +        return UTF8Util::DecodeNextChar_Advance0(&buf);
  24.920 +    }
  24.921 +
  24.922 +    c = UTF8Util::GetCharAt(index, buf, pdata->GetSize());
  24.923 +    return c;
  24.924 +}
  24.925 +
  24.926 +UInt32 String::GetFirstCharAt(UPInt index, const char** offset) const
  24.927 +{
  24.928 +    DataDesc*   pdata = GetData();
  24.929 +    SPInt       i = (SPInt) index;
  24.930 +    const char* buf = pdata->Data;
  24.931 +    const char* end = buf + pdata->GetSize();
  24.932 +    UInt32      c;
  24.933 +
  24.934 +    do 
  24.935 +    {
  24.936 +        c = UTF8Util::DecodeNextChar_Advance0(&buf);
  24.937 +        i--;
  24.938 +
  24.939 +        if (buf >= end)
  24.940 +        {
  24.941 +            // We've hit the end of the string; don't go further.
  24.942 +            OVR_ASSERT(i == 0);
  24.943 +            return c;
  24.944 +        }
  24.945 +    } while (i >= 0);
  24.946 +
  24.947 +    *offset = buf;
  24.948 +
  24.949 +    return c;
  24.950 +}
  24.951 +
  24.952 +UInt32 String::GetNextChar(const char** offset) const
  24.953 +{
  24.954 +    return UTF8Util::DecodeNextChar(offset);
  24.955 +}
  24.956 +
  24.957 +
  24.958 +
  24.959 +void String::AppendChar(UInt32 ch)
  24.960 +{
  24.961 +    DataDesc*   pdata = GetData();
  24.962 +    UPInt       size = pdata->GetSize();
  24.963 +    char        buff[8];
  24.964 +    SPInt       encodeSize = 0;
  24.965 +
  24.966 +    // Converts ch into UTF8 string and fills it into buff.   
  24.967 +    UTF8Util::EncodeChar(buff, &encodeSize, ch);
  24.968 +    OVR_ASSERT(encodeSize >= 0);
  24.969 +
  24.970 +    SetData(AllocDataCopy2(size + (UPInt)encodeSize, 0,
  24.971 +                           pdata->Data, size, buff, (UPInt)encodeSize));
  24.972 +    pdata->Release();
  24.973 +}
  24.974 +
  24.975 +
  24.976 +void String::AppendString(const wchar_t* pstr, SPInt len)
  24.977 +{
  24.978 +    if (!pstr)
  24.979 +        return;
  24.980 +
  24.981 +    DataDesc*   pdata = GetData();
  24.982 +    UPInt       oldSize = pdata->GetSize();    
  24.983 +    UPInt       encodeSize = (UPInt)UTF8Util::GetEncodeStringSize(pstr, len);
  24.984 +
  24.985 +    DataDesc*   pnewData = AllocDataCopy1(oldSize + (UPInt)encodeSize, 0,
  24.986 +                                          pdata->Data, oldSize);
  24.987 +    UTF8Util::EncodeString(pnewData->Data + oldSize,  pstr, len);
  24.988 +
  24.989 +    SetData(pnewData);
  24.990 +    pdata->Release();
  24.991 +}
  24.992 +
  24.993 +
  24.994 +void String::AppendString(const char* putf8str, SPInt utf8StrSz)
  24.995 +{
  24.996 +    if (!putf8str || !utf8StrSz)
  24.997 +        return;
  24.998 +    if (utf8StrSz == -1)
  24.999 +        utf8StrSz = (SPInt)OVR_strlen(putf8str);
 24.1000 +
 24.1001 +    DataDesc*   pdata = GetData();
 24.1002 +    UPInt       oldSize = pdata->GetSize();
 24.1003 +
 24.1004 +    SetData(AllocDataCopy2(oldSize + (UPInt)utf8StrSz, 0,
 24.1005 +                           pdata->Data, oldSize, putf8str, (UPInt)utf8StrSz));
 24.1006 +    pdata->Release();
 24.1007 +}
 24.1008 +
 24.1009 +void    String::AssignString(const InitStruct& src, UPInt size)
 24.1010 +{
 24.1011 +    DataDesc*   poldData = GetData();
 24.1012 +    DataDesc*   pnewData = AllocData(size, 0);
 24.1013 +    src.InitString(pnewData->Data, size);
 24.1014 +    SetData(pnewData);
 24.1015 +    poldData->Release();
 24.1016 +}
 24.1017 +
 24.1018 +void    String::AssignString(const char* putf8str, UPInt size)
 24.1019 +{
 24.1020 +    DataDesc* poldData = GetData();
 24.1021 +    SetData(AllocDataCopy1(size, 0, putf8str, size));
 24.1022 +    poldData->Release();
 24.1023 +}
 24.1024 +
 24.1025 +void    String::operator = (const char* pstr)
 24.1026 +{
 24.1027 +    AssignString(pstr, pstr ? OVR_strlen(pstr) : 0);
 24.1028 +}
 24.1029 +
 24.1030 +void    String::operator = (const wchar_t* pwstr)
 24.1031 +{
 24.1032 +    DataDesc*   poldData = GetData();
 24.1033 +    UPInt       size = pwstr ? (UPInt)UTF8Util::GetEncodeStringSize(pwstr) : 0;
 24.1034 +
 24.1035 +    DataDesc*   pnewData = AllocData(size, 0);
 24.1036 +    UTF8Util::EncodeString(pnewData->Data, pwstr);
 24.1037 +    SetData(pnewData);
 24.1038 +    poldData->Release();
 24.1039 +}
 24.1040 +
 24.1041 +
 24.1042 +void    String::operator = (const String& src)
 24.1043 +{     
 24.1044 +    DataDesc*    psdata = src.GetData();
 24.1045 +    DataDesc*    pdata = GetData();    
 24.1046 +
 24.1047 +    SetData(psdata);
 24.1048 +    psdata->AddRef();
 24.1049 +    pdata->Release();
 24.1050 +}
 24.1051 +
 24.1052 +
 24.1053 +void    String::operator = (const StringBuffer& src)
 24.1054 +{ 
 24.1055 +    DataDesc* polddata = GetData();    
 24.1056 +    SetData(AllocDataCopy1(src.GetSize(), 0, src.ToCStr(), src.GetSize()));
 24.1057 +    polddata->Release();
 24.1058 +}
 24.1059 +
 24.1060 +void    String::operator += (const String& src)
 24.1061 +{
 24.1062 +    DataDesc   *pourData = GetData(),
 24.1063 +               *psrcData = src.GetData();
 24.1064 +    UPInt       ourSize  = pourData->GetSize(),
 24.1065 +                srcSize  = psrcData->GetSize();
 24.1066 +    UPInt       lflag    = pourData->GetLengthFlag() & psrcData->GetLengthFlag();
 24.1067 +
 24.1068 +    SetData(AllocDataCopy2(ourSize + srcSize, lflag,
 24.1069 +                           pourData->Data, ourSize, psrcData->Data, srcSize));
 24.1070 +    pourData->Release();
 24.1071 +}
 24.1072 +
 24.1073 +
 24.1074 +String   String::operator + (const char* str) const
 24.1075 +{   
 24.1076 +    String tmp1(*this);
 24.1077 +    tmp1 += (str ? str : "");
 24.1078 +    return tmp1;
 24.1079 +}
 24.1080 +
 24.1081 +String   String::operator + (const String& src) const
 24.1082 +{ 
 24.1083 +    String tmp1(*this);
 24.1084 +    tmp1 += src;
 24.1085 +    return tmp1;
 24.1086 +}
 24.1087 +
 24.1088 +void    String::Remove(UPInt posAt, SPInt removeLength)
 24.1089 +{
 24.1090 +    DataDesc*   pdata = GetData();
 24.1091 +    UPInt       oldSize = pdata->GetSize();    
 24.1092 +    // Length indicates the number of characters to remove. 
 24.1093 +    UPInt       length = GetLength();
 24.1094 +
 24.1095 +    // If index is past the string, nothing to remove.
 24.1096 +    if (posAt >= length)
 24.1097 +        return;
 24.1098 +    // Otherwise, cap removeLength to the length of the string.
 24.1099 +    if ((posAt + removeLength) > length)
 24.1100 +        removeLength = length - posAt;
 24.1101 +
 24.1102 +    // Get the byte position of the UTF8 char at position posAt.
 24.1103 +    SPInt bytePos    = UTF8Util::GetByteIndex(posAt, pdata->Data, oldSize);
 24.1104 +    SPInt removeSize = UTF8Util::GetByteIndex(removeLength, pdata->Data + bytePos, oldSize-bytePos);
 24.1105 +
 24.1106 +    SetData(AllocDataCopy2(oldSize - removeSize, pdata->GetLengthFlag(),
 24.1107 +                           pdata->Data, bytePos,
 24.1108 +                           pData->Data + bytePos + removeSize, (oldSize - bytePos - removeSize)));
 24.1109 +    pdata->Release();
 24.1110 +}
 24.1111 +
 24.1112 +
 24.1113 +String   String::Substring(UPInt start, UPInt end) const
 24.1114 +{
 24.1115 +    UPInt length = GetLength();
 24.1116 +    if ((start >= length) || (start >= end))
 24.1117 +        return String();   
 24.1118 +
 24.1119 +    DataDesc* pdata = GetData();
 24.1120 +    
 24.1121 +    // If size matches, we know the exact index range.
 24.1122 +    if (pdata->LengthIsSize())
 24.1123 +        return String(pdata->Data + start, end - start);
 24.1124 +    
 24.1125 +    // Get position of starting character.
 24.1126 +    SPInt byteStart = UTF8Util::GetByteIndex(start, pdata->Data, pdata->GetSize());
 24.1127 +    SPInt byteSize  = UTF8Util::GetByteIndex(end - start, pdata->Data + byteStart, pdata->GetSize()-byteStart);
 24.1128 +    return String(pdata->Data + byteStart, (UPInt)byteSize);
 24.1129 +}
 24.1130 +
 24.1131 +void String::Clear()
 24.1132 +{   
 24.1133 +    NullData.AddRef();
 24.1134 +    GetData()->Release();
 24.1135 +    SetData(&NullData);
 24.1136 +}
 24.1137 +
 24.1138 +
 24.1139 +String   String::ToUpper() const 
 24.1140 +{       
 24.1141 +    UInt32      c;
 24.1142 +    const char* psource = GetData()->Data;
 24.1143 +    const char* pend = psource + GetData()->GetSize();
 24.1144 +    String      str;
 24.1145 +    SPInt       bufferOffset = 0;
 24.1146 +    char        buffer[512];
 24.1147 +    
 24.1148 +    while(psource < pend)
 24.1149 +    {
 24.1150 +        do {            
 24.1151 +            c = UTF8Util::DecodeNextChar_Advance0(&psource);
 24.1152 +            UTF8Util::EncodeChar(buffer, &bufferOffset, OVR_towupper(wchar_t(c)));
 24.1153 +        } while ((psource < pend) && (bufferOffset < SPInt(sizeof(buffer)-8)));
 24.1154 +
 24.1155 +        // Append string a piece at a time.
 24.1156 +        str.AppendString(buffer, bufferOffset);
 24.1157 +        bufferOffset = 0;
 24.1158 +    }
 24.1159 +
 24.1160 +    return str;
 24.1161 +}
 24.1162 +
 24.1163 +String   String::ToLower() const 
 24.1164 +{
 24.1165 +    UInt32      c;
 24.1166 +    const char* psource = GetData()->Data;
 24.1167 +    const char* pend = psource + GetData()->GetSize();
 24.1168 +    String      str;
 24.1169 +    SPInt       bufferOffset = 0;
 24.1170 +    char        buffer[512];
 24.1171 +
 24.1172 +    while(psource < pend)
 24.1173 +    {
 24.1174 +        do {
 24.1175 +            c = UTF8Util::DecodeNextChar_Advance0(&psource);
 24.1176 +            UTF8Util::EncodeChar(buffer, &bufferOffset, OVR_towlower(wchar_t(c)));
 24.1177 +        } while ((psource < pend) && (bufferOffset < SPInt(sizeof(buffer)-8)));
 24.1178 +
 24.1179 +        // Append string a piece at a time.
 24.1180 +        str.AppendString(buffer, bufferOffset);
 24.1181 +        bufferOffset = 0;
 24.1182 +    }
 24.1183 +
 24.1184 +    return str;
 24.1185 +}
 24.1186 +
 24.1187 +
 24.1188 +
 24.1189 +String& String::Insert(const char* substr, UPInt posAt, SPInt strSize)
 24.1190 +{
 24.1191 +    DataDesc* poldData   = GetData();
 24.1192 +    UPInt     oldSize    = poldData->GetSize();
 24.1193 +    UPInt     insertSize = (strSize < 0) ? OVR_strlen(substr) : (UPInt)strSize;    
 24.1194 +    UPInt     byteIndex  =  (poldData->LengthIsSize()) ?
 24.1195 +                            posAt : (UPInt)UTF8Util::GetByteIndex(posAt, poldData->Data, oldSize);
 24.1196 +
 24.1197 +    OVR_ASSERT(byteIndex <= oldSize);
 24.1198 +    
 24.1199 +    DataDesc* pnewData = AllocDataCopy2(oldSize + insertSize, 0,
 24.1200 +                                        poldData->Data, byteIndex, substr, insertSize);
 24.1201 +    memcpy(pnewData->Data + byteIndex + insertSize,
 24.1202 +           poldData->Data + byteIndex, oldSize - byteIndex);
 24.1203 +    SetData(pnewData);
 24.1204 +    poldData->Release();
 24.1205 +    return *this;
 24.1206 +}
 24.1207 +
 24.1208 +/*
 24.1209 +String& String::Insert(const UInt32* substr, UPInt posAt, SPInt len)
 24.1210 +{
 24.1211 +    for (SPInt i = 0; i < len; ++i)
 24.1212 +    {
 24.1213 +        UPInt charw = InsertCharAt(substr[i], posAt);
 24.1214 +        posAt += charw;
 24.1215 +    }
 24.1216 +    return *this;
 24.1217 +}
 24.1218 +*/
 24.1219 +
 24.1220 +UPInt String::InsertCharAt(UInt32 c, UPInt posAt)
 24.1221 +{
 24.1222 +    char    buf[8];
 24.1223 +    SPInt   index = 0;
 24.1224 +    UTF8Util::EncodeChar(buf, &index, c);
 24.1225 +    OVR_ASSERT(index >= 0);
 24.1226 +    buf[(UPInt)index] = 0;
 24.1227 +
 24.1228 +    Insert(buf, posAt, index);
 24.1229 +    return (UPInt)index;
 24.1230 +}
 24.1231 +
 24.1232 +
 24.1233 +int String::CompareNoCase(const char* a, const char* b)
 24.1234 +{
 24.1235 +    return OVR_stricmp(a, b);
 24.1236 +}
 24.1237 +
 24.1238 +int String::CompareNoCase(const char* a, const char* b, SPInt len)
 24.1239 +{
 24.1240 +    if (len)
 24.1241 +    {
 24.1242 +        SPInt f,l;
 24.1243 +        SPInt slen = len;
 24.1244 +        const char *s = b;
 24.1245 +        do {
 24.1246 +            f = (SPInt)OVR_tolower((int)(*(a++)));
 24.1247 +            l = (SPInt)OVR_tolower((int)(*(b++)));
 24.1248 +        } while (--len && f && (f == l) && *b != 0);
 24.1249 +
 24.1250 +        if (f == l && (len != 0 || *b != 0))
 24.1251 +        {
 24.1252 +            f = (SPInt)slen;
 24.1253 +            l = (SPInt)OVR_strlen(s);
 24.1254 +            return int(f - l);
 24.1255 +        }
 24.1256 +
 24.1257 +        return int(f - l);
 24.1258 +    }
 24.1259 +    else
 24.1260 +        return (0-(int)OVR_strlen(b));
 24.1261 +}
 24.1262 +
 24.1263 +// ***** Implement hash static functions
 24.1264 +
 24.1265 +// Hash function
 24.1266 +UPInt String::BernsteinHashFunction(const void* pdataIn, UPInt size, UPInt seed)
 24.1267 +{
 24.1268 +    const UByte*    pdata   = (const UByte*) pdataIn;
 24.1269 +    UPInt           h       = seed;
 24.1270 +    while (size > 0)
 24.1271 +    {
 24.1272 +        size--;
 24.1273 +        h = ((h << 5) + h) ^ (unsigned) pdata[size];
 24.1274 +    }
 24.1275 +
 24.1276 +    return h;
 24.1277 +}
 24.1278 +
 24.1279 +// Hash function, case-insensitive
 24.1280 +UPInt String::BernsteinHashFunctionCIS(const void* pdataIn, UPInt size, UPInt seed)
 24.1281 +{
 24.1282 +    const UByte*    pdata = (const UByte*) pdataIn;
 24.1283 +    UPInt           h = seed;
 24.1284 +    while (size > 0)
 24.1285 +    {
 24.1286 +        size--;
 24.1287 +        h = ((h << 5) + h) ^ OVR_tolower(pdata[size]);
 24.1288 +    }
 24.1289 +
 24.1290 +    // Alternative: "sdbm" hash function, suggested at same web page above.
 24.1291 +    // h = 0;
 24.1292 +    // for bytes { h = (h << 16) + (h << 6) - hash + *p; }
 24.1293 +    return h;
 24.1294 +}
 24.1295 +
 24.1296 +
 24.1297 +
 24.1298 +// ***** String Buffer used for Building Strings
 24.1299 +
 24.1300 +
 24.1301 +#define OVR_SBUFF_DEFAULT_GROW_SIZE 512
 24.1302 +// Constructors / Destructor.
 24.1303 +StringBuffer::StringBuffer()
 24.1304 +    : pData(NULL), Size(0), BufferSize(0), GrowSize(OVR_SBUFF_DEFAULT_GROW_SIZE), LengthIsSize(false)
 24.1305 +{
 24.1306 +}
 24.1307 +
 24.1308 +StringBuffer::StringBuffer(UPInt growSize)
 24.1309 +    : pData(NULL), Size(0), BufferSize(0), GrowSize(OVR_SBUFF_DEFAULT_GROW_SIZE), LengthIsSize(false)
 24.1310 +{
 24.1311 +    SetGrowSize(growSize);
 24.1312 +}
 24.1313 +
 24.1314 +StringBuffer::StringBuffer(const char* data)
 24.1315 +    : pData(NULL), Size(0), BufferSize(0), GrowSize(OVR_SBUFF_DEFAULT_GROW_SIZE), LengthIsSize(false)
 24.1316 +{
 24.1317 +    *this = data;
 24.1318 +}
 24.1319 +
 24.1320 +StringBuffer::StringBuffer(const char* data, UPInt dataSize)
 24.1321 +    : pData(NULL), Size(0), BufferSize(0), GrowSize(OVR_SBUFF_DEFAULT_GROW_SIZE), LengthIsSize(false)
 24.1322 +{
 24.1323 +    AppendString(data, dataSize);
 24.1324 +}
 24.1325 +
 24.1326 +StringBuffer::StringBuffer(const String& src)
 24.1327 +    : pData(NULL), Size(0), BufferSize(0), GrowSize(OVR_SBUFF_DEFAULT_GROW_SIZE), LengthIsSize(false)
 24.1328 +{
 24.1329 +    AppendString(src.ToCStr(), src.GetSize());
 24.1330 +}
 24.1331 +
 24.1332 +StringBuffer::StringBuffer(const StringBuffer& src)
 24.1333 +    : pData(NULL), Size(0), BufferSize(src.GetGrowSize()), GrowSize(OVR_SBUFF_DEFAULT_GROW_SIZE), LengthIsSize(false)
 24.1334 +{
 24.1335 +    AppendString(src.ToCStr(), src.GetSize());
 24.1336 +    LengthIsSize = src.LengthIsSize;
 24.1337 +}
 24.1338 +
 24.1339 +StringBuffer::StringBuffer(const wchar_t* data)
 24.1340 +    : pData(NULL), Size(0), BufferSize(0), GrowSize(OVR_SBUFF_DEFAULT_GROW_SIZE), LengthIsSize(false)
 24.1341 +{
 24.1342 +    *this = data;
 24.1343 +}
 24.1344 +
 24.1345 +StringBuffer::~StringBuffer()
 24.1346 +{
 24.1347 +    if (pData)
 24.1348 +        OVR_FREE(pData);
 24.1349 +}
 24.1350 +void StringBuffer::SetGrowSize(UPInt growSize) 
 24.1351 +{ 
 24.1352 +    if (growSize <= 16)
 24.1353 +        GrowSize = 16;
 24.1354 +    else
 24.1355 +    {
 24.1356 +        UByte bits = Alg::UpperBit(UInt32(growSize-1));
 24.1357 +        UPInt size = 1<<bits;
 24.1358 +        GrowSize = size == growSize ? growSize : size;
 24.1359 +    }
 24.1360 +}
 24.1361 +
 24.1362 +UPInt StringBuffer::GetLength() const
 24.1363 +{
 24.1364 +    UPInt length, size = GetSize();
 24.1365 +    if (LengthIsSize)
 24.1366 +        return size;
 24.1367 +
 24.1368 +    length = (UPInt)UTF8Util::GetLength(pData, (UPInt)GetSize());
 24.1369 +
 24.1370 +    if (length == GetSize())
 24.1371 +        LengthIsSize = true;
 24.1372 +    return length;
 24.1373 +}
 24.1374 +
 24.1375 +void    StringBuffer::Reserve(UPInt _size)
 24.1376 +{
 24.1377 +    if (_size >= BufferSize) // >= because of trailing zero! (!AB)
 24.1378 +    {
 24.1379 +        BufferSize = (_size + 1 + GrowSize - 1)& ~(GrowSize-1);
 24.1380 +        if (!pData)
 24.1381 +            pData = (char*)OVR_ALLOC(BufferSize);
 24.1382 +        else 
 24.1383 +            pData = (char*)OVR_REALLOC(pData, BufferSize);
 24.1384 +    }
 24.1385 +}
 24.1386 +void    StringBuffer::Resize(UPInt _size)
 24.1387 +{
 24.1388 +    Reserve(_size);
 24.1389 +    LengthIsSize = false;
 24.1390 +    Size = _size;
 24.1391 +    if (pData)
 24.1392 +        pData[Size] = 0;
 24.1393 +}
 24.1394 +
 24.1395 +void StringBuffer::Clear()
 24.1396 +{
 24.1397 +    Resize(0);
 24.1398 +    /*
 24.1399 +    if (pData != pEmptyNullData)
 24.1400 +    {
 24.1401 +        OVR_FREE(pHeap, pData);
 24.1402 +        pData = pEmptyNullData;
 24.1403 +        Size = BufferSize = 0;
 24.1404 +        LengthIsSize = false;
 24.1405 +    }
 24.1406 +    */
 24.1407 +}
 24.1408 +// Appends a character
 24.1409 +void     StringBuffer::AppendChar(UInt32 ch)
 24.1410 +{
 24.1411 +    char    buff[8];
 24.1412 +    UPInt   origSize = GetSize();
 24.1413 +
 24.1414 +    // Converts ch into UTF8 string and fills it into buff. Also increments index according to the number of bytes
 24.1415 +    // in the UTF8 string.
 24.1416 +    SPInt   srcSize = 0;
 24.1417 +    UTF8Util::EncodeChar(buff, &srcSize, ch);
 24.1418 +    OVR_ASSERT(srcSize >= 0);
 24.1419 +    
 24.1420 +    UPInt size = origSize + srcSize;
 24.1421 +    Resize(size);
 24.1422 +    memcpy(pData + origSize, buff, srcSize);
 24.1423 +}
 24.1424 +
 24.1425 +// Append a string
 24.1426 +void     StringBuffer::AppendString(const wchar_t* pstr, SPInt len)
 24.1427 +{
 24.1428 +    if (!pstr)
 24.1429 +        return;
 24.1430 +
 24.1431 +    SPInt   srcSize     = UTF8Util::GetEncodeStringSize(pstr, len);
 24.1432 +    UPInt   origSize    = GetSize();
 24.1433 +    UPInt   size        = srcSize + origSize;
 24.1434 +
 24.1435 +    Resize(size);
 24.1436 +    UTF8Util::EncodeString(pData + origSize,  pstr, len);
 24.1437 +}
 24.1438 +
 24.1439 +void      StringBuffer::AppendString(const char* putf8str, SPInt utf8StrSz)
 24.1440 +{
 24.1441 +    if (!putf8str || !utf8StrSz)
 24.1442 +        return;
 24.1443 +    if (utf8StrSz == -1)
 24.1444 +        utf8StrSz = (SPInt)OVR_strlen(putf8str);
 24.1445 +
 24.1446 +    UPInt   origSize    = GetSize();
 24.1447 +    UPInt   size        = utf8StrSz + origSize;
 24.1448 +
 24.1449 +    Resize(size);
 24.1450 +    memcpy(pData + origSize, putf8str, utf8StrSz);
 24.1451 +}
 24.1452 +
 24.1453 +
 24.1454 +void      StringBuffer::operator = (const char* pstr)
 24.1455 +{
 24.1456 +    pstr = pstr ? pstr : "";
 24.1457 +    UPInt size = OVR_strlen(pstr);
 24.1458 +    Resize(size);
 24.1459 +    memcpy(pData, pstr, size);
 24.1460 +}
 24.1461 +
 24.1462 +void      StringBuffer::operator = (const wchar_t* pstr)
 24.1463 +{
 24.1464 +    pstr = pstr ? pstr : L"";
 24.1465 +    UPInt size = (UPInt)UTF8Util::GetEncodeStringSize(pstr);
 24.1466 +    Resize(size);
 24.1467 +    UTF8Util::EncodeString(pData, pstr);
 24.1468 +}
 24.1469 +
 24.1470 +void      StringBuffer::operator = (const String& src)
 24.1471 +{
 24.1472 +    Resize(src.GetSize());
 24.1473 +    memcpy(pData, src.ToCStr(), src.GetSize());
 24.1474 +}
 24.1475 +
 24.1476 +
 24.1477 +// Inserts substr at posAt
 24.1478 +void      StringBuffer::Insert(const char* substr, UPInt posAt, SPInt len)
 24.1479 +{
 24.1480 +    UPInt     oldSize    = Size;
 24.1481 +    UPInt     insertSize = (len < 0) ? OVR_strlen(substr) : (UPInt)len;    
 24.1482 +    UPInt     byteIndex  = LengthIsSize ? posAt : 
 24.1483 +                           (UPInt)UTF8Util::GetByteIndex(posAt, pData, (SPInt)Size);
 24.1484 +
 24.1485 +    OVR_ASSERT(byteIndex <= oldSize);
 24.1486 +    Reserve(oldSize + insertSize);
 24.1487 +
 24.1488 +    memmove(pData + byteIndex + insertSize, pData + byteIndex, oldSize - byteIndex + 1);
 24.1489 +    memcpy (pData + byteIndex, substr, insertSize);
 24.1490 +    LengthIsSize = false;
 24.1491 +    Size = oldSize + insertSize;
 24.1492 +    pData[Size] = 0;
 24.1493 +}
 24.1494 +
 24.1495 +// Inserts character at posAt
 24.1496 +UPInt     StringBuffer::InsertCharAt(UInt32 c, UPInt posAt)
 24.1497 +{
 24.1498 +    char    buf[8];
 24.1499 +    SPInt   len = 0;
 24.1500 +    UTF8Util::EncodeChar(buf, &len, c);
 24.1501 +    OVR_ASSERT(len >= 0);
 24.1502 +    buf[(UPInt)len] = 0;
 24.1503 +
 24.1504 +    Insert(buf, posAt, len);
 24.1505 +    return (UPInt)len;
 24.1506 +}
 24.1507 +
 24.1508 +} // OVR
    25.1 --- a/libovr/Src/Kernel/OVR_String.h	Sat Sep 14 17:51:03 2013 +0300
    25.2 +++ b/libovr/Src/Kernel/OVR_String.h	Sun Sep 15 04:10:05 2013 +0300
    25.3 @@ -1,1 +1,645 @@
    25.4 -/************************************************************************************
    25.5 
    25.6 PublicHeader:   OVR.h
    25.7 Filename    :   OVR_String.h
    25.8 Content     :   String UTF8 string implementation with copy-on-write semantics
    25.9                 (thread-safe for assignment but not modification).
   25.10 Created     :   September 19, 2012
   25.11 Notes       : 
   25.12 
   25.13 Copyright   :   Copyright 2012 Oculus VR, Inc. All Rights reserved.
   25.14 
   25.15 Use of this software is subject to the terms of the Oculus license
   25.16 agreement provided at the time of installation or download, or which
   25.17 otherwise accompanies this software in either electronic or hard copy form.
   25.18 
   25.19 ************************************************************************************/
   25.20 
   25.21 #ifndef OVR_String_h
   25.22 #define OVR_String_h
   25.23 
   25.24 #include "OVR_Types.h"
   25.25 #include "OVR_Allocator.h"
   25.26 #include "OVR_UTF8Util.h"
   25.27 #include "OVR_Atomic.h"
   25.28 #include "OVR_Std.h"
   25.29 #include "OVR_Alg.h"
   25.30 
   25.31 namespace OVR {
   25.32 
   25.33 // ***** Classes
   25.34 
   25.35 class String;
   25.36 class StringBuffer;
   25.37 
   25.38 
   25.39 //-----------------------------------------------------------------------------------
   25.40 // ***** String Class 
   25.41 
   25.42 // String is UTF8 based string class with copy-on-write implementation
   25.43 // for assignment.
   25.44 
   25.45 class String
   25.46 {
   25.47 protected:
   25.48 
   25.49     enum FlagConstants
   25.50     {
   25.51         //Flag_GetLength      = 0x7FFFFFFF,
   25.52         // This flag is set if GetLength() == GetSize() for a string.
   25.53         // Avoid extra scanning is Substring and indexing logic.
   25.54         Flag_LengthIsSizeShift   = (sizeof(UPInt)*8 - 1)
   25.55     };
   25.56 
   25.57 
   25.58     // Internal structure to hold string data
   25.59     struct DataDesc
   25.60     {
   25.61         // Number of bytes. Will be the same as the number of chars if the characters
   25.62         // are ascii, may not be equal to number of chars in case string data is UTF8.
   25.63         UPInt   Size;       
   25.64         volatile SInt32 RefCount;
   25.65         char    Data[1];
   25.66 
   25.67         void    AddRef()
   25.68         {
   25.69             AtomicOps<SInt32>::ExchangeAdd_NoSync(&RefCount, 1);
   25.70         }
   25.71         // Decrement ref count. This needs to be thread-safe, since
   25.72         // a different thread could have also decremented the ref count.
   25.73         // For example, if u start off with a ref count = 2. Now if u
   25.74         // decrement the ref count and check against 0 in different
   25.75         // statements, a different thread can also decrement the ref count
   25.76         // in between our decrement and checking against 0 and will find
   25.77         // the ref count = 0 and delete the object. This will lead to a crash
   25.78         // when context switches to our thread and we'll be trying to delete
   25.79         // an already deleted object. Hence decrementing the ref count and
   25.80         // checking against 0 needs to made an atomic operation.
   25.81         void    Release()
   25.82         {
   25.83             if ((AtomicOps<SInt32>::ExchangeAdd_NoSync(&RefCount, -1) - 1) == 0)
   25.84                 OVR_FREE(this);
   25.85         }
   25.86 
   25.87         static UPInt GetLengthFlagBit()     { return UPInt(1) << Flag_LengthIsSizeShift; }
   25.88         UPInt       GetSize() const         { return Size & ~GetLengthFlagBit() ; }
   25.89         UPInt       GetLengthFlag()  const  { return Size & GetLengthFlagBit(); }
   25.90         bool        LengthIsSize() const    { return GetLengthFlag() != 0; }
   25.91     };
   25.92 
   25.93     // Heap type of the string is encoded in the lower bits.
   25.94     enum HeapType
   25.95     {
   25.96         HT_Global   = 0,    // Heap is global.
   25.97         HT_Local    = 1,    // SF::String_loc: Heap is determined based on string's address.
   25.98         HT_Dynamic  = 2,    // SF::String_temp: Heap is stored as a part of the class.
   25.99         HT_Mask     = 3
  25.100     };
  25.101 
  25.102     union {
  25.103         DataDesc* pData;
  25.104         UPInt     HeapTypeBits;
  25.105     };
  25.106     typedef union {
  25.107         DataDesc* pData;
  25.108         UPInt     HeapTypeBits;
  25.109     } DataDescUnion;
  25.110 
  25.111     inline HeapType    GetHeapType() const { return (HeapType) (HeapTypeBits & HT_Mask); }
  25.112 
  25.113     inline DataDesc*   GetData() const
  25.114     {
  25.115         DataDescUnion u;
  25.116         u.pData    = pData;
  25.117         u.HeapTypeBits = (u.HeapTypeBits & ~(UPInt)HT_Mask);
  25.118         return u.pData;
  25.119     }
  25.120     
  25.121     inline void        SetData(DataDesc* pdesc)
  25.122     {
  25.123         HeapType ht = GetHeapType();
  25.124         pData = pdesc;
  25.125         OVR_ASSERT((HeapTypeBits & HT_Mask) == 0);
  25.126         HeapTypeBits |= ht;        
  25.127     }
  25.128 
  25.129     
  25.130     DataDesc*   AllocData(UPInt size, UPInt lengthIsSize);
  25.131     DataDesc*   AllocDataCopy1(UPInt size, UPInt lengthIsSize,
  25.132                                const char* pdata, UPInt copySize);
  25.133     DataDesc*   AllocDataCopy2(UPInt size, UPInt lengthIsSize,
  25.134                                const char* pdata1, UPInt copySize1,
  25.135                                const char* pdata2, UPInt copySize2);
  25.136 
  25.137     // Special constructor to avoid data initalization when used in derived class.
  25.138     struct NoConstructor { };
  25.139     String(const NoConstructor&) { }
  25.140 
  25.141 public:
  25.142 
  25.143     // For initializing string with dynamic buffer
  25.144     struct InitStruct
  25.145     {
  25.146         virtual ~InitStruct() { }
  25.147         virtual void InitString(char* pbuffer, UPInt size) const = 0;
  25.148     };
  25.149 
  25.150 
  25.151     // Constructors / Destructors.
  25.152     String();
  25.153     String(const char* data);
  25.154     String(const char* data1, const char* pdata2, const char* pdata3 = 0);
  25.155     String(const char* data, UPInt buflen);
  25.156     String(const String& src);
  25.157     String(const StringBuffer& src);
  25.158     String(const InitStruct& src, UPInt size);
  25.159     explicit String(const wchar_t* data);      
  25.160 
  25.161     // Destructor (Captain Obvious guarantees!)
  25.162     ~String()
  25.163     {
  25.164         GetData()->Release();
  25.165     }
  25.166 
  25.167     // Declaration of NullString
  25.168     static DataDesc NullData;
  25.169 
  25.170 
  25.171     // *** General Functions
  25.172 
  25.173     void        Clear();
  25.174 
  25.175     // For casting to a pointer to char.
  25.176     operator const char*() const        { return GetData()->Data; }
  25.177     // Pointer to raw buffer.
  25.178     const char* ToCStr() const          { return GetData()->Data; }
  25.179 
  25.180     // Returns number of bytes
  25.181     UPInt       GetSize() const         { return GetData()->GetSize() ; }
  25.182     // Tells whether or not the string is empty
  25.183     bool        IsEmpty() const         { return GetSize() == 0; }
  25.184 
  25.185     // Returns  number of characters
  25.186     UPInt       GetLength() const;
  25.187 
  25.188     // Returns  character at the specified index
  25.189     UInt32      GetCharAt(UPInt index) const;
  25.190     UInt32      GetFirstCharAt(UPInt index, const char** offset) const;
  25.191     UInt32      GetNextChar(const char** offset) const;
  25.192 
  25.193     // Appends a character
  25.194     void        AppendChar(UInt32 ch);
  25.195 
  25.196     // Append a string
  25.197     void        AppendString(const wchar_t* pstr, SPInt len = -1);
  25.198     void        AppendString(const char* putf8str, SPInt utf8StrSz = -1);
  25.199 
  25.200     // Assigned a string with dynamic data (copied through initializer).
  25.201     void        AssignString(const InitStruct& src, UPInt size);
  25.202     // Assigns string with known size.
  25.203     void        AssignString(const char* putf8str, UPInt size);
  25.204 
  25.205     //  Resize the string to the new size
  25.206 //  void        Resize(UPInt _size);
  25.207 
  25.208     // Removes the character at posAt
  25.209     void        Remove(UPInt posAt, SPInt len = 1);
  25.210 
  25.211     // Returns a String that's a substring of this.
  25.212     //  -start is the index of the first UTF8 character you want to include.
  25.213     //  -end is the index one past the last UTF8 character you want to include.
  25.214     String   Substring(UPInt start, UPInt end) const;
  25.215 
  25.216     // Case-conversion
  25.217     String   ToUpper() const;
  25.218     String   ToLower() const;
  25.219 
  25.220     // Inserts substr at posAt
  25.221     String&    Insert (const char* substr, UPInt posAt, SPInt len = -1);
  25.222 
  25.223     // Inserts character at posAt
  25.224     UPInt       InsertCharAt(UInt32 c, UPInt posAt);
  25.225 
  25.226     // Inserts substr at posAt, which is an index of a character (not byte).
  25.227     // Of size is specified, it is in bytes.
  25.228 //  String&    Insert(const UInt32* substr, UPInt posAt, SPInt size = -1);
  25.229 
  25.230     // Get Byte index of the character at position = index
  25.231     UPInt       GetByteIndex(UPInt index) const { return (UPInt)UTF8Util::GetByteIndex(index, GetData()->Data); }
  25.232 
  25.233     // Utility: case-insensitive string compare.  stricmp() & strnicmp() are not
  25.234     // ANSI or POSIX, do not seem to appear in Linux.
  25.235     static int OVR_STDCALL   CompareNoCase(const char* a, const char* b);
  25.236     static int OVR_STDCALL   CompareNoCase(const char* a, const char* b, SPInt len);
  25.237 
  25.238     // Hash function, case-insensitive
  25.239     static UPInt OVR_STDCALL BernsteinHashFunctionCIS(const void* pdataIn, UPInt size, UPInt seed = 5381);
  25.240 
  25.241     // Hash function, case-sensitive
  25.242     static UPInt OVR_STDCALL BernsteinHashFunction(const void* pdataIn, UPInt size, UPInt seed = 5381);
  25.243 
  25.244 
  25.245     // ***** File path parsing helper functions.
  25.246     // Implemented in OVR_String_FilePath.cpp.
  25.247 
  25.248     // Absolute paths can star with:
  25.249     //  - protocols:        'file://', 'http://'
  25.250     //  - windows drive:    'c:\'
  25.251     //  - UNC share name:   '\\share'
  25.252     //  - unix root         '/'
  25.253     static bool HasAbsolutePath(const char* path);
  25.254     static bool HasExtension(const char* path);
  25.255     static bool HasProtocol(const char* path);
  25.256 
  25.257     bool    HasAbsolutePath() const { return HasAbsolutePath(ToCStr()); }
  25.258     bool    HasExtension() const    { return HasExtension(ToCStr()); }
  25.259     bool    HasProtocol() const     { return HasProtocol(ToCStr()); }
  25.260 
  25.261     String  GetProtocol() const;    // Returns protocol, if any, with trailing '://'.
  25.262     String  GetPath() const;        // Returns path with trailing '/'.
  25.263     String  GetFilename() const;    // Returns filename, including extension.
  25.264     String  GetExtension() const;   // Returns extension with a dot.
  25.265 
  25.266     void    StripProtocol();        // Strips front protocol, if any, from the string.
  25.267     void    StripExtension();       // Strips off trailing extension.
  25.268     
  25.269 
  25.270     // Operators
  25.271     // Assignment
  25.272     void        operator =  (const char* str);
  25.273     void        operator =  (const wchar_t* str);
  25.274     void        operator =  (const String& src);
  25.275     void        operator =  (const StringBuffer& src);
  25.276 
  25.277     // Addition
  25.278     void        operator += (const String& src);
  25.279     void        operator += (const char* psrc)       { AppendString(psrc); }
  25.280     void        operator += (const wchar_t* psrc)    { AppendString(psrc); }
  25.281     void        operator += (char  ch)               { AppendChar(ch); }
  25.282     String      operator +  (const char* str) const;
  25.283     String      operator +  (const String& src)  const;
  25.284 
  25.285     // Comparison
  25.286     bool        operator == (const String& str) const
  25.287     {
  25.288         return (OVR_strcmp(GetData()->Data, str.GetData()->Data)== 0);
  25.289     }
  25.290 
  25.291     bool        operator != (const String& str) const
  25.292     {
  25.293         return !operator == (str);
  25.294     }
  25.295 
  25.296     bool        operator == (const char* str) const
  25.297     {
  25.298         return OVR_strcmp(GetData()->Data, str) == 0;
  25.299     }
  25.300 
  25.301     bool        operator != (const char* str) const
  25.302     {
  25.303         return !operator == (str);
  25.304     }
  25.305 
  25.306     bool        operator <  (const char* pstr) const
  25.307     {
  25.308         return OVR_strcmp(GetData()->Data, pstr) < 0;
  25.309     }
  25.310 
  25.311     bool        operator <  (const String& str) const
  25.312     {
  25.313         return *this < str.GetData()->Data;
  25.314     }
  25.315 
  25.316     bool        operator >  (const char* pstr) const
  25.317     {
  25.318         return OVR_strcmp(GetData()->Data, pstr) > 0;
  25.319     }
  25.320 
  25.321     bool        operator >  (const String& str) const
  25.322     {
  25.323         return *this > str.GetData()->Data;
  25.324     }
  25.325 
  25.326     int CompareNoCase(const char* pstr) const
  25.327     {
  25.328         return CompareNoCase(GetData()->Data, pstr);
  25.329     }
  25.330     int CompareNoCase(const String& str) const
  25.331     {
  25.332         return CompareNoCase(GetData()->Data, str.ToCStr());
  25.333     }
  25.334 
  25.335     // Accesses raw bytes
  25.336     const char&     operator [] (int index) const
  25.337     {
  25.338         OVR_ASSERT(index >= 0 && (UPInt)index < GetSize());
  25.339         return GetData()->Data[index];
  25.340     }
  25.341     const char&     operator [] (UPInt index) const
  25.342     {
  25.343         OVR_ASSERT(index < GetSize());
  25.344         return GetData()->Data[index];
  25.345     }
  25.346 
  25.347 
  25.348     // Case insensitive keys are used to look up insensitive string in hash tables
  25.349     // for SWF files with version before SWF 7.
  25.350     struct NoCaseKey
  25.351     {   
  25.352         const String* pStr;
  25.353         NoCaseKey(const String &str) : pStr(&str){};
  25.354     };
  25.355 
  25.356     bool    operator == (const NoCaseKey& strKey) const
  25.357     {
  25.358         return (CompareNoCase(ToCStr(), strKey.pStr->ToCStr()) == 0);
  25.359     }
  25.360     bool    operator != (const NoCaseKey& strKey) const
  25.361     {
  25.362         return !(CompareNoCase(ToCStr(), strKey.pStr->ToCStr()) == 0);
  25.363     }
  25.364 
  25.365     // Hash functor used for strings.
  25.366     struct HashFunctor
  25.367     {    
  25.368         UPInt  operator()(const String& data) const
  25.369         {
  25.370             UPInt  size = data.GetSize();
  25.371             return String::BernsteinHashFunction((const char*)data, size);
  25.372         }        
  25.373     };
  25.374     // Case-insensitive hash functor used for strings. Supports additional
  25.375     // lookup based on NoCaseKey.
  25.376     struct NoCaseHashFunctor
  25.377     {    
  25.378         UPInt  operator()(const String& data) const
  25.379         {
  25.380             UPInt  size = data.GetSize();
  25.381             return String::BernsteinHashFunctionCIS((const char*)data, size);
  25.382         }
  25.383         UPInt  operator()(const NoCaseKey& data) const
  25.384         {       
  25.385             UPInt  size = data.pStr->GetSize();
  25.386             return String::BernsteinHashFunctionCIS((const char*)data.pStr->ToCStr(), size);
  25.387         }
  25.388     };
  25.389 
  25.390 };
  25.391 
  25.392 
  25.393 //-----------------------------------------------------------------------------------
  25.394 // ***** String Buffer used for Building Strings
  25.395 
  25.396 class StringBuffer
  25.397 {
  25.398     char*           pData;
  25.399     UPInt           Size;
  25.400     UPInt           BufferSize;
  25.401     UPInt           GrowSize;    
  25.402     mutable bool    LengthIsSize;    
  25.403 
  25.404 public:
  25.405 
  25.406     // Constructors / Destructor.    
  25.407     StringBuffer();
  25.408     explicit StringBuffer(UPInt growSize);
  25.409     StringBuffer(const char* data);
  25.410     StringBuffer(const char* data, UPInt buflen);
  25.411     StringBuffer(const String& src);
  25.412     StringBuffer(const StringBuffer& src);
  25.413     explicit StringBuffer(const wchar_t* data);
  25.414     ~StringBuffer();
  25.415     
  25.416 
  25.417     // Modify grow size used for growing/shrinking the buffer.
  25.418     UPInt       GetGrowSize() const         { return GrowSize; }
  25.419     void        SetGrowSize(UPInt growSize);
  25.420     
  25.421 
  25.422     // *** General Functions
  25.423     // Does not release memory, just sets Size to 0
  25.424     void        Clear();
  25.425 
  25.426     // For casting to a pointer to char.
  25.427     operator const char*() const        { return (pData) ? pData : ""; }
  25.428     // Pointer to raw buffer.
  25.429     const char* ToCStr() const          { return (pData) ? pData : ""; }
  25.430 
  25.431     // Returns number of bytes.
  25.432     UPInt       GetSize() const         { return Size ; }
  25.433     // Tells whether or not the string is empty.
  25.434     bool        IsEmpty() const         { return GetSize() == 0; }
  25.435 
  25.436     // Returns  number of characters
  25.437     UPInt       GetLength() const;
  25.438 
  25.439     // Returns  character at the specified index
  25.440     UInt32      GetCharAt(UPInt index) const;
  25.441     UInt32      GetFirstCharAt(UPInt index, const char** offset) const;
  25.442     UInt32      GetNextChar(const char** offset) const;
  25.443 
  25.444 
  25.445     //  Resize the string to the new size
  25.446     void        Resize(UPInt _size);
  25.447     void        Reserve(UPInt _size);
  25.448 
  25.449     // Appends a character
  25.450     void        AppendChar(UInt32 ch);
  25.451 
  25.452     // Append a string
  25.453     void        AppendString(const wchar_t* pstr, SPInt len = -1);
  25.454     void        AppendString(const char* putf8str, SPInt utf8StrSz = -1);
  25.455     void        AppendFormat(const char* format, ...);
  25.456 
  25.457     // Assigned a string with dynamic data (copied through initializer).
  25.458     //void        AssignString(const InitStruct& src, UPInt size);
  25.459 
  25.460     // Inserts substr at posAt
  25.461     void        Insert (const char* substr, UPInt posAt, SPInt len = -1);
  25.462     // Inserts character at posAt
  25.463     UPInt       InsertCharAt(UInt32 c, UPInt posAt);
  25.464 
  25.465     // Assignment
  25.466     void        operator =  (const char* str);
  25.467     void        operator =  (const wchar_t* str);
  25.468     void        operator =  (const String& src);
  25.469 
  25.470     // Addition
  25.471     void        operator += (const String& src)      { AppendString(src.ToCStr(),src.GetSize()); }
  25.472     void        operator += (const char* psrc)       { AppendString(psrc); }
  25.473     void        operator += (const wchar_t* psrc)    { AppendString(psrc); }
  25.474     void        operator += (char  ch)               { AppendChar(ch); }
  25.475     //String   operator +  (const char* str) const ;
  25.476     //String   operator +  (const String& src)  const ;
  25.477 
  25.478     // Accesses raw bytes
  25.479     char&       operator [] (int index)
  25.480     {
  25.481         OVR_ASSERT(((UPInt)index) < GetSize());
  25.482         return pData[index];
  25.483     }
  25.484     char&       operator [] (UPInt index)
  25.485     {
  25.486         OVR_ASSERT(index < GetSize());
  25.487         return pData[index];
  25.488     }
  25.489 
  25.490     const char&     operator [] (int index) const 
  25.491     {
  25.492         OVR_ASSERT(((UPInt)index) < GetSize());
  25.493         return pData[index];
  25.494     }
  25.495     const char&     operator [] (UPInt index) const
  25.496     {
  25.497         OVR_ASSERT(index < GetSize());
  25.498         return pData[index];
  25.499     }
  25.500 };
  25.501 
  25.502 
  25.503 //
  25.504 // Wrapper for string data. The data must have a guaranteed 
  25.505 // lifespan throughout the usage of the wrapper. Not intended for 
  25.506 // cached usage. Not thread safe.
  25.507 //
  25.508 class StringDataPtr
  25.509 {
  25.510 public:
  25.511     StringDataPtr() : pStr(NULL), Size(0) {}
  25.512     StringDataPtr(const StringDataPtr& p)
  25.513         : pStr(p.pStr), Size(p.Size) {}
  25.514     StringDataPtr(const char* pstr, UPInt sz)
  25.515         : pStr(pstr), Size(sz) {}
  25.516     StringDataPtr(const char* pstr)
  25.517         : pStr(pstr), Size((pstr != NULL) ? OVR_strlen(pstr) : 0) {}
  25.518     explicit StringDataPtr(const String& str)
  25.519         : pStr(str.ToCStr()), Size(str.GetSize()) {}
  25.520     template <typename T, int N> 
  25.521     StringDataPtr(const T (&v)[N])
  25.522         : pStr(v), Size(N) {}
  25.523 
  25.524 public:
  25.525     const char* ToCStr() const { return pStr; }
  25.526     UPInt       GetSize() const { return Size; }
  25.527     bool        IsEmpty() const { return GetSize() == 0; }
  25.528 
  25.529     // value is a prefix of this string
  25.530     // Character's values are not compared.
  25.531     bool        IsPrefix(const StringDataPtr& value) const
  25.532     {
  25.533         return ToCStr() == value.ToCStr() && GetSize() >= value.GetSize();
  25.534     }
  25.535     // value is a suffix of this string
  25.536     // Character's values are not compared.
  25.537     bool        IsSuffix(const StringDataPtr& value) const
  25.538     {
  25.539         return ToCStr() <= value.ToCStr() && (End()) == (value.End());
  25.540     }
  25.541 
  25.542     // Find first character.
  25.543     // init_ind - initial index.
  25.544     SPInt       FindChar(char c, UPInt init_ind = 0) const 
  25.545     {
  25.546         for (UPInt i = init_ind; i < GetSize(); ++i)
  25.547             if (pStr[i] == c)
  25.548                 return static_cast<SPInt>(i);
  25.549 
  25.550         return -1; 
  25.551     }
  25.552 
  25.553     // Find last character.
  25.554     // init_ind - initial index.
  25.555     SPInt       FindLastChar(char c, UPInt init_ind = ~0) const 
  25.556     {
  25.557         if (init_ind == (UPInt)~0 || init_ind > GetSize())
  25.558             init_ind = GetSize();
  25.559         else
  25.560             ++init_ind;
  25.561 
  25.562         for (UPInt i = init_ind; i > 0; --i)
  25.563             if (pStr[i - 1] == c)
  25.564                 return static_cast<SPInt>(i - 1);
  25.565 
  25.566         return -1; 
  25.567     }
  25.568 
  25.569     // Create new object and trim size bytes from the left.
  25.570     StringDataPtr  GetTrimLeft(UPInt size) const
  25.571     {
  25.572         // Limit trim size to the size of the string.
  25.573         size = Alg::PMin(GetSize(), size);
  25.574 
  25.575         return StringDataPtr(ToCStr() + size, GetSize() - size);
  25.576     }
  25.577     // Create new object and trim size bytes from the right.
  25.578     StringDataPtr  GetTrimRight(UPInt size) const
  25.579     {
  25.580         // Limit trim to the size of the string.
  25.581         size = Alg::PMin(GetSize(), size);
  25.582 
  25.583         return StringDataPtr(ToCStr(), GetSize() - size);
  25.584     }
  25.585 
  25.586     // Create new object, which contains next token.
  25.587     // Useful for parsing.
  25.588     StringDataPtr GetNextToken(char separator = ':') const
  25.589     {
  25.590         UPInt cur_pos = 0;
  25.591         const char* cur_str = ToCStr();
  25.592 
  25.593         for (; cur_pos < GetSize() && cur_str[cur_pos]; ++cur_pos)
  25.594         {
  25.595             if (cur_str[cur_pos] == separator)
  25.596             {
  25.597                 break;
  25.598             }
  25.599         }
  25.600 
  25.601         return StringDataPtr(ToCStr(), cur_pos);
  25.602     }
  25.603 
  25.604     // Trim size bytes from the left.
  25.605     StringDataPtr& TrimLeft(UPInt size)
  25.606     {
  25.607         // Limit trim size to the size of the string.
  25.608         size = Alg::PMin(GetSize(), size);
  25.609         pStr += size;
  25.610         Size -= size;
  25.611 
  25.612         return *this;
  25.613     }
  25.614     // Trim size bytes from the right.
  25.615     StringDataPtr& TrimRight(UPInt size)
  25.616     {
  25.617         // Limit trim to the size of the string.
  25.618         size = Alg::PMin(GetSize(), size);
  25.619         Size -= size;
  25.620 
  25.621         return *this;
  25.622     }
  25.623 
  25.624     const char* Begin() const { return ToCStr(); }
  25.625     const char* End() const { return ToCStr() + GetSize(); }
  25.626 
  25.627     // Hash functor used string data pointers
  25.628     struct HashFunctor
  25.629     {    
  25.630         UPInt operator()(const StringDataPtr& data) const
  25.631         {
  25.632             return String::BernsteinHashFunction(data.ToCStr(), data.GetSize());
  25.633         }        
  25.634     };
  25.635 
  25.636     bool operator== (const StringDataPtr& data) const 
  25.637     {
  25.638         return (OVR_strncmp(pStr, data.pStr, data.Size) == 0);
  25.639     }
  25.640 
  25.641 protected:
  25.642     const char* pStr;
  25.643     UPInt       Size;
  25.644 };
  25.645 
  25.646 } // OVR
  25.647 
  25.648 #endif
  25.649 \ No newline at end of file
  25.650 +/************************************************************************************
  25.651 +
  25.652 +PublicHeader:   OVR.h
  25.653 +Filename    :   OVR_String.h
  25.654 +Content     :   String UTF8 string implementation with copy-on-write semantics
  25.655 +                (thread-safe for assignment but not modification).
  25.656 +Created     :   September 19, 2012
  25.657 +Notes       : 
  25.658 +
  25.659 +Copyright   :   Copyright 2012 Oculus VR, Inc. All Rights reserved.
  25.660 +
  25.661 +Use of this software is subject to the terms of the Oculus license
  25.662 +agreement provided at the time of installation or download, or which
  25.663 +otherwise accompanies this software in either electronic or hard copy form.
  25.664 +
  25.665 +************************************************************************************/
  25.666 +
  25.667 +#ifndef OVR_String_h
  25.668 +#define OVR_String_h
  25.669 +
  25.670 +#include "OVR_Types.h"
  25.671 +#include "OVR_Allocator.h"
  25.672 +#include "OVR_UTF8Util.h"
  25.673 +#include "OVR_Atomic.h"
  25.674 +#include "OVR_Std.h"
  25.675 +#include "OVR_Alg.h"
  25.676 +
  25.677 +namespace OVR {
  25.678 +
  25.679 +// ***** Classes
  25.680 +
  25.681 +class String;
  25.682 +class StringBuffer;
  25.683 +
  25.684 +
  25.685 +//-----------------------------------------------------------------------------------
  25.686 +// ***** String Class 
  25.687 +
  25.688 +// String is UTF8 based string class with copy-on-write implementation
  25.689 +// for assignment.
  25.690 +
  25.691 +class String
  25.692 +{
  25.693 +protected:
  25.694 +
  25.695 +    enum FlagConstants
  25.696 +    {
  25.697 +        //Flag_GetLength      = 0x7FFFFFFF,
  25.698 +        // This flag is set if GetLength() == GetSize() for a string.
  25.699 +        // Avoid extra scanning is Substring and indexing logic.
  25.700 +        Flag_LengthIsSizeShift   = (sizeof(UPInt)*8 - 1)
  25.701 +    };
  25.702 +
  25.703 +
  25.704 +    // Internal structure to hold string data
  25.705 +    struct DataDesc
  25.706 +    {
  25.707 +        // Number of bytes. Will be the same as the number of chars if the characters
  25.708 +        // are ascii, may not be equal to number of chars in case string data is UTF8.
  25.709 +        UPInt   Size;       
  25.710 +        volatile SInt32 RefCount;
  25.711 +        char    Data[1];
  25.712 +
  25.713 +        void    AddRef()
  25.714 +        {
  25.715 +            AtomicOps<SInt32>::ExchangeAdd_NoSync(&RefCount, 1);
  25.716 +        }
  25.717 +        // Decrement ref count. This needs to be thread-safe, since
  25.718 +        // a different thread could have also decremented the ref count.
  25.719 +        // For example, if u start off with a ref count = 2. Now if u
  25.720 +        // decrement the ref count and check against 0 in different
  25.721 +        // statements, a different thread can also decrement the ref count
  25.722 +        // in between our decrement and checking against 0 and will find
  25.723 +        // the ref count = 0 and delete the object. This will lead to a crash
  25.724 +        // when context switches to our thread and we'll be trying to delete
  25.725 +        // an already deleted object. Hence decrementing the ref count and
  25.726 +        // checking against 0 needs to made an atomic operation.
  25.727 +        void    Release()
  25.728 +        {
  25.729 +            if ((AtomicOps<SInt32>::ExchangeAdd_NoSync(&RefCount, -1) - 1) == 0)
  25.730 +                OVR_FREE(this);
  25.731 +        }
  25.732 +
  25.733 +        static UPInt GetLengthFlagBit()     { return UPInt(1) << Flag_LengthIsSizeShift; }
  25.734 +        UPInt       GetSize() const         { return Size & ~GetLengthFlagBit() ; }
  25.735 +        UPInt       GetLengthFlag()  const  { return Size & GetLengthFlagBit(); }
  25.736 +        bool        LengthIsSize() const    { return GetLengthFlag() != 0; }
  25.737 +    };
  25.738 +
  25.739 +    // Heap type of the string is encoded in the lower bits.
  25.740 +    enum HeapType
  25.741 +    {
  25.742 +        HT_Global   = 0,    // Heap is global.
  25.743 +        HT_Local    = 1,    // SF::String_loc: Heap is determined based on string's address.
  25.744 +        HT_Dynamic  = 2,    // SF::String_temp: Heap is stored as a part of the class.
  25.745 +        HT_Mask     = 3
  25.746 +    };
  25.747 +
  25.748 +    union {
  25.749 +        DataDesc* pData;
  25.750 +        UPInt     HeapTypeBits;
  25.751 +    };
  25.752 +    typedef union {
  25.753 +        DataDesc* pData;
  25.754 +        UPInt     HeapTypeBits;
  25.755 +    } DataDescUnion;
  25.756 +
  25.757 +    inline HeapType    GetHeapType() const { return (HeapType) (HeapTypeBits & HT_Mask); }
  25.758 +
  25.759 +    inline DataDesc*   GetData() const
  25.760 +    {
  25.761 +        DataDescUnion u;
  25.762 +        u.pData    = pData;
  25.763 +        u.HeapTypeBits = (u.HeapTypeBits & ~(UPInt)HT_Mask);
  25.764 +        return u.pData;
  25.765 +    }
  25.766 +    
  25.767 +    inline void        SetData(DataDesc* pdesc)
  25.768 +    {
  25.769 +        HeapType ht = GetHeapType();
  25.770 +        pData = pdesc;
  25.771 +        OVR_ASSERT((HeapTypeBits & HT_Mask) == 0);
  25.772 +        HeapTypeBits |= ht;        
  25.773 +    }
  25.774 +
  25.775 +    
  25.776 +    DataDesc*   AllocData(UPInt size, UPInt lengthIsSize);
  25.777 +    DataDesc*   AllocDataCopy1(UPInt size, UPInt lengthIsSize,
  25.778 +                               const char* pdata, UPInt copySize);
  25.779 +    DataDesc*   AllocDataCopy2(UPInt size, UPInt lengthIsSize,
  25.780 +                               const char* pdata1, UPInt copySize1,
  25.781 +                               const char* pdata2, UPInt copySize2);
  25.782 +
  25.783 +    // Special constructor to avoid data initalization when used in derived class.
  25.784 +    struct NoConstructor { };
  25.785 +    String(const NoConstructor&) { }
  25.786 +
  25.787 +public:
  25.788 +
  25.789 +    // For initializing string with dynamic buffer
  25.790 +    struct InitStruct
  25.791 +    {
  25.792 +        virtual ~InitStruct() { }
  25.793 +        virtual void InitString(char* pbuffer, UPInt size) const = 0;
  25.794 +    };
  25.795 +
  25.796 +
  25.797 +    // Constructors / Destructors.
  25.798 +    String();
  25.799 +    String(const char* data);
  25.800 +    String(const char* data1, const char* pdata2, const char* pdata3 = 0);
  25.801 +    String(const char* data, UPInt buflen);
  25.802 +    String(const String& src);
  25.803 +    String(const StringBuffer& src);
  25.804 +    String(const InitStruct& src, UPInt size);
  25.805 +    explicit String(const wchar_t* data);      
  25.806 +
  25.807 +    // Destructor (Captain Obvious guarantees!)
  25.808 +    ~String()
  25.809 +    {
  25.810 +        GetData()->Release();
  25.811 +    }
  25.812 +
  25.813 +    // Declaration of NullString
  25.814 +    static DataDesc NullData;
  25.815 +
  25.816 +
  25.817 +    // *** General Functions
  25.818 +
  25.819 +    void        Clear();
  25.820 +
  25.821 +    // For casting to a pointer to char.
  25.822 +    operator const char*() const        { return GetData()->Data; }
  25.823 +    // Pointer to raw buffer.
  25.824 +    const char* ToCStr() const          { return GetData()->Data; }
  25.825 +
  25.826 +    // Returns number of bytes
  25.827 +    UPInt       GetSize() const         { return GetData()->GetSize() ; }
  25.828 +    // Tells whether or not the string is empty
  25.829 +    bool        IsEmpty() const         { return GetSize() == 0; }
  25.830 +
  25.831 +    // Returns  number of characters
  25.832 +    UPInt       GetLength() const;
  25.833 +
  25.834 +    // Returns  character at the specified index
  25.835 +    UInt32      GetCharAt(UPInt index) const;
  25.836 +    UInt32      GetFirstCharAt(UPInt index, const char** offset) const;
  25.837 +    UInt32      GetNextChar(const char** offset) const;
  25.838 +
  25.839 +    // Appends a character
  25.840 +    void        AppendChar(UInt32 ch);
  25.841 +
  25.842 +    // Append a string
  25.843 +    void        AppendString(const wchar_t* pstr, SPInt len = -1);
  25.844 +    void        AppendString(const char* putf8str, SPInt utf8StrSz = -1);
  25.845 +
  25.846 +    // Assigned a string with dynamic data (copied through initializer).
  25.847 +    void        AssignString(const InitStruct& src, UPInt size);
  25.848 +    // Assigns string with known size.
  25.849 +    void        AssignString(const char* putf8str, UPInt size);
  25.850 +
  25.851 +    //  Resize the string to the new size
  25.852 +//  void        Resize(UPInt _size);
  25.853 +
  25.854 +    // Removes the character at posAt
  25.855 +    void        Remove(UPInt posAt, SPInt len = 1);
  25.856 +
  25.857 +    // Returns a String that's a substring of this.
  25.858 +    //  -start is the index of the first UTF8 character you want to include.
  25.859 +    //  -end is the index one past the last UTF8 character you want to include.
  25.860 +    String   Substring(UPInt start, UPInt end) const;
  25.861 +
  25.862 +    // Case-conversion
  25.863 +    String   ToUpper() const;
  25.864 +    String   ToLower() const;
  25.865 +
  25.866 +    // Inserts substr at posAt
  25.867 +    String&    Insert (const char* substr, UPInt posAt, SPInt len = -1);
  25.868 +
  25.869 +    // Inserts character at posAt
  25.870 +    UPInt       InsertCharAt(UInt32 c, UPInt posAt);
  25.871 +
  25.872 +    // Inserts substr at posAt, which is an index of a character (not byte).
  25.873 +    // Of size is specified, it is in bytes.
  25.874 +//  String&    Insert(const UInt32* substr, UPInt posAt, SPInt size = -1);
  25.875 +
  25.876 +    // Get Byte index of the character at position = index
  25.877 +    UPInt       GetByteIndex(UPInt index) const { return (UPInt)UTF8Util::GetByteIndex(index, GetData()->Data); }
  25.878 +
  25.879 +    // Utility: case-insensitive string compare.  stricmp() & strnicmp() are not
  25.880 +    // ANSI or POSIX, do not seem to appear in Linux.
  25.881 +    static int OVR_STDCALL   CompareNoCase(const char* a, const char* b);
  25.882 +    static int OVR_STDCALL   CompareNoCase(const char* a, const char* b, SPInt len);
  25.883 +
  25.884 +    // Hash function, case-insensitive
  25.885 +    static UPInt OVR_STDCALL BernsteinHashFunctionCIS(const void* pdataIn, UPInt size, UPInt seed = 5381);
  25.886 +
  25.887 +    // Hash function, case-sensitive
  25.888 +    static UPInt OVR_STDCALL BernsteinHashFunction(const void* pdataIn, UPInt size, UPInt seed = 5381);
  25.889 +
  25.890 +
  25.891 +    // ***** File path parsing helper functions.
  25.892 +    // Implemented in OVR_String_FilePath.cpp.
  25.893 +
  25.894 +    // Absolute paths can star with:
  25.895 +    //  - protocols:        'file://', 'http://'
  25.896 +    //  - windows drive:    'c:\'
  25.897 +    //  - UNC share name:   '\\share'
  25.898 +    //  - unix root         '/'
  25.899 +    static bool HasAbsolutePath(const char* path);
  25.900 +    static bool HasExtension(const char* path);
  25.901 +    static bool HasProtocol(const char* path);
  25.902 +
  25.903 +    bool    HasAbsolutePath() const { return HasAbsolutePath(ToCStr()); }
  25.904 +    bool    HasExtension() const    { return HasExtension(ToCStr()); }
  25.905 +    bool    HasProtocol() const     { return HasProtocol(ToCStr()); }
  25.906 +
  25.907 +    String  GetProtocol() const;    // Returns protocol, if any, with trailing '://'.
  25.908 +    String  GetPath() const;        // Returns path with trailing '/'.
  25.909 +    String  GetFilename() const;    // Returns filename, including extension.
  25.910 +    String  GetExtension() const;   // Returns extension with a dot.
  25.911 +
  25.912 +    void    StripProtocol();        // Strips front protocol, if any, from the string.
  25.913 +    void    StripExtension();       // Strips off trailing extension.
  25.914 +    
  25.915 +
  25.916 +    // Operators
  25.917 +    // Assignment
  25.918 +    void        operator =  (const char* str);
  25.919 +    void        operator =  (const wchar_t* str);
  25.920 +    void        operator =  (const String& src);
  25.921 +    void        operator =  (const StringBuffer& src);
  25.922 +
  25.923 +    // Addition
  25.924 +    void        operator += (const String& src);
  25.925 +    void        operator += (const char* psrc)       { AppendString(psrc); }
  25.926 +    void        operator += (const wchar_t* psrc)    { AppendString(psrc); }
  25.927 +    void        operator += (char  ch)               { AppendChar(ch); }
  25.928 +    String      operator +  (const char* str) const;
  25.929 +    String      operator +  (const String& src)  const;
  25.930 +
  25.931 +    // Comparison
  25.932 +    bool        operator == (const String& str) const
  25.933 +    {
  25.934 +        return (OVR_strcmp(GetData()->Data, str.GetData()->Data)== 0);
  25.935 +    }
  25.936 +
  25.937 +    bool        operator != (const String& str) const
  25.938 +    {
  25.939 +        return !operator == (str);
  25.940 +    }
  25.941 +
  25.942 +    bool        operator == (const char* str) const
  25.943 +    {
  25.944 +        return OVR_strcmp(GetData()->Data, str) == 0;
  25.945 +    }
  25.946 +
  25.947 +    bool        operator != (const char* str) const
  25.948 +    {
  25.949 +        return !operator == (str);
  25.950 +    }
  25.951 +
  25.952 +    bool        operator <  (const char* pstr) const
  25.953 +    {
  25.954 +        return OVR_strcmp(GetData()->Data, pstr) < 0;
  25.955 +    }
  25.956 +
  25.957 +    bool        operator <  (const String& str) const
  25.958 +    {
  25.959 +        return *this < str.GetData()->Data;
  25.960 +    }
  25.961 +
  25.962 +    bool        operator >  (const char* pstr) const
  25.963 +    {
  25.964 +        return OVR_strcmp(GetData()->Data, pstr) > 0;
  25.965 +    }
  25.966 +
  25.967 +    bool        operator >  (const String& str) const
  25.968 +    {
  25.969 +        return *this > str.GetData()->Data;
  25.970 +    }
  25.971 +
  25.972 +    int CompareNoCase(const char* pstr) const
  25.973 +    {
  25.974 +        return CompareNoCase(GetData()->Data, pstr);
  25.975 +    }
  25.976 +    int CompareNoCase(const String& str) const
  25.977 +    {
  25.978 +        return CompareNoCase(GetData()->Data, str.ToCStr());
  25.979 +    }
  25.980 +
  25.981 +    // Accesses raw bytes
  25.982 +    const char&     operator [] (int index) const
  25.983 +    {
  25.984 +        OVR_ASSERT(index >= 0 && (UPInt)index < GetSize());
  25.985 +        return GetData()->Data[index];
  25.986 +    }
  25.987 +    const char&     operator [] (UPInt index) const
  25.988 +    {
  25.989 +        OVR_ASSERT(index < GetSize());
  25.990 +        return GetData()->Data[index];
  25.991 +    }
  25.992 +
  25.993 +
  25.994 +    // Case insensitive keys are used to look up insensitive string in hash tables
  25.995 +    // for SWF files with version before SWF 7.
  25.996 +    struct NoCaseKey
  25.997 +    {   
  25.998 +        const String* pStr;
  25.999 +        NoCaseKey(const String &str) : pStr(&str){};
 25.1000 +    };
 25.1001 +
 25.1002 +    bool    operator == (const NoCaseKey& strKey) const
 25.1003 +    {
 25.1004 +        return (CompareNoCase(ToCStr(), strKey.pStr->ToCStr()) == 0);
 25.1005 +    }
 25.1006 +    bool    operator != (const NoCaseKey& strKey) const
 25.1007 +    {
 25.1008 +        return !(CompareNoCase(ToCStr(), strKey.pStr->ToCStr()) == 0);
 25.1009 +    }
 25.1010 +
 25.1011 +    // Hash functor used for strings.
 25.1012 +    struct HashFunctor
 25.1013 +    {    
 25.1014 +        UPInt  operator()(const String& data) const
 25.1015 +        {
 25.1016 +            UPInt  size = data.GetSize();
 25.1017 +            return String::BernsteinHashFunction((const char*)data, size);
 25.1018 +        }        
 25.1019 +    };
 25.1020 +    // Case-insensitive hash functor used for strings. Supports additional
 25.1021 +    // lookup based on NoCaseKey.
 25.1022 +    struct NoCaseHashFunctor
 25.1023 +    {    
 25.1024 +        UPInt  operator()(const String& data) const
 25.1025 +        {
 25.1026 +            UPInt  size = data.GetSize();
 25.1027 +            return String::BernsteinHashFunctionCIS((const char*)data, size);
 25.1028 +        }
 25.1029 +        UPInt  operator()(const NoCaseKey& data) const
 25.1030 +        {       
 25.1031 +            UPInt  size = data.pStr->GetSize();
 25.1032 +            return String::BernsteinHashFunctionCIS((const char*)data.pStr->ToCStr(), size);
 25.1033 +        }
 25.1034 +    };
 25.1035 +
 25.1036 +};
 25.1037 +
 25.1038 +
 25.1039 +//-----------------------------------------------------------------------------------
 25.1040 +// ***** String Buffer used for Building Strings
 25.1041 +
 25.1042 +class StringBuffer
 25.1043 +{
 25.1044 +    char*           pData;
 25.1045 +    UPInt           Size;
 25.1046 +    UPInt           BufferSize;
 25.1047 +    UPInt           GrowSize;    
 25.1048 +    mutable bool    LengthIsSize;    
 25.1049 +
 25.1050 +public:
 25.1051 +
 25.1052 +    // Constructors / Destructor.    
 25.1053 +    StringBuffer();
 25.1054 +    explicit StringBuffer(UPInt growSize);
 25.1055 +    StringBuffer(const char* data);
 25.1056 +    StringBuffer(const char* data, UPInt buflen);
 25.1057 +    StringBuffer(const String& src);
 25.1058 +    StringBuffer(const StringBuffer& src);
 25.1059 +    explicit StringBuffer(const wchar_t* data);
 25.1060 +    ~StringBuffer();
 25.1061 +    
 25.1062 +
 25.1063 +    // Modify grow size used for growing/shrinking the buffer.
 25.1064 +    UPInt       GetGrowSize() const         { return GrowSize; }
 25.1065 +    void        SetGrowSize(UPInt growSize);
 25.1066 +    
 25.1067 +
 25.1068 +    // *** General Functions
 25.1069 +    // Does not release memory, just sets Size to 0
 25.1070 +    void        Clear();
 25.1071 +
 25.1072 +    // For casting to a pointer to char.
 25.1073 +    operator const char*() const        { return (pData) ? pData : ""; }
 25.1074 +    // Pointer to raw buffer.
 25.1075 +    const char* ToCStr() const          { return (pData) ? pData : ""; }
 25.1076 +
 25.1077 +    // Returns number of bytes.
 25.1078 +    UPInt       GetSize() const         { return Size ; }
 25.1079 +    // Tells whether or not the string is empty.
 25.1080 +    bool        IsEmpty() const         { return GetSize() == 0; }
 25.1081 +
 25.1082 +    // Returns  number of characters
 25.1083 +    UPInt       GetLength() const;
 25.1084 +
 25.1085 +    // Returns  character at the specified index
 25.1086 +    UInt32      GetCharAt(UPInt index) const;
 25.1087 +    UInt32      GetFirstCharAt(UPInt index, const char** offset) const;
 25.1088 +    UInt32      GetNextChar(const char** offset) const;
 25.1089 +
 25.1090 +
 25.1091 +    //  Resize the string to the new size
 25.1092 +    void        Resize(UPInt _size);
 25.1093 +    void        Reserve(UPInt _size);
 25.1094 +
 25.1095 +    // Appends a character
 25.1096 +    void        AppendChar(UInt32 ch);
 25.1097 +
 25.1098 +    // Append a string
 25.1099 +    void        AppendString(const wchar_t* pstr, SPInt len = -1);
 25.1100 +    void        AppendString(const char* putf8str, SPInt utf8StrSz = -1);
 25.1101 +    void        AppendFormat(const char* format, ...);
 25.1102 +
 25.1103 +    // Assigned a string with dynamic data (copied through initializer).
 25.1104 +    //void        AssignString(const InitStruct& src, UPInt size);
 25.1105 +
 25.1106 +    // Inserts substr at posAt
 25.1107 +    void        Insert (const char* substr, UPInt posAt, SPInt len = -1);
 25.1108 +    // Inserts character at posAt
 25.1109 +    UPInt       InsertCharAt(UInt32 c, UPInt posAt);
 25.1110 +
 25.1111 +    // Assignment
 25.1112 +    void        operator =  (const char* str);
 25.1113 +    void        operator =  (const wchar_t* str);
 25.1114 +    void        operator =  (const String& src);
 25.1115 +
 25.1116 +    // Addition
 25.1117 +    void        operator += (const String& src)      { AppendString(src.ToCStr(),src.GetSize()); }
 25.1118 +    void        operator += (const char* psrc)       { AppendString(psrc); }
 25.1119 +    void        operator += (const wchar_t* psrc)    { AppendString(psrc); }
 25.1120 +    void        operator += (char  ch)               { AppendChar(ch); }
 25.1121 +    //String   operator +  (const char* str) const ;
 25.1122 +    //String   operator +  (const String& src)  const ;
 25.1123 +
 25.1124 +    // Accesses raw bytes
 25.1125 +    char&       operator [] (int index)
 25.1126 +    {
 25.1127 +        OVR_ASSERT(((UPInt)index) < GetSize());
 25.1128 +        return pData[index];
 25.1129 +    }
 25.1130 +    char&       operator [] (UPInt index)
 25.1131 +    {
 25.1132 +        OVR_ASSERT(index < GetSize());
 25.1133 +        return pData[index];
 25.1134 +    }
 25.1135 +
 25.1136 +    const char&     operator [] (int index) const 
 25.1137 +    {
 25.1138 +        OVR_ASSERT(((UPInt)index) < GetSize());
 25.1139 +        return pData[index];
 25.1140 +    }
 25.1141 +    const char&     operator [] (UPInt index) const
 25.1142 +    {
 25.1143 +        OVR_ASSERT(index < GetSize());
 25.1144 +        return pData[index];
 25.1145 +    }
 25.1146 +};
 25.1147 +
 25.1148 +
 25.1149 +//
 25.1150 +// Wrapper for string data. The data must have a guaranteed 
 25.1151 +// lifespan throughout the usage of the wrapper. Not intended for 
 25.1152 +// cached usage. Not thread safe.
 25.1153 +//
 25.1154 +class StringDataPtr
 25.1155 +{
 25.1156 +public:
 25.1157 +    StringDataPtr() : pStr(NULL), Size(0) {}
 25.1158 +    StringDataPtr(const StringDataPtr& p)
 25.1159 +        : pStr(p.pStr), Size(p.Size) {}
 25.1160 +    StringDataPtr(const char* pstr, UPInt sz)
 25.1161 +        : pStr(pstr), Size(sz) {}
 25.1162 +    StringDataPtr(const char* pstr)
 25.1163 +        : pStr(pstr), Size((pstr != NULL) ? OVR_strlen(pstr) : 0) {}
 25.1164 +    explicit StringDataPtr(const String& str)
 25.1165 +        : pStr(str.ToCStr()), Size(str.GetSize()) {}
 25.1166 +    template <typename T, int N> 
 25.1167 +    StringDataPtr(const T (&v)[N])
 25.1168 +        : pStr(v), Size(N) {}
 25.1169 +
 25.1170 +public:
 25.1171 +    const char* ToCStr() const { return pStr; }
 25.1172 +    UPInt       GetSize() const { return Size; }
 25.1173 +    bool        IsEmpty() const { return GetSize() == 0; }
 25.1174 +
 25.1175 +    // value is a prefix of this string
 25.1176 +    // Character's values are not compared.
 25.1177 +    bool        IsPrefix(const StringDataPtr& value) const
 25.1178 +    {
 25.1179 +        return ToCStr() == value.ToCStr() && GetSize() >= value.GetSize();
 25.1180 +    }
 25.1181 +    // value is a suffix of this string
 25.1182 +    // Character's values are not compared.
 25.1183 +    bool        IsSuffix(const StringDataPtr& value) const
 25.1184 +    {
 25.1185 +        return ToCStr() <= value.ToCStr() && (End()) == (value.End());
 25.1186 +    }
 25.1187 +
 25.1188 +    // Find first character.
 25.1189 +    // init_ind - initial index.
 25.1190 +    SPInt       FindChar(char c, UPInt init_ind = 0) const 
 25.1191 +    {
 25.1192 +        for (UPInt i = init_ind; i < GetSize(); ++i)
 25.1193 +            if (pStr[i] == c)
 25.1194 +                return static_cast<SPInt>(i);
 25.1195 +
 25.1196 +        return -1; 
 25.1197 +    }
 25.1198 +
 25.1199 +    // Find last character.
 25.1200 +    // init_ind - initial index.
 25.1201 +    SPInt       FindLastChar(char c, UPInt init_ind = ~0) const 
 25.1202 +    {
 25.1203 +        if (init_ind == (UPInt)~0 || init_ind > GetSize())
 25.1204 +            init_ind = GetSize();
 25.1205 +        else
 25.1206 +            ++init_ind;
 25.1207 +
 25.1208 +        for (UPInt i = init_ind; i > 0; --i)
 25.1209 +            if (pStr[i - 1] == c)
 25.1210 +                return static_cast<SPInt>(i - 1);
 25.1211 +
 25.1212 +        return -1; 
 25.1213 +    }
 25.1214 +
 25.1215 +    // Create new object and trim size bytes from the left.
 25.1216 +    StringDataPtr  GetTrimLeft(UPInt size) const
 25.1217 +    {
 25.1218 +        // Limit trim size to the size of the string.
 25.1219 +        size = Alg::PMin(GetSize(), size);
 25.1220 +
 25.1221 +        return StringDataPtr(ToCStr() + size, GetSize() - size);
 25.1222 +    }
 25.1223 +    // Create new object and trim size bytes from the right.
 25.1224 +    StringDataPtr  GetTrimRight(UPInt size) const
 25.1225 +    {
 25.1226 +        // Limit trim to the size of the string.
 25.1227 +        size = Alg::PMin(GetSize(), size);
 25.1228 +
 25.1229 +        return StringDataPtr(ToCStr(), GetSize() - size);
 25.1230 +    }
 25.1231 +
 25.1232 +    // Create new object, which contains next token.
 25.1233 +    // Useful for parsing.
 25.1234 +    StringDataPtr GetNextToken(char separator = ':') const
 25.1235 +    {
 25.1236 +        UPInt cur_pos = 0;
 25.1237 +        const char* cur_str = ToCStr();
 25.1238 +
 25.1239 +        for (; cur_pos < GetSize() && cur_str[cur_pos]; ++cur_pos)
 25.1240 +        {
 25.1241 +            if (cur_str[cur_pos] == separator)
 25.1242 +            {
 25.1243 +                break;
 25.1244 +            }
 25.1245 +        }
 25.1246 +
 25.1247 +        return StringDataPtr(ToCStr(), cur_pos);
 25.1248 +    }
 25.1249 +
 25.1250 +    // Trim size bytes from the left.
 25.1251 +    StringDataPtr& TrimLeft(UPInt size)
 25.1252 +    {
 25.1253 +        // Limit trim size to the size of the string.
 25.1254 +        size = Alg::PMin(GetSize(), size);
 25.1255 +        pStr += size;
 25.1256 +        Size -= size;
 25.1257 +
 25.1258 +        return *this;
 25.1259 +    }
 25.1260 +    // Trim size bytes from the right.
 25.1261 +    StringDataPtr& TrimRight(UPInt size)
 25.1262 +    {
 25.1263 +        // Limit trim to the size of the string.
 25.1264 +        size = Alg::PMin(GetSize(), size);
 25.1265 +        Size -= size;
 25.1266 +
 25.1267 +        return *this;
 25.1268 +    }
 25.1269 +
 25.1270 +    const char* Begin() const { return ToCStr(); }
 25.1271 +    const char* End() const { return ToCStr() + GetSize(); }
 25.1272 +
 25.1273 +    // Hash functor used string data pointers
 25.1274 +    struct HashFunctor
 25.1275 +    {    
 25.1276 +        UPInt operator()(const StringDataPtr& data) const
 25.1277 +        {
 25.1278 +            return String::BernsteinHashFunction(data.ToCStr(), data.GetSize());
 25.1279 +        }        
 25.1280 +    };
 25.1281 +
 25.1282 +    bool operator== (const StringDataPtr& data) const 
 25.1283 +    {
 25.1284 +        return (OVR_strncmp(pStr, data.pStr, data.Size) == 0);
 25.1285 +    }
 25.1286 +
 25.1287 +protected:
 25.1288 +    const char* pStr;
 25.1289 +    UPInt       Size;
 25.1290 +};
 25.1291 +
 25.1292 +} // OVR
 25.1293 +
 25.1294 +#endif
    26.1 --- a/libovr/Src/Kernel/OVR_StringHash.h	Sat Sep 14 17:51:03 2013 +0300
    26.2 +++ b/libovr/Src/Kernel/OVR_StringHash.h	Sun Sep 15 04:10:05 2013 +0300
    26.3 @@ -1,1 +1,89 @@
    26.4 -/************************************************************************************
    26.5 
    26.6 PublicHeader:   None
    26.7 Filename    :   OVR_StringHash.h
    26.8 Content     :   String hash table used when optional case-insensitive
    26.9                 lookup is required.
   26.10 Created     :   September 19, 2012
   26.11 Notes       : 
   26.12 
   26.13 Copyright   :   Copyright 2012 Oculus VR, Inc. All Rights reserved.
   26.14 
   26.15 Use of this software is subject to the terms of the Oculus license
   26.16 agreement provided at the time of installation or download, or which
   26.17 otherwise accompanies this software in either electronic or hard copy form.
   26.18 
   26.19 ************************************************************************************/
   26.20 
   26.21 #ifndef OVR_StringHash_h
   26.22 #define OVR_StringHash_h
   26.23 
   26.24 #include "OVR_String.h"
   26.25 #include "OVR_Hash.h"
   26.26 
   26.27 namespace OVR {
   26.28 
   26.29 //-----------------------------------------------------------------------------------
   26.30 // *** StringHash
   26.31 
   26.32 // This is a custom string hash table that supports case-insensitive
   26.33 // searches through special functions such as GetCaseInsensitive, etc.
   26.34 // This class is used for Flash labels, exports and other case-insensitive tables.
   26.35 
   26.36 template<class U, class Allocator = ContainerAllocator<U> >
   26.37 class StringHash : public Hash<String, U, String::NoCaseHashFunctor, Allocator>
   26.38 {
   26.39 public:
   26.40     typedef U                                                        ValueType;
   26.41     typedef StringHash<U, Allocator>                                 SelfType;
   26.42     typedef Hash<String, U, String::NoCaseHashFunctor, Allocator>    BaseType;
   26.43 
   26.44 public:    
   26.45 
   26.46     void    operator = (const SelfType& src) { BaseType::operator = (src); }
   26.47 
   26.48     bool    GetCaseInsensitive(const String& key, U* pvalue) const
   26.49     {
   26.50         String::NoCaseKey ikey(key);
   26.51         return BaseType::GetAlt(ikey, pvalue);
   26.52     }
   26.53     // Pointer-returning get variety.
   26.54     const U* GetCaseInsensitive(const String& key) const   
   26.55     {
   26.56         String::NoCaseKey ikey(key);
   26.57         return BaseType::GetAlt(ikey);
   26.58     }
   26.59     U*  GetCaseInsensitive(const String& key)
   26.60     {
   26.61         String::NoCaseKey ikey(key);
   26.62         return BaseType::GetAlt(ikey);
   26.63     }
   26.64 
   26.65     
   26.66     typedef typename BaseType::Iterator base_iterator;
   26.67 
   26.68     base_iterator    FindCaseInsensitive(const String& key)
   26.69     {
   26.70         String::NoCaseKey ikey(key);
   26.71         return BaseType::FindAlt(ikey);
   26.72     }
   26.73 
   26.74     // Set just uses a find and assigns value if found. The key is not modified;
   26.75     // this behavior is identical to Flash string variable assignment.    
   26.76     void    SetCaseInsensitive(const String& key, const U& value)
   26.77     {
   26.78         base_iterator it = FindCaseInsensitive(key);
   26.79         if (it != BaseType::End())
   26.80         {
   26.81             it->Second = value;
   26.82         }
   26.83         else
   26.84         {
   26.85             BaseType::Add(key, value);
   26.86         }
   26.87     } 
   26.88 };
   26.89 
   26.90 } // OVR 
   26.91 
   26.92 #endif
   26.93 \ No newline at end of file
   26.94 +/************************************************************************************
   26.95 +
   26.96 +PublicHeader:   None
   26.97 +Filename    :   OVR_StringHash.h
   26.98 +Content     :   String hash table used when optional case-insensitive
   26.99 +                lookup is required.
  26.100 +Created     :   September 19, 2012
  26.101 +Notes       : 
  26.102 +
  26.103 +Copyright   :   Copyright 2012 Oculus VR, Inc. All Rights reserved.
  26.104 +
  26.105 +Use of this software is subject to the terms of the Oculus license
  26.106 +agreement provided at the time of installation or download, or which
  26.107 +otherwise accompanies this software in either electronic or hard copy form.
  26.108 +
  26.109 +************************************************************************************/
  26.110 +
  26.111 +#ifndef OVR_StringHash_h
  26.112 +#define OVR_StringHash_h
  26.113 +
  26.114 +#include "OVR_String.h"
  26.115 +#include "OVR_Hash.h"
  26.116 +
  26.117 +namespace OVR {
  26.118 +
  26.119 +//-----------------------------------------------------------------------------------
  26.120 +// *** StringHash
  26.121 +
  26.122 +// This is a custom string hash table that supports case-insensitive
  26.123 +// searches through special functions such as GetCaseInsensitive, etc.
  26.124 +// This class is used for Flash labels, exports and other case-insensitive tables.
  26.125 +
  26.126 +template<class U, class Allocator = ContainerAllocator<U> >
  26.127 +class StringHash : public Hash<String, U, String::NoCaseHashFunctor, Allocator>
  26.128 +{
  26.129 +public:
  26.130 +    typedef U                                                        ValueType;
  26.131 +    typedef StringHash<U, Allocator>                                 SelfType;
  26.132 +    typedef Hash<String, U, String::NoCaseHashFunctor, Allocator>    BaseType;
  26.133 +
  26.134 +public:    
  26.135 +
  26.136 +    void    operator = (const SelfType& src) { BaseType::operator = (src); }
  26.137 +
  26.138 +    bool    GetCaseInsensitive(const String& key, U* pvalue) const
  26.139 +    {
  26.140 +        String::NoCaseKey ikey(key);
  26.141 +        return BaseType::GetAlt(ikey, pvalue);
  26.142 +    }
  26.143 +    // Pointer-returning get variety.
  26.144 +    const U* GetCaseInsensitive(const String& key) const   
  26.145 +    {
  26.146 +        String::NoCaseKey ikey(key);
  26.147 +        return BaseType::GetAlt(ikey);
  26.148 +    }
  26.149 +    U*  GetCaseInsensitive(const String& key)
  26.150 +    {
  26.151 +        String::NoCaseKey ikey(key);
  26.152 +        return BaseType::GetAlt(ikey);
  26.153 +    }
  26.154 +
  26.155 +    
  26.156 +    typedef typename BaseType::Iterator base_iterator;
  26.157 +
  26.158 +    base_iterator    FindCaseInsensitive(const String& key)
  26.159 +    {
  26.160 +        String::NoCaseKey ikey(key);
  26.161 +        return BaseType::FindAlt(ikey);
  26.162 +    }
  26.163 +
  26.164 +    // Set just uses a find and assigns value if found. The key is not modified;
  26.165 +    // this behavior is identical to Flash string variable assignment.    
  26.166 +    void    SetCaseInsensitive(const String& key, const U& value)
  26.167 +    {
  26.168 +        base_iterator it = FindCaseInsensitive(key);
  26.169 +        if (it != BaseType::End())
  26.170 +        {
  26.171 +            it->Second = value;
  26.172 +        }
  26.173 +        else
  26.174 +        {
  26.175 +            BaseType::Add(key, value);
  26.176 +        }
  26.177 +    } 
  26.178 +};
  26.179 +
  26.180 +} // OVR 
  26.181 +
  26.182 +#endif
    27.1 --- a/libovr/Src/Kernel/OVR_String_FormatUtil.cpp	Sat Sep 14 17:51:03 2013 +0300
    27.2 +++ b/libovr/Src/Kernel/OVR_String_FormatUtil.cpp	Sun Sep 15 04:10:05 2013 +0300
    27.3 @@ -1,1 +1,42 @@
    27.4 -/************************************************************************************
    27.5 
    27.6 Filename    :   OVR_String_FormatUtil.cpp
    27.7 Content     :   String format functions.
    27.8 Created     :   February 27, 2013
    27.9 Notes       : 
   27.10 
   27.11 Copyright   :   Copyright 2013 Oculus VR, Inc. All Rights reserved.
   27.12 
   27.13 Use of this software is subject to the terms of the Oculus license
   27.14 agreement provided at the time of installation or download, or which
   27.15 otherwise accompanies this software in either electronic or hard copy form.
   27.16 
   27.17 ************************************************************************************/
   27.18 
   27.19 #include "OVR_String.h"
   27.20 #include "OVR_Log.h"
   27.21 
   27.22 namespace OVR {
   27.23 
   27.24 void StringBuffer::AppendFormat(const char* format, ...)
   27.25 {       
   27.26     va_list argList;
   27.27 
   27.28     va_start(argList, format);
   27.29     UPInt size = OVR_vscprintf(format, argList);
   27.30     va_end(argList);
   27.31 
   27.32     char* buffer = (char*) OVR_ALLOC(sizeof(char) * (size+1));
   27.33 
   27.34     va_start(argList, format);
   27.35     UPInt result = OVR_vsprintf(buffer, size+1, format, argList);
   27.36     OVR_UNUSED1(result);
   27.37     va_end(argList);
   27.38     OVR_ASSERT_LOG(result == size, ("Error in OVR_vsprintf"));
   27.39 
   27.40     AppendString(buffer);
   27.41 
   27.42     OVR_FREE(buffer);
   27.43 }
   27.44 
   27.45 } // OVR
   27.46 \ No newline at end of file
   27.47 +/************************************************************************************
   27.48 +
   27.49 +Filename    :   OVR_String_FormatUtil.cpp
   27.50 +Content     :   String format functions.
   27.51 +Created     :   February 27, 2013
   27.52 +Notes       : 
   27.53 +
   27.54 +Copyright   :   Copyright 2013 Oculus VR, Inc. All Rights reserved.
   27.55 +
   27.56 +Use of this software is subject to the terms of the Oculus license
   27.57 +agreement provided at the time of installation or download, or which
   27.58 +otherwise accompanies this software in either electronic or hard copy form.
   27.59 +
   27.60 +************************************************************************************/
   27.61 +
   27.62 +#include "OVR_String.h"
   27.63 +#include "OVR_Log.h"
   27.64 +
   27.65 +namespace OVR {
   27.66 +
   27.67 +void StringBuffer::AppendFormat(const char* format, ...)
   27.68 +{       
   27.69 +    va_list argList;
   27.70 +
   27.71 +    va_start(argList, format);
   27.72 +    UPInt size = OVR_vscprintf(format, argList);
   27.73 +    va_end(argList);
   27.74 +
   27.75 +    char* buffer = (char*) OVR_ALLOC(sizeof(char) * (size+1));
   27.76 +
   27.77 +    va_start(argList, format);
   27.78 +    UPInt result = OVR_vsprintf(buffer, size+1, format, argList);
   27.79 +    OVR_UNUSED1(result);
   27.80 +    va_end(argList);
   27.81 +    OVR_ASSERT_LOG(result == size, ("Error in OVR_vsprintf"));
   27.82 +
   27.83 +    AppendString(buffer);
   27.84 +
   27.85 +    OVR_FREE(buffer);
   27.86 +}
   27.87 +
   27.88 +} // OVR
    28.1 --- a/libovr/Src/Kernel/OVR_String_PathUtil.cpp	Sat Sep 14 17:51:03 2013 +0300
    28.2 +++ b/libovr/Src/Kernel/OVR_String_PathUtil.cpp	Sun Sep 15 04:10:05 2013 +0300
    28.3 @@ -1,1 +1,200 @@
    28.4 -/************************************************************************************
    28.5 
    28.6 Filename    :   OVR_String_PathUtil.cpp
    28.7 Content     :   String filename/url helper function
    28.8 Created     :   September 19, 2012
    28.9 Notes       : 
   28.10 
   28.11 Copyright   :   Copyright 2012 Oculus VR, Inc. All Rights reserved.
   28.12 
   28.13 Use of this software is subject to the terms of the Oculus license
   28.14 agreement provided at the time of installation or download, or which
   28.15 otherwise accompanies this software in either electronic or hard copy form.
   28.16 
   28.17 ************************************************************************************/
   28.18 
   28.19 #include "OVR_String.h"
   28.20 #include "OVR_UTF8Util.h"
   28.21 
   28.22 namespace OVR {
   28.23 
   28.24 //--------------------------------------------------------------------
   28.25 // ***** Path-Scanner helper function 
   28.26 
   28.27 // Scans file path finding filename start and extension start, fills in their addess.
   28.28 void ScanFilePath(const char* url, const char** pfilename, const char** pext)
   28.29 { 
   28.30     const char* urlStart = url;
   28.31     const char *filename = 0;
   28.32     const char *lastDot = 0;
   28.33 
   28.34     UInt32 charVal = UTF8Util::DecodeNextChar(&url);
   28.35 
   28.36     while (charVal != 0)
   28.37     {
   28.38         if ((charVal == '/') || (charVal == '\\'))
   28.39         {
   28.40             filename = url;
   28.41             lastDot  = 0;
   28.42         }
   28.43         else if (charVal == '.')
   28.44         {
   28.45             lastDot = url - 1;
   28.46         }
   28.47         
   28.48         charVal = UTF8Util::DecodeNextChar(&url);
   28.49     }
   28.50 
   28.51     if (pfilename)
   28.52     {
   28.53         // It was a naked filename
   28.54         if (urlStart && (*urlStart != '.') && *urlStart)
   28.55             *pfilename = urlStart;
   28.56         else
   28.57             *pfilename = filename;
   28.58     }
   28.59 
   28.60     if (pext)
   28.61     {
   28.62         *pext = lastDot;
   28.63     }
   28.64 }
   28.65 
   28.66 // Scans till the end of protocol. Returns first character past protocol,
   28.67 // 0 if not found.
   28.68 //  - protocol: 'file://', 'http://'
   28.69 const char* ScanPathProtocol(const char* url)
   28.70 {    
   28.71     UInt32 charVal = UTF8Util::DecodeNextChar(&url);
   28.72     UInt32 charVal2;
   28.73    
   28.74     while (charVal != 0)
   28.75     {
   28.76         // Treat a colon followed by a slash as absolute.
   28.77         if (charVal == ':')
   28.78         {
   28.79             charVal2 = UTF8Util::DecodeNextChar(&url);
   28.80             charVal  = UTF8Util::DecodeNextChar(&url);
   28.81             if ((charVal == '/') && (charVal2 == '\\'))
   28.82                 return url;
   28.83         }
   28.84         charVal = UTF8Util::DecodeNextChar(&url);
   28.85     }
   28.86     return 0;
   28.87 }
   28.88 
   28.89 
   28.90 //--------------------------------------------------------------------
   28.91 // ***** String Path API implementation
   28.92 
   28.93 bool String::HasAbsolutePath(const char* url)
   28.94 {
   28.95     // Absolute paths can star with:
   28.96     //  - protocols:        'file://', 'http://'
   28.97     //  - windows drive:    'c:\'
   28.98     //  - UNC share name:   '\\share'
   28.99     //  - unix root         '/'
  28.100 
  28.101     // On the other hand, relative paths are:
  28.102     //  - directory:        'directory/file'
  28.103     //  - this directory:   './file'
  28.104     //  - parent directory: '../file'
  28.105     // 
  28.106     // For now, we don't parse '.' or '..' out, but instead let it be concatenated
  28.107     // to string and let the OS figure it out. This, however, is not good for file
  28.108     // name matching in library/etc, so it should be improved.
  28.109 
  28.110     if (!url || !*url)
  28.111         return true; // Treat empty strings as absolute.    
  28.112 
  28.113     UInt32 charVal = UTF8Util::DecodeNextChar(&url);
  28.114 
  28.115     // Fist character of '/' or '\\' means absolute url.
  28.116     if ((charVal == '/') || (charVal == '\\'))
  28.117         return true;
  28.118 
  28.119     while (charVal != 0)
  28.120     {
  28.121         // Treat a colon followed by a slash as absolute.
  28.122         if (charVal == ':')
  28.123         {
  28.124             charVal = UTF8Util::DecodeNextChar(&url);
  28.125             // Protocol or windows drive. Absolute.
  28.126             if ((charVal == '/') || (charVal == '\\'))
  28.127                 return true;
  28.128         }
  28.129         else if ((charVal == '/') || (charVal == '\\'))
  28.130         {
  28.131             // Not a first character (else 'if' above the loop would have caught it).
  28.132             // Must be a relative url.
  28.133             break;
  28.134         }
  28.135 
  28.136         charVal = UTF8Util::DecodeNextChar(&url);
  28.137     }
  28.138 
  28.139     // We get here for relative paths.
  28.140     return false;    
  28.141 }
  28.142 
  28.143 
  28.144 bool String::HasExtension(const char* path)
  28.145 {
  28.146     const char* ext = 0;
  28.147     ScanFilePath(path, 0, &ext);
  28.148     return ext != 0;
  28.149 }
  28.150 bool String::HasProtocol(const char* path)
  28.151 {
  28.152     return ScanPathProtocol(path) != 0;
  28.153 }
  28.154 
  28.155 
  28.156 String  String::GetPath() const
  28.157 {
  28.158     const char* filename = 0;
  28.159     ScanFilePath(ToCStr(), &filename, 0);
  28.160 
  28.161     // Technically we can have extra logic somewhere for paths,
  28.162     // such as enforcing protocol and '/' only based on flags,
  28.163     // but we keep it simple for now.
  28.164     return String(ToCStr(), filename ? (filename-ToCStr()) : GetSize());
  28.165 }
  28.166 
  28.167 String  String::GetProtocol() const
  28.168 {
  28.169     const char* protocolEnd = ScanPathProtocol(ToCStr());
  28.170     return String(ToCStr(), protocolEnd ? (protocolEnd-ToCStr()) : 0);
  28.171 }
  28.172 
  28.173 String  String::GetFilename() const
  28.174 {
  28.175     const char* filename = 0;
  28.176     ScanFilePath(ToCStr(), &filename, 0);
  28.177     return String(filename);
  28.178 }
  28.179 String  String::GetExtension() const
  28.180 {
  28.181     const char* ext = 0;
  28.182     ScanFilePath(ToCStr(), 0, &ext);
  28.183     return String(ext);
  28.184 }
  28.185 
  28.186 void    String::StripExtension()
  28.187 {
  28.188     const char* ext = 0;
  28.189     ScanFilePath(ToCStr(), 0, &ext);    
  28.190     if (ext)
  28.191     {
  28.192         *this = String(ToCStr(), ext-ToCStr());
  28.193     }
  28.194 }
  28.195 
  28.196 void    String::StripProtocol()
  28.197 {
  28.198     const char* protocol = ScanPathProtocol(ToCStr());
  28.199     if (protocol)
  28.200         AssignString(protocol, OVR_strlen(protocol));
  28.201 }
  28.202 
  28.203 } // OVR
  28.204 \ No newline at end of file
  28.205 +/************************************************************************************
  28.206 +
  28.207 +Filename    :   OVR_String_PathUtil.cpp
  28.208 +Content     :   String filename/url helper function
  28.209 +Created     :   September 19, 2012
  28.210 +Notes       : 
  28.211 +
  28.212 +Copyright   :   Copyright 2012 Oculus VR, Inc. All Rights reserved.
  28.213 +
  28.214 +Use of this software is subject to the terms of the Oculus license
  28.215 +agreement provided at the time of installation or download, or which
  28.216 +otherwise accompanies this software in either electronic or hard copy form.
  28.217 +
  28.218 +************************************************************************************/
  28.219 +
  28.220 +#include "OVR_String.h"
  28.221 +#include "OVR_UTF8Util.h"
  28.222 +
  28.223 +namespace OVR {
  28.224 +
  28.225 +//--------------------------------------------------------------------
  28.226 +// ***** Path-Scanner helper function 
  28.227 +
  28.228 +// Scans file path finding filename start and extension start, fills in their addess.
  28.229 +void ScanFilePath(const char* url, const char** pfilename, const char** pext)
  28.230 +{ 
  28.231 +    const char* urlStart = url;
  28.232 +    const char *filename = 0;
  28.233 +    const char *lastDot = 0;
  28.234 +
  28.235 +    UInt32 charVal = UTF8Util::DecodeNextChar(&url);
  28.236 +
  28.237 +    while (charVal != 0)
  28.238 +    {
  28.239 +        if ((charVal == '/') || (charVal == '\\'))
  28.240 +        {
  28.241 +            filename = url;
  28.242 +            lastDot  = 0;
  28.243 +        }
  28.244 +        else if (charVal == '.')
  28.245 +        {
  28.246 +            lastDot = url - 1;
  28.247 +        }
  28.248 +        
  28.249 +        charVal = UTF8Util::DecodeNextChar(&url);
  28.250 +    }
  28.251 +
  28.252 +    if (pfilename)
  28.253 +    {
  28.254 +        // It was a naked filename
  28.255 +        if (urlStart && (*urlStart != '.') && *urlStart)
  28.256 +            *pfilename = urlStart;
  28.257 +        else
  28.258 +            *pfilename = filename;
  28.259 +    }
  28.260 +
  28.261 +    if (pext)
  28.262 +    {
  28.263 +        *pext = lastDot;
  28.264 +    }
  28.265 +}
  28.266 +
  28.267 +// Scans till the end of protocol. Returns first character past protocol,
  28.268 +// 0 if not found.
  28.269 +//  - protocol: 'file://', 'http://'
  28.270 +const char* ScanPathProtocol(const char* url)
  28.271 +{    
  28.272 +    UInt32 charVal = UTF8Util::DecodeNextChar(&url);
  28.273 +    UInt32 charVal2;
  28.274 +   
  28.275 +    while (charVal != 0)
  28.276 +    {
  28.277 +        // Treat a colon followed by a slash as absolute.
  28.278 +        if (charVal == ':')
  28.279 +        {
  28.280 +            charVal2 = UTF8Util::DecodeNextChar(&url);
  28.281 +            charVal  = UTF8Util::DecodeNextChar(&url);
  28.282 +            if ((charVal == '/') && (charVal2 == '\\'))
  28.283 +                return url;
  28.284 +        }
  28.285 +        charVal = UTF8Util::DecodeNextChar(&url);
  28.286 +    }
  28.287 +    return 0;
  28.288 +}
  28.289 +
  28.290 +
  28.291 +//--------------------------------------------------------------------
  28.292 +// ***** String Path API implementation
  28.293 +
  28.294 +bool String::HasAbsolutePath(const char* url)
  28.295 +{
  28.296 +    // Absolute paths can star with:
  28.297 +    //  - protocols:        'file://', 'http://'
  28.298 +    //  - windows drive:    'c:\'
  28.299 +    //  - UNC share name:   '\\share'
  28.300 +    //  - unix root         '/'
  28.301 +
  28.302 +    // On the other hand, relative paths are:
  28.303 +    //  - directory:        'directory/file'
  28.304 +    //  - this directory:   './file'
  28.305 +    //  - parent directory: '../file'
  28.306 +    // 
  28.307 +    // For now, we don't parse '.' or '..' out, but instead let it be concatenated
  28.308 +    // to string and let the OS figure it out. This, however, is not good for file
  28.309 +    // name matching in library/etc, so it should be improved.
  28.310 +
  28.311 +    if (!url || !*url)
  28.312 +        return true; // Treat empty strings as absolute.    
  28.313 +
  28.314 +    UInt32 charVal = UTF8Util::DecodeNextChar(&url);
  28.315 +
  28.316 +    // Fist character of '/' or '\\' means absolute url.
  28.317 +    if ((charVal == '/') || (charVal == '\\'))
  28.318 +        return true;
  28.319 +
  28.320 +    while (charVal != 0)
  28.321 +    {
  28.322 +        // Treat a colon followed by a slash as absolute.
  28.323 +        if (charVal == ':')
  28.324 +        {
  28.325 +            charVal = UTF8Util::DecodeNextChar(&url);
  28.326 +            // Protocol or windows drive. Absolute.
  28.327 +            if ((charVal == '/') || (charVal == '\\'))
  28.328 +                return true;
  28.329 +        }
  28.330 +        else if ((charVal == '/') || (charVal == '\\'))
  28.331 +        {
  28.332 +            // Not a first character (else 'if' above the loop would have caught it).
  28.333 +            // Must be a relative url.
  28.334 +            break;
  28.335 +        }
  28.336 +
  28.337 +        charVal = UTF8Util::DecodeNextChar(&url);
  28.338 +    }
  28.339 +
  28.340 +    // We get here for relative paths.
  28.341 +    return false;    
  28.342 +}
  28.343 +
  28.344 +
  28.345 +bool String::HasExtension(const char* path)
  28.346 +{
  28.347 +    const char* ext = 0;
  28.348 +    ScanFilePath(path, 0, &ext);
  28.349 +    return ext != 0;
  28.350 +}
  28.351 +bool String::HasProtocol(const char* path)
  28.352 +{
  28.353 +    return ScanPathProtocol(path) != 0;
  28.354 +}
  28.355 +
  28.356 +
  28.357 +String  String::GetPath() const
  28.358 +{
  28.359 +    const char* filename = 0;
  28.360 +    ScanFilePath(ToCStr(), &filename, 0);
  28.361 +
  28.362 +    // Technically we can have extra logic somewhere for paths,
  28.363 +    // such as enforcing protocol and '/' only based on flags,
  28.364 +    // but we keep it simple for now.
  28.365 +    return String(ToCStr(), filename ? (filename-ToCStr()) : GetSize());
  28.366 +}
  28.367 +
  28.368 +String  String::GetProtocol() const
  28.369 +{
  28.370 +    const char* protocolEnd = ScanPathProtocol(ToCStr());
  28.371 +    return String(ToCStr(), protocolEnd ? (protocolEnd-ToCStr()) : 0);
  28.372 +}
  28.373 +
  28.374 +String  String::GetFilename() const
  28.375 +{
  28.376 +    const char* filename = 0;
  28.377 +    ScanFilePath(ToCStr(), &filename, 0);
  28.378 +    return String(filename);
  28.379 +}
  28.380 +String  String::GetExtension() const
  28.381 +{
  28.382 +    const char* ext = 0;
  28.383 +    ScanFilePath(ToCStr(), 0, &ext);
  28.384 +    return String(ext);
  28.385 +}
  28.386 +
  28.387 +void    String::StripExtension()
  28.388 +{
  28.389 +    const char* ext = 0;
  28.390 +    ScanFilePath(ToCStr(), 0, &ext);    
  28.391 +    if (ext)
  28.392 +    {
  28.393 +        *this = String(ToCStr(), ext-ToCStr());
  28.394 +    }
  28.395 +}
  28.396 +
  28.397 +void    String::StripProtocol()
  28.398 +{
  28.399 +    const char* protocol = ScanPathProtocol(ToCStr());
  28.400 +    if (protocol)
  28.401 +        AssignString(protocol, OVR_strlen(protocol));
  28.402 +}
  28.403 +
  28.404 +} // OVR
    29.1 --- a/libovr/Src/Kernel/OVR_SysFile.cpp	Sat Sep 14 17:51:03 2013 +0300
    29.2 +++ b/libovr/Src/Kernel/OVR_SysFile.cpp	Sun Sep 15 04:10:05 2013 +0300
    29.3 @@ -1,1 +1,125 @@
    29.4 -/**************************************************************************
    29.5 
    29.6 Filename    :   OVR_SysFile.cpp
    29.7 Content     :   File wrapper class implementation (Win32)
    29.8 
    29.9 Created     :   April 5, 1999
   29.10 Authors     :   Michael Antonov
   29.11 
   29.12 Copyright   :   Copyright 2011 Oculus VR, Inc. All Rights reserved.
   29.13 
   29.14 Use of this software is subject to the terms of the Oculus license
   29.15 agreement provided at the time of installation or download, or which
   29.16 otherwise accompanies this software in either electronic or hard copy form.
   29.17 
   29.18 **************************************************************************/
   29.19 
   29.20 #define  GFILE_CXX
   29.21 
   29.22 // Standard C library (Captain Obvious guarantees!)
   29.23 #include <stdio.h>
   29.24 
   29.25 #include "OVR_SysFile.h"
   29.26 
   29.27 namespace OVR {
   29.28 
   29.29 // This is - a dummy file that fails on all calls.
   29.30 
   29.31 class UnopenedFile : public File
   29.32 {
   29.33 public:
   29.34     UnopenedFile()  { }
   29.35     ~UnopenedFile() { }
   29.36 
   29.37     virtual const char* GetFilePath()               { return 0; }
   29.38 
   29.39     // ** File Information
   29.40     virtual bool        IsValid()                   { return 0; }
   29.41     virtual bool        IsWritable()                { return 0; }
   29.42 
   29.43     // Return position / file size
   29.44     virtual int         Tell()                      { return 0; }
   29.45     virtual SInt64      LTell()                     { return 0; }
   29.46     virtual int         GetLength()                 { return 0; }
   29.47     virtual SInt64      LGetLength()                { return 0; }
   29.48 
   29.49 //  virtual bool        Stat(FileStats *pfs)        { return 0; }
   29.50     virtual int         GetErrorCode()              { return Error_FileNotFound; }
   29.51 
   29.52     // ** Stream implementation & I/O
   29.53     virtual int         Write(const UByte *pbuffer, int numBytes)     { return -1; OVR_UNUSED2(pbuffer, numBytes); }
   29.54     virtual int         Read(UByte *pbuffer, int numBytes)            { return -1; OVR_UNUSED2(pbuffer, numBytes); }
   29.55     virtual int         SkipBytes(int numBytes)                       { return 0;  OVR_UNUSED(numBytes); }
   29.56     virtual int         BytesAvailable()                              { return 0; }
   29.57     virtual bool        Flush()                                       { return 0; }
   29.58     virtual int         Seek(int offset, int origin)                  { return -1; OVR_UNUSED2(offset, origin); }
   29.59     virtual SInt64      LSeek(SInt64 offset, int origin)              { return -1; OVR_UNUSED2(offset, origin); }
   29.60     
   29.61     virtual int         CopyFromStream(File *pstream, int byteSize)   { return -1; OVR_UNUSED2(pstream, byteSize); }
   29.62     virtual bool        Close()                                       { return 0; }    
   29.63 };
   29.64 
   29.65 
   29.66 
   29.67 // ***** System File
   29.68 
   29.69 // System file is created to access objects on file system directly
   29.70 // This file can refer directly to path
   29.71 
   29.72 // ** Constructor
   29.73 SysFile::SysFile() : DelegatedFile(0)
   29.74 {
   29.75     pFile = *new UnopenedFile;
   29.76 }
   29.77 
   29.78 File* FileFILEOpen(const String& path, int flags, int mode);
   29.79 
   29.80 // Opens a file
   29.81 SysFile::SysFile(const String& path, int flags, int mode) : DelegatedFile(0)
   29.82 {
   29.83     Open(path, flags, mode);
   29.84 }
   29.85 
   29.86 
   29.87 // ** Open & management
   29.88 // Will fail if file's already open
   29.89 bool SysFile::Open(const String& path, int flags, int mode)
   29.90 {
   29.91     pFile = *FileFILEOpen(path, flags, mode);
   29.92     if ((!pFile) || (!pFile->IsValid()))
   29.93     {
   29.94         pFile = *new UnopenedFile;
   29.95         return 0;
   29.96     }
   29.97     //pFile = *OVR_NEW DelegatedFile(pFile); // MA Testing
   29.98     if (flags & Open_Buffered)
   29.99         pFile = *new BufferedFile(pFile);
  29.100     return 1;
  29.101 }
  29.102 
  29.103 
  29.104 // ** Overrides
  29.105 
  29.106 int SysFile::GetErrorCode()
  29.107 {
  29.108     return pFile ? pFile->GetErrorCode() : Error_FileNotFound;
  29.109 }
  29.110 
  29.111 
  29.112 // Overrides to provide re-open support
  29.113 bool SysFile::IsValid()
  29.114 {
  29.115     return pFile && pFile->IsValid();
  29.116 }
  29.117 bool SysFile::Close()
  29.118 {
  29.119     if (IsValid())
  29.120     {
  29.121         DelegatedFile::Close();
  29.122         pFile = *new UnopenedFile;
  29.123         return 1;
  29.124     }
  29.125     return 0;
  29.126 }
  29.127 
  29.128 } // OVR
  29.129 \ No newline at end of file
  29.130 +/**************************************************************************
  29.131 +
  29.132 +Filename    :   OVR_SysFile.cpp
  29.133 +Content     :   File wrapper class implementation (Win32)
  29.134 +
  29.135 +Created     :   April 5, 1999
  29.136 +Authors     :   Michael Antonov
  29.137 +
  29.138 +Copyright   :   Copyright 2011 Oculus VR, Inc. All Rights reserved.
  29.139 +
  29.140 +Use of this software is subject to the terms of the Oculus license
  29.141 +agreement provided at the time of installation or download, or which
  29.142 +otherwise accompanies this software in either electronic or hard copy form.
  29.143 +
  29.144 +**************************************************************************/
  29.145 +
  29.146 +#define  GFILE_CXX
  29.147 +
  29.148 +// Standard C library (Captain Obvious guarantees!)
  29.149 +#include <stdio.h>
  29.150 +
  29.151 +#include "OVR_SysFile.h"
  29.152 +
  29.153 +namespace OVR {
  29.154 +
  29.155 +// This is - a dummy file that fails on all calls.
  29.156 +
  29.157 +class UnopenedFile : public File
  29.158 +{
  29.159 +public:
  29.160 +    UnopenedFile()  { }
  29.161 +    ~UnopenedFile() { }
  29.162 +
  29.163 +    virtual const char* GetFilePath()               { return 0; }
  29.164 +
  29.165 +    // ** File Information
  29.166 +    virtual bool        IsValid()                   { return 0; }
  29.167 +    virtual bool        IsWritable()                { return 0; }
  29.168 +
  29.169 +    // Return position / file size
  29.170 +    virtual int         Tell()                      { return 0; }
  29.171 +    virtual SInt64      LTell()                     { return 0; }
  29.172 +    virtual int         GetLength()                 { return 0; }
  29.173 +    virtual SInt64      LGetLength()                { return 0; }
  29.174 +
  29.175 +//  virtual bool        Stat(FileStats *pfs)        { return 0; }
  29.176 +    virtual int         GetErrorCode()              { return Error_FileNotFound; }
  29.177 +
  29.178 +    // ** Stream implementation & I/O
  29.179 +    virtual int         Write(const UByte *pbuffer, int numBytes)     { return -1; OVR_UNUSED2(pbuffer, numBytes); }
  29.180 +    virtual int         Read(UByte *pbuffer, int numBytes)            { return -1; OVR_UNUSED2(pbuffer, numBytes); }
  29.181 +    virtual int         SkipBytes(int numBytes)                       { return 0;  OVR_UNUSED(numBytes); }
  29.182 +    virtual int         BytesAvailable()                              { return 0; }
  29.183 +    virtual bool        Flush()                                       { return 0; }
  29.184 +    virtual int         Seek(int offset, int origin)                  { return -1; OVR_UNUSED2(offset, origin); }
  29.185 +    virtual SInt64      LSeek(SInt64 offset, int origin)              { return -1; OVR_UNUSED2(offset, origin); }
  29.186 +    
  29.187 +    virtual int         CopyFromStream(File *pstream, int byteSize)   { return -1; OVR_UNUSED2(pstream, byteSize); }
  29.188 +    virtual bool        Close()                                       { return 0; }    
  29.189 +};
  29.190 +
  29.191 +
  29.192 +
  29.193 +// ***** System File
  29.194 +
  29.195 +// System file is created to access objects on file system directly
  29.196 +// This file can refer directly to path
  29.197 +
  29.198 +// ** Constructor
  29.199 +SysFile::SysFile() : DelegatedFile(0)
  29.200 +{
  29.201 +    pFile = *new UnopenedFile;
  29.202 +}
  29.203 +
  29.204 +File* FileFILEOpen(const String& path, int flags, int mode);
  29.205 +
  29.206 +// Opens a file
  29.207 +SysFile::SysFile(const String& path, int flags, int mode) : DelegatedFile(0)
  29.208 +{
  29.209 +    Open(path, flags, mode);
  29.210 +}
  29.211 +
  29.212 +
  29.213 +// ** Open & management
  29.214 +// Will fail if file's already open
  29.215 +bool SysFile::Open(const String& path, int flags, int mode)
  29.216 +{
  29.217 +    pFile = *FileFILEOpen(path, flags, mode);
  29.218 +    if ((!pFile) || (!pFile->IsValid()))
  29.219 +    {
  29.220 +        pFile = *new UnopenedFile;
  29.221 +        return 0;
  29.222 +    }
  29.223 +    //pFile = *OVR_NEW DelegatedFile(pFile); // MA Testing
  29.224 +    if (flags & Open_Buffered)
  29.225 +        pFile = *new BufferedFile(pFile);
  29.226 +    return 1;
  29.227 +}
  29.228 +
  29.229 +
  29.230 +// ** Overrides
  29.231 +
  29.232 +int SysFile::GetErrorCode()
  29.233 +{
  29.234 +    return pFile ? pFile->GetErrorCode() : Error_FileNotFound;
  29.235 +}
  29.236 +
  29.237 +
  29.238 +// Overrides to provide re-open support
  29.239 +bool SysFile::IsValid()
  29.240 +{
  29.241 +    return pFile && pFile->IsValid();
  29.242 +}
  29.243 +bool SysFile::Close()
  29.244 +{
  29.245 +    if (IsValid())
  29.246 +    {
  29.247 +        DelegatedFile::Close();
  29.248 +        pFile = *new UnopenedFile;
  29.249 +        return 1;
  29.250 +    }
  29.251 +    return 0;
  29.252 +}
  29.253 +
  29.254 +} // OVR
    30.1 --- a/libovr/Src/Kernel/OVR_SysFile.h	Sat Sep 14 17:51:03 2013 +0300
    30.2 +++ b/libovr/Src/Kernel/OVR_SysFile.h	Sun Sep 15 04:10:05 2013 +0300
    30.3 @@ -1,1 +1,93 @@
    30.4 -/************************************************************************************
    30.5 
    30.6 PublicHeader:   Kernel
    30.7 Filename    :   OVR_SysFile.h
    30.8 Content     :   Header for all internal file management - functions and structures
    30.9                 to be inherited by OS specific subclasses.
   30.10 Created     :   September 19, 2012
   30.11 Notes       : 
   30.12 
   30.13 Notes       :   errno may not be preserved across use of GBaseFile member functions
   30.14             :   Directories cannot be deleted while files opened from them are in use
   30.15                 (For the GetFullName function)
   30.16 
   30.17 Copyright   :   Copyright 2012 Oculus VR, Inc. All Rights reserved.
   30.18 
   30.19 Use of this software is subject to the terms of the Oculus license
   30.20 agreement provided at the time of installation or download, or which
   30.21 otherwise accompanies this software in either electronic or hard copy form.
   30.22 
   30.23 ************************************************************************************/
   30.24 
   30.25 #ifndef OVR_SysFile_h
   30.26 #define OVR_SysFile_h
   30.27 
   30.28 #include "OVR_File.h"
   30.29 
   30.30 namespace OVR {
   30.31 
   30.32 // ***** Declared classes
   30.33 class   SysFile;
   30.34 
   30.35 //-----------------------------------------------------------------------------------
   30.36 // *** File Statistics
   30.37 
   30.38 // This class contents are similar to _stat, providing
   30.39 // creation, modify and other information about the file.
   30.40 struct FileStat
   30.41 {
   30.42     // No change or create time because they are not available on most systems
   30.43     SInt64  ModifyTime;
   30.44     SInt64  AccessTime;
   30.45     SInt64  FileSize;
   30.46 
   30.47     bool operator== (const FileStat& stat) const
   30.48     {
   30.49         return ( (ModifyTime == stat.ModifyTime) &&
   30.50                  (AccessTime == stat.AccessTime) &&
   30.51                  (FileSize == stat.FileSize) );
   30.52     }
   30.53 };
   30.54 
   30.55 //-----------------------------------------------------------------------------------
   30.56 // *** System File
   30.57 
   30.58 // System file is created to access objects on file system directly
   30.59 // This file can refer directly to path.
   30.60 // System file can be open & closed several times; however, such use is not recommended
   30.61 // This class is realy a wrapper around an implementation of File interface for a 
   30.62 // particular platform.
   30.63 
   30.64 class SysFile : public DelegatedFile
   30.65 {
   30.66 protected:
   30.67   SysFile(const SysFile &source) : DelegatedFile () { OVR_UNUSED(source); }
   30.68 public:
   30.69 
   30.70     // ** Constructor
   30.71     SysFile();
   30.72     // Opens a file
   30.73     SysFile(const String& path, int flags = Open_Read|Open_Buffered, int mode = Mode_ReadWrite); 
   30.74 
   30.75     // ** Open & management 
   30.76     bool  Open(const String& path, int flags = Open_Read|Open_Buffered, int mode = Mode_ReadWrite);
   30.77         
   30.78     OVR_FORCE_INLINE bool  Create(const String& path, int mode = Mode_ReadWrite)
   30.79     { return Open(path, Open_ReadWrite|Open_Create, mode); }
   30.80 
   30.81     // Helper function: obtain file statistics information. In GFx, this is used to detect file changes.
   30.82     // Return 0 if function failed, most likely because the file doesn't exist.
   30.83     static bool OVR_CDECL GetFileStat(FileStat* pfileStats, const String& path);
   30.84     
   30.85     // ** Overrides
   30.86     // Overridden to provide re-open support
   30.87     virtual int   GetErrorCode();
   30.88 
   30.89     virtual bool  IsValid();
   30.90 
   30.91     virtual bool  Close();    
   30.92 };
   30.93 
   30.94 } // Scaleform
   30.95 
   30.96 #endif
   30.97 \ No newline at end of file
   30.98 +/************************************************************************************
   30.99 +
  30.100 +PublicHeader:   Kernel
  30.101 +Filename    :   OVR_SysFile.h
  30.102 +Content     :   Header for all internal file management - functions and structures
  30.103 +                to be inherited by OS specific subclasses.
  30.104 +Created     :   September 19, 2012
  30.105 +Notes       : 
  30.106 +
  30.107 +Notes       :   errno may not be preserved across use of GBaseFile member functions
  30.108 +            :   Directories cannot be deleted while files opened from them are in use
  30.109 +                (For the GetFullName function)
  30.110 +
  30.111 +Copyright   :   Copyright 2012 Oculus VR, Inc. All Rights reserved.
  30.112 +
  30.113 +Use of this software is subject to the terms of the Oculus license
  30.114 +agreement provided at the time of installation or download, or which
  30.115 +otherwise accompanies this software in either electronic or hard copy form.
  30.116 +
  30.117 +************************************************************************************/
  30.118 +
  30.119 +#ifndef OVR_SysFile_h
  30.120 +#define OVR_SysFile_h
  30.121 +
  30.122 +#include "OVR_File.h"
  30.123 +
  30.124 +namespace OVR {
  30.125 +
  30.126 +// ***** Declared classes
  30.127 +class   SysFile;
  30.128 +
  30.129 +//-----------------------------------------------------------------------------------
  30.130 +// *** File Statistics
  30.131 +
  30.132 +// This class contents are similar to _stat, providing
  30.133 +// creation, modify and other information about the file.
  30.134 +struct FileStat
  30.135 +{
  30.136 +    // No change or create time because they are not available on most systems
  30.137 +    SInt64  ModifyTime;
  30.138 +    SInt64  AccessTime;
  30.139 +    SInt64  FileSize;
  30.140 +
  30.141 +    bool operator== (const FileStat& stat) const
  30.142 +    {
  30.143 +        return ( (ModifyTime == stat.ModifyTime) &&
  30.144 +                 (AccessTime == stat.AccessTime) &&
  30.145 +                 (FileSize == stat.FileSize) );
  30.146 +    }
  30.147 +};
  30.148 +
  30.149 +//-----------------------------------------------------------------------------------
  30.150 +// *** System File
  30.151 +
  30.152 +// System file is created to access objects on file system directly
  30.153 +// This file can refer directly to path.
  30.154 +// System file can be open & closed several times; however, such use is not recommended
  30.155 +// This class is realy a wrapper around an implementation of File interface for a 
  30.156 +// particular platform.
  30.157 +
  30.158 +class SysFile : public DelegatedFile
  30.159 +{
  30.160 +protected:
  30.161 +  SysFile(const SysFile &source) : DelegatedFile () { OVR_UNUSED(source); }
  30.162 +public:
  30.163 +
  30.164 +    // ** Constructor
  30.165 +    SysFile();
  30.166 +    // Opens a file
  30.167 +    SysFile(const String& path, int flags = Open_Read|Open_Buffered, int mode = Mode_ReadWrite); 
  30.168 +
  30.169 +    // ** Open & management 
  30.170 +    bool  Open(const String& path, int flags = Open_Read|Open_Buffered, int mode = Mode_ReadWrite);
  30.171 +        
  30.172 +    OVR_FORCE_INLINE bool  Create(const String& path, int mode = Mode_ReadWrite)
  30.173 +    { return Open(path, Open_ReadWrite|Open_Create, mode); }
  30.174 +
  30.175 +    // Helper function: obtain file statistics information. In GFx, this is used to detect file changes.
  30.176 +    // Return 0 if function failed, most likely because the file doesn't exist.
  30.177 +    static bool OVR_CDECL GetFileStat(FileStat* pfileStats, const String& path);
  30.178 +    
  30.179 +    // ** Overrides
  30.180 +    // Overridden to provide re-open support
  30.181 +    virtual int   GetErrorCode();
  30.182 +
  30.183 +    virtual bool  IsValid();
  30.184 +
  30.185 +    virtual bool  Close();    
  30.186 +};
  30.187 +
  30.188 +} // Scaleform
  30.189 +
  30.190 +#endif
    31.1 --- a/libovr/Src/Kernel/OVR_System.cpp	Sat Sep 14 17:51:03 2013 +0300
    31.2 +++ b/libovr/Src/Kernel/OVR_System.cpp	Sun Sep 15 04:10:05 2013 +0300
    31.3 @@ -1,1 +1,70 @@
    31.4 -/************************************************************************************
    31.5 
    31.6 Filename    :   OVR_System.cpp
    31.7 Content     :   General kernel initialization/cleanup, including that
    31.8                 of the memory allocator.
    31.9 Created     :   September 19, 2012
   31.10 Notes       : 
   31.11 
   31.12 Copyright   :   Copyright 2012 Oculus VR, Inc. All Rights reserved.
   31.13 
   31.14 Use of this software is subject to the terms of the Oculus license
   31.15 agreement provided at the time of installation or download, or which
   31.16 otherwise accompanies this software in either electronic or hard copy form.
   31.17 
   31.18 ************************************************************************************/
   31.19 
   31.20 #include "OVR_System.h"
   31.21 #include "OVR_Threads.h"
   31.22 #include "OVR_Timer.h"
   31.23 
   31.24 namespace OVR {
   31.25 
   31.26 // *****  OVR::System Implementation
   31.27 
   31.28 // Initializes System core, installing allocator.
   31.29 void System::Init(Log* log, Allocator *palloc)
   31.30 {    
   31.31     if (!Allocator::GetInstance())
   31.32     {
   31.33         Log::SetGlobalLog(log);
   31.34         Timer::initializeTimerSystem();
   31.35         Allocator::setInstance(palloc);
   31.36     }
   31.37     else
   31.38     {
   31.39         OVR_DEBUG_LOG(("System::Init failed - duplicate call."));
   31.40     }
   31.41 }
   31.42 
   31.43 void System::Destroy()
   31.44 {    
   31.45     if (Allocator::GetInstance())
   31.46     {
   31.47         // Wait for all threads to finish; this must be done so that memory
   31.48         // allocator and all destructors finalize correctly.
   31.49 #ifdef OVR_ENABLE_THREADS
   31.50         Thread::FinishAllThreads();
   31.51 #endif
   31.52 
   31.53         // Shutdown heap and destroy SysAlloc singleton, if any.
   31.54         Allocator::GetInstance()->onSystemShutdown();
   31.55         Allocator::setInstance(0);
   31.56 
   31.57         Timer::shutdownTimerSystem();
   31.58         Log::SetGlobalLog(Log::GetDefaultLog());
   31.59     }
   31.60     else
   31.61     {
   31.62         OVR_DEBUG_LOG(("System::Destroy failed - System not initialized."));
   31.63     }
   31.64 }
   31.65 
   31.66 // Returns 'true' if system was properly initialized.
   31.67 bool System::IsInitialized()
   31.68 {
   31.69     return Allocator::GetInstance() != 0;
   31.70 }
   31.71 
   31.72 } // OVR
   31.73 
   31.74 \ No newline at end of file
   31.75 +/************************************************************************************
   31.76 +
   31.77 +Filename    :   OVR_System.cpp
   31.78 +Content     :   General kernel initialization/cleanup, including that
   31.79 +                of the memory allocator.
   31.80 +Created     :   September 19, 2012
   31.81 +Notes       : 
   31.82 +
   31.83 +Copyright   :   Copyright 2012 Oculus VR, Inc. All Rights reserved.
   31.84 +
   31.85 +Use of this software is subject to the terms of the Oculus license
   31.86 +agreement provided at the time of installation or download, or which
   31.87 +otherwise accompanies this software in either electronic or hard copy form.
   31.88 +
   31.89 +************************************************************************************/
   31.90 +
   31.91 +#include "OVR_System.h"
   31.92 +#include "OVR_Threads.h"
   31.93 +#include "OVR_Timer.h"
   31.94 +
   31.95 +namespace OVR {
   31.96 +
   31.97 +// *****  OVR::System Implementation
   31.98 +
   31.99 +// Initializes System core, installing allocator.
  31.100 +void System::Init(Log* log, Allocator *palloc)
  31.101 +{    
  31.102 +    if (!Allocator::GetInstance())
  31.103 +    {
  31.104 +        Log::SetGlobalLog(log);
  31.105 +        Timer::initializeTimerSystem();
  31.106 +        Allocator::setInstance(palloc);
  31.107 +    }
  31.108 +    else
  31.109 +    {
  31.110 +        OVR_DEBUG_LOG(("System::Init failed - duplicate call."));
  31.111 +    }
  31.112 +}
  31.113 +
  31.114 +void System::Destroy()
  31.115 +{    
  31.116 +    if (Allocator::GetInstance())
  31.117 +    {
  31.118 +        // Wait for all threads to finish; this must be done so that memory
  31.119 +        // allocator and all destructors finalize correctly.
  31.120 +#ifdef OVR_ENABLE_THREADS
  31.121 +        Thread::FinishAllThreads();
  31.122 +#endif
  31.123 +
  31.124 +        // Shutdown heap and destroy SysAlloc singleton, if any.
  31.125 +        Allocator::GetInstance()->onSystemShutdown();
  31.126 +        Allocator::setInstance(0);
  31.127 +
  31.128 +        Timer::shutdownTimerSystem();
  31.129 +        Log::SetGlobalLog(Log::GetDefaultLog());
  31.130 +    }
  31.131 +    else
  31.132 +    {
  31.133 +        OVR_DEBUG_LOG(("System::Destroy failed - System not initialized."));
  31.134 +    }
  31.135 +}
  31.136 +
  31.137 +// Returns 'true' if system was properly initialized.
  31.138 +bool System::IsInitialized()
  31.139 +{
  31.140 +    return Allocator::GetInstance() != 0;
  31.141 +}
  31.142 +
  31.143 +} // OVR
  31.144 +
    32.1 --- a/libovr/Src/Kernel/OVR_System.h	Sat Sep 14 17:51:03 2013 +0300
    32.2 +++ b/libovr/Src/Kernel/OVR_System.h	Sun Sep 15 04:10:05 2013 +0300
    32.3 @@ -1,1 +1,67 @@
    32.4 -/************************************************************************************
    32.5 
    32.6 PublicHeader:   OVR
    32.7 Filename    :   OVR_System.h
    32.8 Content     :   General kernel initialization/cleanup, including that
    32.9                 of the memory allocator.
   32.10 Created     :   September 19, 2012
   32.11 Notes       : 
   32.12 
   32.13 Copyright   :   Copyright 2012 Oculus VR, Inc. All Rights reserved.
   32.14 
   32.15 Use of this software is subject to the terms of the Oculus license
   32.16 agreement provided at the time of installation or download, or which
   32.17 otherwise accompanies this software in either electronic or hard copy form.
   32.18 
   32.19 ************************************************************************************/
   32.20 
   32.21 #ifndef OVR_System_h
   32.22 #define OVR_System_h
   32.23 
   32.24 #include "OVR_Allocator.h"
   32.25 #include "OVR_Log.h"
   32.26 
   32.27 namespace OVR {
   32.28 
   32.29 // ***** System Core Initialization class
   32.30 
   32.31 // System initialization must take place before any other OVR_Kernel objects are used;
   32.32 // this is done my calling System::Init(). Among other things, this is necessary to
   32.33 // initialize the memory allocator. Similarly, System::Destroy must be
   32.34 // called before program exist for proper cleanup. Both of these tasks can be achieved by
   32.35 // simply creating System object first, allowing its constructor/destructor do the work.
   32.36 
   32.37 // TBD: Require additional System class for Oculus Rift API?
   32.38 
   32.39 class System
   32.40 {
   32.41 public:
   32.42 
   32.43     // System constructor expects allocator to be specified, if it is being substituted.
   32.44     System(Log* log = Log::ConfigureDefaultLog(LogMask_Debug),
   32.45            Allocator* palloc = DefaultAllocator::InitSystemSingleton())
   32.46     {
   32.47         Init(log, palloc);
   32.48     }
   32.49 
   32.50     ~System()
   32.51     {
   32.52         Destroy();
   32.53     }
   32.54 
   32.55     // Returns 'true' if system was properly initialized.
   32.56     static bool OVR_CDECL IsInitialized();
   32.57 
   32.58     // Initializes System core.  Users can override memory implementation by passing
   32.59     // a different Allocator here.
   32.60     static void OVR_CDECL Init(Log* log = Log::ConfigureDefaultLog(LogMask_Debug),
   32.61                                Allocator *palloc = DefaultAllocator::InitSystemSingleton());
   32.62 
   32.63     // De-initializes System more, finalizing the threading system and destroying
   32.64     // the global memory allocator.
   32.65     static void OVR_CDECL Destroy();    
   32.66 };
   32.67 
   32.68 } // OVR
   32.69 
   32.70 #endif
   32.71 \ No newline at end of file
   32.72 +/************************************************************************************
   32.73 +
   32.74 +PublicHeader:   OVR
   32.75 +Filename    :   OVR_System.h
   32.76 +Content     :   General kernel initialization/cleanup, including that
   32.77 +                of the memory allocator.
   32.78 +Created     :   September 19, 2012
   32.79 +Notes       : 
   32.80 +
   32.81 +Copyright   :   Copyright 2012 Oculus VR, Inc. All Rights reserved.
   32.82 +
   32.83 +Use of this software is subject to the terms of the Oculus license
   32.84 +agreement provided at the time of installation or download, or which
   32.85 +otherwise accompanies this software in either electronic or hard copy form.
   32.86 +
   32.87 +************************************************************************************/
   32.88 +
   32.89 +#ifndef OVR_System_h
   32.90 +#define OVR_System_h
   32.91 +
   32.92 +#include "OVR_Allocator.h"
   32.93 +#include "OVR_Log.h"
   32.94 +
   32.95 +namespace OVR {
   32.96 +
   32.97 +// ***** System Core Initialization class
   32.98 +
   32.99 +// System initialization must take place before any other OVR_Kernel objects are used;
  32.100 +// this is done my calling System::Init(). Among other things, this is necessary to
  32.101 +// initialize the memory allocator. Similarly, System::Destroy must be
  32.102 +// called before program exist for proper cleanup. Both of these tasks can be achieved by
  32.103 +// simply creating System object first, allowing its constructor/destructor do the work.
  32.104 +
  32.105 +// TBD: Require additional System class for Oculus Rift API?
  32.106 +
  32.107 +class System
  32.108 +{
  32.109 +public:
  32.110 +
  32.111 +    // System constructor expects allocator to be specified, if it is being substituted.
  32.112 +    System(Log* log = Log::ConfigureDefaultLog(LogMask_Debug),
  32.113 +           Allocator* palloc = DefaultAllocator::InitSystemSingleton())
  32.114 +    {
  32.115 +        Init(log, palloc);
  32.116 +    }
  32.117 +
  32.118 +    ~System()
  32.119 +    {
  32.120 +        Destroy();
  32.121 +    }
  32.122 +
  32.123 +    // Returns 'true' if system was properly initialized.
  32.124 +    static bool OVR_CDECL IsInitialized();
  32.125 +
  32.126 +    // Initializes System core.  Users can override memory implementation by passing
  32.127 +    // a different Allocator here.
  32.128 +    static void OVR_CDECL Init(Log* log = Log::ConfigureDefaultLog(LogMask_Debug),
  32.129 +                               Allocator *palloc = DefaultAllocator::InitSystemSingleton());
  32.130 +
  32.131 +    // De-initializes System more, finalizing the threading system and destroying
  32.132 +    // the global memory allocator.
  32.133 +    static void OVR_CDECL Destroy();    
  32.134 +};
  32.135 +
  32.136 +} // OVR
  32.137 +
  32.138 +#endif
    33.1 --- a/libovr/Src/Kernel/OVR_Threads.h	Sat Sep 14 17:51:03 2013 +0300
    33.2 +++ b/libovr/Src/Kernel/OVR_Threads.h	Sun Sep 15 04:10:05 2013 +0300
    33.3 @@ -1,1 +1,396 @@
    33.4 -/************************************************************************************
    33.5 
    33.6 PublicHeader:   None
    33.7 Filename    :   OVR_Threads.h
    33.8 Content     :   Contains thread-related (safe) functionality
    33.9 Created     :   September 19, 2012
   33.10 Notes       : 
   33.11 
   33.12 Copyright   :   Copyright 2012 Oculus VR, Inc. All Rights reserved.
   33.13 
   33.14 Use of this software is subject to the terms of the Oculus license
   33.15 agreement provided at the time of installation or download, or which
   33.16 otherwise accompanies this software in either electronic or hard copy form.
   33.17 
   33.18 ************************************************************************************/
   33.19 #ifndef OVR_Threads_h
   33.20 #define OVR_Threads_h
   33.21 
   33.22 #include "OVR_Types.h"
   33.23 #include "OVR_Atomic.h"
   33.24 #include "OVR_RefCount.h"
   33.25 #include "OVR_Array.h"
   33.26 
   33.27 // Defines the infinite wait delay timeout
   33.28 #define OVR_WAIT_INFINITE 0xFFFFFFFF
   33.29 
   33.30 // To be defined in the project configuration options
   33.31 #ifdef OVR_ENABLE_THREADS
   33.32 
   33.33 
   33.34 namespace OVR {
   33.35 
   33.36 //-----------------------------------------------------------------------------------
   33.37 // ****** Declared classes
   33.38 
   33.39 // Declared with thread support only
   33.40 class   Mutex;
   33.41 class   WaitCondition;
   33.42 class   Event;
   33.43 // Implementation forward declarations
   33.44 class MutexImpl;
   33.45 class WaitConditionImpl;
   33.46 
   33.47 
   33.48 
   33.49 //-----------------------------------------------------------------------------------
   33.50 // ***** Mutex
   33.51 
   33.52 // Mutex class represents a system Mutex synchronization object that provides access 
   33.53 // serialization between different threads, allowing one thread mutually exclusive access 
   33.54 // to a resource. Mutex is more heavy-weight then Lock, but supports WaitCondition.
   33.55 
   33.56 class Mutex
   33.57 {
   33.58     friend class WaitConditionImpl;    
   33.59     friend class MutexImpl;
   33.60 
   33.61     MutexImpl  *pImpl; 
   33.62 
   33.63 public:
   33.64     // Constructor/destructor
   33.65     Mutex(bool recursive = 1);
   33.66     ~Mutex();
   33.67 
   33.68     // Locking functions
   33.69     void  DoLock();
   33.70     bool  TryLock();
   33.71     void  Unlock();
   33.72 
   33.73     // Returns 1 if the mutes is currently locked by another thread
   33.74     // Returns 0 if the mutex is not locked by another thread, and can therefore be acquired. 
   33.75     bool  IsLockedByAnotherThread();
   33.76     
   33.77     // Locker class; Used for automatic locking of a mutex withing scope    
   33.78     class Locker
   33.79     {
   33.80     public:
   33.81         Mutex *pMutex;
   33.82         Locker(Mutex *pmutex)
   33.83             { pMutex = pmutex; pMutex->DoLock(); }
   33.84         ~Locker()
   33.85             { pMutex->Unlock(); }
   33.86     };
   33.87 };
   33.88 
   33.89 
   33.90 //-----------------------------------------------------------------------------------
   33.91 // ***** WaitCondition
   33.92 
   33.93 /*
   33.94     WaitCondition is a synchronization primitive that can be used to implement what is known as a monitor.
   33.95     Dependent threads wait on a wait condition by calling Wait(), and get woken up by other threads that
   33.96     call Notify() or NotifyAll().
   33.97 
   33.98     The unique feature of this class is that it provides an atomic way of first releasing a Mutex, and then 
   33.99     starting a wait on a wait condition. If both the mutex and the wait condition are associated with the same
  33.100     resource, this ensures that any condition checked for while the mutex was locked does not change before
  33.101     the wait on the condition is actually initiated.
  33.102 */
  33.103 
  33.104 class WaitCondition
  33.105 {
  33.106     friend class WaitConditionImpl;
  33.107     // Internal implementation structure
  33.108     WaitConditionImpl *pImpl;
  33.109 
  33.110 public:
  33.111     // Constructor/destructor
  33.112     WaitCondition();
  33.113     ~WaitCondition();
  33.114 
  33.115     // Release mutex and wait for condition. The mutex is re-aquired after the wait.
  33.116     // Delay is specified in milliseconds (1/1000 of a second).
  33.117     bool    Wait(Mutex *pmutex, unsigned delay = OVR_WAIT_INFINITE);
  33.118 
  33.119     // Notify a condition, releasing at one object waiting
  33.120     void    Notify();
  33.121     // Notify a condition, releasing all objects waiting
  33.122     void    NotifyAll();
  33.123 };
  33.124 
  33.125 
  33.126 //-----------------------------------------------------------------------------------
  33.127 // ***** Event
  33.128 
  33.129 // Event is a wait-able synchronization object similar to Windows event.
  33.130 // Event can be waited on until it's signaled by another thread calling
  33.131 // either SetEvent or PulseEvent.
  33.132 
  33.133 class Event
  33.134 {
  33.135     // Event state, its mutex and the wait condition
  33.136     volatile bool   State;
  33.137     volatile bool   Temporary;  
  33.138     mutable Mutex   StateMutex;
  33.139     WaitCondition   StateWaitCondition;
  33.140 
  33.141     void updateState(bool newState, bool newTemp, bool mustNotify);
  33.142 
  33.143 public:    
  33.144     Event(bool setInitially = 0) : State(setInitially), Temporary(false) { }
  33.145     ~Event() { }
  33.146 
  33.147     // Wait on an event condition until it is set
  33.148     // Delay is specified in milliseconds (1/1000 of a second).
  33.149     bool  Wait(unsigned delay = OVR_WAIT_INFINITE);
  33.150     
  33.151     // Set an event, releasing objects waiting on it
  33.152     void  SetEvent()
  33.153     { updateState(true, false, true); }
  33.154 
  33.155     // Reset an event, un-signaling it
  33.156     void  ResetEvent()
  33.157     { updateState(false, false, false); }
  33.158 
  33.159     // Set and then reset an event once a waiter is released.
  33.160     // If threads are already waiting, they will be notified and released
  33.161     // If threads are not waiting, the event is set until the first thread comes in
  33.162     void  PulseEvent()
  33.163     { updateState(true, true, true); }
  33.164 };
  33.165 
  33.166 
  33.167 //-----------------------------------------------------------------------------------
  33.168 // ***** Thread class
  33.169 
  33.170 // ThreadId uniquely identifies a thread; returned by GetCurrentThreadId() and
  33.171 // Thread::GetThreadId.
  33.172 typedef void* ThreadId;
  33.173 
  33.174 
  33.175 // *** Thread flags
  33.176 
  33.177 // Indicates that the thread is has been started, i.e. Start method has been called, and threads
  33.178 // OnExit() method has not yet been called/returned.
  33.179 #define OVR_THREAD_STARTED               0x01
  33.180 // This flag is set once the thread has ran, and finished.
  33.181 #define OVR_THREAD_FINISHED              0x02
  33.182 // This flag is set temporarily if this thread was started suspended. It is used internally.
  33.183 #define OVR_THREAD_START_SUSPENDED       0x08
  33.184 // This flag is used to ask a thread to exit. Message driven threads will usually check this flag
  33.185 // and finish once it is set.
  33.186 #define OVR_THREAD_EXIT                  0x10
  33.187 
  33.188 
  33.189 class Thread : public RefCountBase<Thread>
  33.190 { // NOTE: Waitable must be the first base since it implements RefCountImpl.    
  33.191 
  33.192 public:
  33.193 
  33.194     // *** Callback functions, can be used instead of overriding Run
  33.195 
  33.196     // Run function prototypes.    
  33.197     // Thread function and user handle passed to it, executed by the default
  33.198     // Thread::Run implementation if not null.
  33.199     typedef int (*ThreadFn)(Thread *pthread, void* h);
  33.200     
  33.201     // Thread ThreadFunction1 is executed if not 0, otherwise ThreadFunction2 is tried
  33.202     ThreadFn    ThreadFunction;    
  33.203     // User handle passes to a thread
  33.204     void*       UserHandle;
  33.205 
  33.206     // Thread state to start a thread with
  33.207     enum ThreadState
  33.208     {
  33.209         NotRunning  = 0,
  33.210         Running     = 1,
  33.211         Suspended   = 2
  33.212     };
  33.213 
  33.214     // Thread priority
  33.215     enum ThreadPriority
  33.216     {
  33.217         CriticalPriority,
  33.218         HighestPriority,
  33.219         AboveNormalPriority,
  33.220         NormalPriority,
  33.221         BelowNormalPriority,
  33.222         LowestPriority,
  33.223         IdlePriority,
  33.224     };
  33.225 
  33.226     // Thread constructor parameters
  33.227     struct CreateParams
  33.228     {
  33.229         CreateParams(ThreadFn func = 0, void* hand = 0, UPInt ssize = 128 * 1024, 
  33.230                      int proc = -1, ThreadState state = NotRunning, ThreadPriority prior = NormalPriority)
  33.231                      : threadFunction(func), userHandle(hand), stackSize(ssize), 
  33.232                        processor(proc), initialState(state), priority(prior) {}
  33.233         ThreadFn       threadFunction;   // Thread function
  33.234         void*          userHandle;       // User handle passes to a thread
  33.235         UPInt          stackSize;        // Thread stack size
  33.236         int            processor;        // Thread hardware processor
  33.237         ThreadState    initialState;     // 
  33.238         ThreadPriority priority;         // Thread priority
  33.239     };
  33.240 
  33.241     // *** Constructors
  33.242 
  33.243     // A default constructor always creates a thread in NotRunning state, because
  33.244     // the derived class has not yet been initialized. The derived class can call Start explicitly.
  33.245     // "processor" parameter specifies which hardware processor this thread will be run on. 
  33.246     // -1 means OS decides this. Implemented only on Win32
  33.247     Thread(UPInt stackSize = 128 * 1024, int processor = -1);
  33.248     // Constructors that initialize the thread with a pointer to function.
  33.249     // An option to start a thread is available, but it should not be used if classes are derived from Thread.
  33.250     // "processor" parameter specifies which hardware processor this thread will be run on. 
  33.251     // -1 means OS decides this. Implemented only on Win32
  33.252     Thread(ThreadFn threadFunction, void*  userHandle = 0, UPInt stackSize = 128 * 1024,
  33.253            int processor = -1, ThreadState initialState = NotRunning);
  33.254     // Constructors that initialize the thread with a create parameters structure.
  33.255     explicit Thread(const CreateParams& params);
  33.256 
  33.257     // Destructor.
  33.258     virtual ~Thread();
  33.259 
  33.260     // Waits for all Threads to finish; should be called only from the root
  33.261     // application thread. Once this function returns, we know that all other
  33.262     // thread's references to Thread object have been released.
  33.263     static  void OVR_CDECL FinishAllThreads();
  33.264 
  33.265 
  33.266     // *** Overridable Run function for thread processing
  33.267 
  33.268     // - returning from this method will end the execution of the thread
  33.269     // - return value is usually 0 for success 
  33.270     virtual int   Run();
  33.271     // Called after return/exit function
  33.272     virtual void  OnExit();
  33.273 
  33.274 
  33.275     // *** Thread management
  33.276 
  33.277     // Starts the thread if its not already running
  33.278     // - internally sets up the threading and calls Run()
  33.279     // - initial state can either be Running or Suspended, NotRunning will just fail and do nothing
  33.280     // - returns the exit code
  33.281     virtual bool  Start(ThreadState initialState = Running);
  33.282 
  33.283     // Quits with an exit code
  33.284     virtual void  Exit(int exitCode=0);
  33.285 
  33.286     // Suspend the thread until resumed
  33.287     // Returns 1 for success, 0 for failure.
  33.288     bool  Suspend();
  33.289     // Resumes currently suspended thread
  33.290     // Returns 1 for success, 0 for failure.
  33.291     bool  Resume();
  33.292 
  33.293     // Static function to return a pointer to the current thread
  33.294     //static Thread* GetThread();
  33.295 
  33.296 
  33.297     // *** Thread status query functions
  33.298 
  33.299     bool          GetExitFlag() const;
  33.300     void          SetExitFlag(bool exitFlag);
  33.301 
  33.302     // Determines whether the thread was running and is now finished
  33.303     bool          IsFinished() const;
  33.304     // Determines if the thread is currently suspended
  33.305     bool          IsSuspended() const;
  33.306     // Returns current thread state
  33.307     ThreadState   GetThreadState() const;
  33.308 
  33.309     // Returns the number of available CPUs on the system 
  33.310     static int    GetCPUCount();
  33.311 
  33.312     // Returns the thread exit code. Exit code is initialized to 0,
  33.313     // and set to the return value if Run function after the thread is finished.
  33.314     inline int    GetExitCode() const { return ExitCode; }
  33.315     // Returns an OS handle 
  33.316 #if defined(OVR_OS_WIN32)
  33.317     void*          GetOSHandle() const { return ThreadHandle; }
  33.318 #else
  33.319     pthread_t      GetOSHandle() const { return ThreadHandle; }
  33.320 #endif
  33.321 
  33.322 #if defined(OVR_OS_WIN32)
  33.323     ThreadId       GetThreadId() const { return IdValue; }
  33.324 #else
  33.325     ThreadId       GetThreadId() const { return (ThreadId)GetOSHandle(); }
  33.326 #endif
  33.327 
  33.328     static int      GetOSPriority(ThreadPriority);
  33.329     // *** Sleep
  33.330 
  33.331     // Sleep secs seconds
  33.332     static bool    Sleep(unsigned secs);
  33.333     // Sleep msecs milliseconds
  33.334     static bool    MSleep(unsigned msecs);
  33.335 
  33.336 
  33.337     // *** Debugging functionality
  33.338 #if defined(OVR_OS_WIN32)
  33.339     virtual void    SetThreadName( const char* name );
  33.340 #else
  33.341     virtual void    SetThreadName( const char* name ) { OVR_UNUSED(name); }
  33.342 #endif
  33.343 
  33.344 private:
  33.345 #if defined(OVR_OS_WIN32)
  33.346     friend unsigned WINAPI Thread_Win32StartFn(void *pthread);
  33.347 
  33.348 #else
  33.349     friend void *Thread_PthreadStartFn(void * phandle);
  33.350 
  33.351     static int            InitAttr;
  33.352     static pthread_attr_t Attr;
  33.353 #endif
  33.354 
  33.355 protected:    
  33.356     // Thread state flags
  33.357     AtomicInt<UInt32>   ThreadFlags;
  33.358     AtomicInt<SInt32>   SuspendCount;
  33.359     UPInt               StackSize;
  33.360 
  33.361     // Hardware processor which this thread is running on.
  33.362     int            Processor;
  33.363     ThreadPriority Priority;
  33.364 
  33.365 #if defined(OVR_OS_WIN32)
  33.366     void*               ThreadHandle;
  33.367     volatile ThreadId   IdValue;
  33.368 
  33.369     // System-specific cleanup function called from destructor
  33.370     void                CleanupSystemThread();
  33.371 
  33.372 #else
  33.373     pthread_t           ThreadHandle;
  33.374 #endif
  33.375 
  33.376     // Exit code of the thread, as returned by Run.
  33.377     int                 ExitCode;
  33.378 
  33.379     // Internal run function.
  33.380     int                 PRun();    
  33.381     // Finishes the thread and releases internal reference to it.
  33.382     void                FinishAndRelease();
  33.383 
  33.384     void                Init(const CreateParams& params);
  33.385 
  33.386     // Protected copy constructor
  33.387     Thread(const Thread &source) { OVR_UNUSED(source); }
  33.388 
  33.389 };
  33.390 
  33.391 // Returns the unique Id of a thread it is called on, intended for
  33.392 // comparison purposes.
  33.393 ThreadId GetCurrentThreadId();
  33.394 
  33.395 
  33.396 } // OVR
  33.397 
  33.398 #endif // OVR_ENABLE_THREADS
  33.399 #endif // OVR_Threads_h
  33.400 \ No newline at end of file
  33.401 +/************************************************************************************
  33.402 +
  33.403 +PublicHeader:   None
  33.404 +Filename    :   OVR_Threads.h
  33.405 +Content     :   Contains thread-related (safe) functionality
  33.406 +Created     :   September 19, 2012
  33.407 +Notes       : 
  33.408 +
  33.409 +Copyright   :   Copyright 2012 Oculus VR, Inc. All Rights reserved.
  33.410 +
  33.411 +Use of this software is subject to the terms of the Oculus license
  33.412 +agreement provided at the time of installation or download, or which
  33.413 +otherwise accompanies this software in either electronic or hard copy form.
  33.414 +
  33.415 +************************************************************************************/
  33.416 +#ifndef OVR_Threads_h
  33.417 +#define OVR_Threads_h
  33.418 +
  33.419 +#include "OVR_Types.h"
  33.420 +#include "OVR_Atomic.h"
  33.421 +#include "OVR_RefCount.h"
  33.422 +#include "OVR_Array.h"
  33.423 +
  33.424 +// Defines the infinite wait delay timeout
  33.425 +#define OVR_WAIT_INFINITE 0xFFFFFFFF
  33.426 +
  33.427 +// To be defined in the project configuration options
  33.428 +#ifdef OVR_ENABLE_THREADS
  33.429 +
  33.430 +
  33.431 +namespace OVR {
  33.432 +
  33.433 +//-----------------------------------------------------------------------------------
  33.434 +// ****** Declared classes
  33.435 +
  33.436 +// Declared with thread support only
  33.437 +class   Mutex;
  33.438 +class   WaitCondition;
  33.439 +class   Event;
  33.440 +// Implementation forward declarations
  33.441 +class MutexImpl;
  33.442 +class WaitConditionImpl;
  33.443 +
  33.444 +
  33.445 +
  33.446 +//-----------------------------------------------------------------------------------
  33.447 +// ***** Mutex
  33.448 +
  33.449 +// Mutex class represents a system Mutex synchronization object that provides access 
  33.450 +// serialization between different threads, allowing one thread mutually exclusive access 
  33.451 +// to a resource. Mutex is more heavy-weight then Lock, but supports WaitCondition.
  33.452 +
  33.453 +class Mutex
  33.454 +{
  33.455 +    friend class WaitConditionImpl;    
  33.456 +    friend class MutexImpl;
  33.457 +
  33.458 +    MutexImpl  *pImpl; 
  33.459 +
  33.460 +public:
  33.461 +    // Constructor/destructor
  33.462 +    Mutex(bool recursive = 1);
  33.463 +    ~Mutex();
  33.464 +
  33.465 +    // Locking functions
  33.466 +    void  DoLock();
  33.467 +    bool  TryLock();
  33.468 +    void  Unlock();
  33.469 +
  33.470 +    // Returns 1 if the mutes is currently locked by another thread
  33.471 +    // Returns 0 if the mutex is not locked by another thread, and can therefore be acquired. 
  33.472 +    bool  IsLockedByAnotherThread();
  33.473 +    
  33.474 +    // Locker class; Used for automatic locking of a mutex withing scope    
  33.475 +    class Locker
  33.476 +    {
  33.477 +    public:
  33.478 +        Mutex *pMutex;
  33.479 +        Locker(Mutex *pmutex)
  33.480 +            { pMutex = pmutex; pMutex->DoLock(); }
  33.481 +        ~Locker()
  33.482 +            { pMutex->Unlock(); }
  33.483 +    };
  33.484 +};
  33.485 +
  33.486 +
  33.487 +//-----------------------------------------------------------------------------------
  33.488 +// ***** WaitCondition
  33.489 +
  33.490 +/*
  33.491 +    WaitCondition is a synchronization primitive that can be used to implement what is known as a monitor.
  33.492 +    Dependent threads wait on a wait condition by calling Wait(), and get woken up by other threads that
  33.493 +    call Notify() or NotifyAll().
  33.494 +
  33.495 +    The unique feature of this class is that it provides an atomic way of first releasing a Mutex, and then 
  33.496 +    starting a wait on a wait condition. If both the mutex and the wait condition are associated with the same
  33.497 +    resource, this ensures that any condition checked for while the mutex was locked does not change before
  33.498 +    the wait on the condition is actually initiated.
  33.499 +*/
  33.500 +
  33.501 +class WaitCondition
  33.502 +{
  33.503 +    friend class WaitConditionImpl;
  33.504 +    // Internal implementation structure
  33.505 +    WaitConditionImpl *pImpl;
  33.506 +
  33.507 +public:
  33.508 +    // Constructor/destructor
  33.509 +    WaitCondition();
  33.510 +    ~WaitCondition();
  33.511 +
  33.512 +    // Release mutex and wait for condition. The mutex is re-aquired after the wait.
  33.513 +    // Delay is specified in milliseconds (1/1000 of a second).
  33.514 +    bool    Wait(Mutex *pmutex, unsigned delay = OVR_WAIT_INFINITE);
  33.515 +
  33.516 +    // Notify a condition, releasing at one object waiting
  33.517 +    void    Notify();
  33.518 +    // Notify a condition, releasing all objects waiting
  33.519 +    void    NotifyAll();
  33.520 +};
  33.521 +
  33.522 +
  33.523 +//-----------------------------------------------------------------------------------
  33.524 +// ***** Event
  33.525 +
  33.526 +// Event is a wait-able synchronization object similar to Windows event.
  33.527 +// Event can be waited on until it's signaled by another thread calling
  33.528 +// either SetEvent or PulseEvent.
  33.529 +
  33.530 +class Event
  33.531 +{
  33.532 +    // Event state, its mutex and the wait condition
  33.533 +    volatile bool   State;
  33.534 +    volatile bool   Temporary;  
  33.535 +    mutable Mutex   StateMutex;
  33.536 +    WaitCondition   StateWaitCondition;
  33.537 +
  33.538 +    void updateState(bool newState, bool newTemp, bool mustNotify);
  33.539 +
  33.540 +public:    
  33.541 +    Event(bool setInitially = 0) : State(setInitially), Temporary(false) { }
  33.542 +    ~Event() { }
  33.543 +
  33.544 +    // Wait on an event condition until it is set
  33.545 +    // Delay is specified in milliseconds (1/1000 of a second).
  33.546 +    bool  Wait(unsigned delay = OVR_WAIT_INFINITE);
  33.547 +    
  33.548 +    // Set an event, releasing objects waiting on it
  33.549 +    void  SetEvent()
  33.550 +    { updateState(true, false, true); }
  33.551 +
  33.552 +    // Reset an event, un-signaling it
  33.553 +    void  ResetEvent()
  33.554 +    { updateState(false, false, false); }
  33.555 +
  33.556 +    // Set and then reset an event once a waiter is released.
  33.557 +    // If threads are already waiting, they will be notified and released
  33.558 +    // If threads are not waiting, the event is set until the first thread comes in
  33.559 +    void  PulseEvent()
  33.560 +    { updateState(true, true, true); }
  33.561 +};
  33.562 +
  33.563 +
  33.564 +//-----------------------------------------------------------------------------------
  33.565 +// ***** Thread class
  33.566 +
  33.567 +// ThreadId uniquely identifies a thread; returned by GetCurrentThreadId() and
  33.568 +// Thread::GetThreadId.
  33.569 +typedef void* ThreadId;
  33.570 +
  33.571 +
  33.572 +// *** Thread flags
  33.573 +
  33.574 +// Indicates that the thread is has been started, i.e. Start method has been called, and threads
  33.575 +// OnExit() method has not yet been called/returned.
  33.576 +#define OVR_THREAD_STARTED               0x01
  33.577 +// This flag is set once the thread has ran, and finished.
  33.578 +#define OVR_THREAD_FINISHED              0x02
  33.579 +// This flag is set temporarily if this thread was started suspended. It is used internally.
  33.580 +#define OVR_THREAD_START_SUSPENDED       0x08
  33.581 +// This flag is used to ask a thread to exit. Message driven threads will usually check this flag
  33.582 +// and finish once it is set.
  33.583 +#define OVR_THREAD_EXIT                  0x10
  33.584 +
  33.585 +
  33.586 +class Thread : public RefCountBase<Thread>
  33.587 +{ // NOTE: Waitable must be the first base since it implements RefCountImpl.    
  33.588 +
  33.589 +public:
  33.590 +
  33.591 +    // *** Callback functions, can be used instead of overriding Run
  33.592 +
  33.593 +    // Run function prototypes.    
  33.594 +    // Thread function and user handle passed to it, executed by the default
  33.595 +    // Thread::Run implementation if not null.
  33.596 +    typedef int (*ThreadFn)(Thread *pthread, void* h);
  33.597 +    
  33.598 +    // Thread ThreadFunction1 is executed if not 0, otherwise ThreadFunction2 is tried
  33.599 +    ThreadFn    ThreadFunction;    
  33.600 +    // User handle passes to a thread
  33.601 +    void*       UserHandle;
  33.602 +
  33.603 +    // Thread state to start a thread with
  33.604 +    enum ThreadState
  33.605 +    {
  33.606 +        NotRunning  = 0,
  33.607 +        Running     = 1,
  33.608 +        Suspended   = 2
  33.609 +    };
  33.610 +
  33.611 +    // Thread priority
  33.612 +    enum ThreadPriority
  33.613 +    {
  33.614 +        CriticalPriority,
  33.615 +        HighestPriority,
  33.616 +        AboveNormalPriority,
  33.617 +        NormalPriority,
  33.618 +        BelowNormalPriority,
  33.619 +        LowestPriority,
  33.620 +        IdlePriority,
  33.621 +    };
  33.622 +
  33.623 +    // Thread constructor parameters
  33.624 +    struct CreateParams
  33.625 +    {
  33.626 +        CreateParams(ThreadFn func = 0, void* hand = 0, UPInt ssize = 128 * 1024, 
  33.627 +                     int proc = -1, ThreadState state = NotRunning, ThreadPriority prior = NormalPriority)
  33.628 +                     : threadFunction(func), userHandle(hand), stackSize(ssize), 
  33.629 +                       processor(proc), initialState(state), priority(prior) {}
  33.630 +        ThreadFn       threadFunction;   // Thread function
  33.631 +        void*          userHandle;       // User handle passes to a thread
  33.632 +        UPInt          stackSize;        // Thread stack size
  33.633 +        int            processor;        // Thread hardware processor
  33.634 +        ThreadState    initialState;     // 
  33.635 +        ThreadPriority priority;         // Thread priority
  33.636 +    };
  33.637 +
  33.638 +    // *** Constructors
  33.639 +
  33.640 +    // A default constructor always creates a thread in NotRunning state, because
  33.641 +    // the derived class has not yet been initialized. The derived class can call Start explicitly.
  33.642 +    // "processor" parameter specifies which hardware processor this thread will be run on. 
  33.643 +    // -1 means OS decides this. Implemented only on Win32
  33.644 +    Thread(UPInt stackSize = 128 * 1024, int processor = -1);
  33.645 +    // Constructors that initialize the thread with a pointer to function.
  33.646 +    // An option to start a thread is available, but it should not be used if classes are derived from Thread.
  33.647 +    // "processor" parameter specifies which hardware processor this thread will be run on. 
  33.648 +    // -1 means OS decides this. Implemented only on Win32
  33.649 +    Thread(ThreadFn threadFunction, void*  userHandle = 0, UPInt stackSize = 128 * 1024,
  33.650 +           int processor = -1, ThreadState initialState = NotRunning);
  33.651 +    // Constructors that initialize the thread with a create parameters structure.
  33.652 +    explicit Thread(const CreateParams& params);
  33.653 +
  33.654 +    // Destructor.
  33.655 +    virtual ~Thread();
  33.656 +
  33.657 +    // Waits for all Threads to finish; should be called only from the root
  33.658 +    // application thread. Once this function returns, we know that all other
  33.659 +    // thread's references to Thread object have been released.
  33.660 +    static  void OVR_CDECL FinishAllThreads();
  33.661 +
  33.662 +
  33.663 +    // *** Overridable Run function for thread processing
  33.664 +
  33.665 +    // - returning from this method will end the execution of the thread
  33.666 +    // - return value is usually 0 for success 
  33.667 +    virtual int   Run();
  33.668 +    // Called after return/exit function
  33.669 +    virtual void  OnExit();
  33.670 +
  33.671 +
  33.672 +    // *** Thread management
  33.673 +
  33.674 +    // Starts the thread if its not already running
  33.675 +    // - internally sets up the threading and calls Run()
  33.676 +    // - initial state can either be Running or Suspended, NotRunning will just fail and do nothing
  33.677 +    // - returns the exit code
  33.678 +    virtual bool  Start(ThreadState initialState = Running);
  33.679 +
  33.680 +    // Quits with an exit code
  33.681 +    virtual void  Exit(int exitCode=0);
  33.682 +
  33.683 +    // Suspend the thread until resumed
  33.684 +    // Returns 1 for success, 0 for failure.
  33.685 +    bool  Suspend();
  33.686 +    // Resumes currently suspended thread
  33.687 +    // Returns 1 for success, 0 for failure.
  33.688 +    bool  Resume();
  33.689 +
  33.690 +    // Static function to return a pointer to the current thread
  33.691 +    //static Thread* GetThread();
  33.692 +
  33.693 +
  33.694 +    // *** Thread status query functions
  33.695 +
  33.696 +    bool          GetExitFlag() const;
  33.697 +    void          SetExitFlag(bool exitFlag);
  33.698 +
  33.699 +    // Determines whether the thread was running and is now finished
  33.700 +    bool          IsFinished() const;
  33.701 +    // Determines if the thread is currently suspended
  33.702 +    bool          IsSuspended() const;
  33.703 +    // Returns current thread state
  33.704 +    ThreadState   GetThreadState() const;
  33.705 +
  33.706 +    // Returns the number of available CPUs on the system 
  33.707 +    static int    GetCPUCount();
  33.708 +
  33.709 +    // Returns the thread exit code. Exit code is initialized to 0,
  33.710 +    // and set to the return value if Run function after the thread is finished.
  33.711 +    inline int    GetExitCode() const { return ExitCode; }
  33.712 +    // Returns an OS handle 
  33.713 +#if defined(OVR_OS_WIN32)
  33.714 +    void*          GetOSHandle() const { return ThreadHandle; }
  33.715 +#else
  33.716 +    pthread_t      GetOSHandle() const { return ThreadHandle; }
  33.717 +#endif
  33.718 +
  33.719 +#if defined(OVR_OS_WIN32)
  33.720 +    ThreadId       GetThreadId() const { return IdValue; }
  33.721 +#else
  33.722 +    ThreadId       GetThreadId() const { return (ThreadId)GetOSHandle(); }
  33.723 +#endif
  33.724 +
  33.725 +    static int      GetOSPriority(ThreadPriority);
  33.726 +    // *** Sleep
  33.727 +
  33.728 +    // Sleep secs seconds
  33.729 +    static bool    Sleep(unsigned secs);
  33.730 +    // Sleep msecs milliseconds
  33.731 +    static bool    MSleep(unsigned msecs);
  33.732 +
  33.733 +
  33.734 +    // *** Debugging functionality
  33.735 +#if defined(OVR_OS_WIN32)
  33.736 +    virtual void    SetThreadName( const char* name );
  33.737 +#else
  33.738 +    virtual void    SetThreadName( const char* name ) { OVR_UNUSED(name); }
  33.739 +#endif
  33.740 +
  33.741 +private:
  33.742 +#if defined(OVR_OS_WIN32)
  33.743 +    friend unsigned WINAPI Thread_Win32StartFn(void *pthread);
  33.744 +
  33.745 +#else
  33.746 +    friend void *Thread_PthreadStartFn(void * phandle);
  33.747 +
  33.748 +    static int            InitAttr;
  33.749 +    static pthread_attr_t Attr;
  33.750 +#endif
  33.751 +
  33.752 +protected:    
  33.753 +    // Thread state flags
  33.754 +    AtomicInt<UInt32>   ThreadFlags;
  33.755 +    AtomicInt<SInt32>   SuspendCount;
  33.756 +    UPInt               StackSize;
  33.757 +
  33.758 +    // Hardware processor which this thread is running on.
  33.759 +    int            Processor;
  33.760 +    ThreadPriority Priority;
  33.761 +
  33.762 +#if defined(OVR_OS_WIN32)
  33.763 +    void*               ThreadHandle;
  33.764 +    volatile ThreadId   IdValue;
  33.765 +
  33.766 +    // System-specific cleanup function called from destructor
  33.767 +    void                CleanupSystemThread();
  33.768 +
  33.769 +#else
  33.770 +    pthread_t           ThreadHandle;
  33.771 +#endif
  33.772 +
  33.773 +    // Exit code of the thread, as returned by Run.
  33.774 +    int                 ExitCode;
  33.775 +
  33.776 +    // Internal run function.
  33.777 +    int                 PRun();    
  33.778 +    // Finishes the thread and releases internal reference to it.
  33.779 +    void                FinishAndRelease();
  33.780 +
  33.781 +    void                Init(const CreateParams& params);
  33.782 +
  33.783 +    // Protected copy constructor
  33.784 +    Thread(const Thread &source) { OVR_UNUSED(source); }
  33.785 +
  33.786 +};
  33.787 +
  33.788 +// Returns the unique Id of a thread it is called on, intended for
  33.789 +// comparison purposes.
  33.790 +ThreadId GetCurrentThreadId();
  33.791 +
  33.792 +
  33.793 +} // OVR
  33.794 +
  33.795 +#endif // OVR_ENABLE_THREADS
  33.796 +#endif // OVR_Threads_h
    34.1 --- a/libovr/Src/Kernel/OVR_Timer.cpp	Sat Sep 14 17:51:03 2013 +0300
    34.2 +++ b/libovr/Src/Kernel/OVR_Timer.cpp	Sun Sep 15 04:10:05 2013 +0300
    34.3 @@ -1,1 +1,156 @@
    34.4 -/************************************************************************************
    34.5 
    34.6 Filename    :   OVR_Timer.cpp
    34.7 Content     :   Provides static functions for precise timing
    34.8 Created     :   September 19, 2012
    34.9 Notes       : 
   34.10 
   34.11 Copyright   :   Copyright 2012 Oculus VR, Inc. All Rights reserved.
   34.12 
   34.13 Use of this software is subject to the terms of the Oculus license
   34.14 agreement provided at the time of installation or download, or which
   34.15 otherwise accompanies this software in either electronic or hard copy form.
   34.16 
   34.17 ************************************************************************************/
   34.18 
   34.19 #include "OVR_Timer.h"
   34.20 
   34.21 #if defined (OVR_OS_WIN32)
   34.22 #include <windows.h>
   34.23 
   34.24 #else
   34.25 #include <sys/time.h>
   34.26 #endif
   34.27 
   34.28 namespace OVR {
   34.29 
   34.30 //-----------------------------------------------------------------------------------
   34.31 // ***** Timer Class
   34.32 
   34.33 UInt64 Timer::GetProfileTicks()
   34.34 {
   34.35     return (GetRawTicks() * MksPerSecond) / GetRawFrequency();
   34.36 }
   34.37 double Timer::GetProfileSeconds()
   34.38 {
   34.39     static UInt64 StartTime = GetProfileTicks();
   34.40     return TicksToSeconds(GetProfileTicks()-StartTime);
   34.41 }
   34.42 
   34.43 
   34.44 //------------------------------------------------------------------------
   34.45 // *** Win32 Specific Timer
   34.46 
   34.47 #if (defined (OVR_OS_WIN32))
   34.48 
   34.49 CRITICAL_SECTION WinAPI_GetTimeCS;
   34.50 volatile UInt32  WinAPI_OldTime = 0;
   34.51 volatile UInt32  WinAPI_WrapCounter = 0;
   34.52 
   34.53 
   34.54 UInt32 Timer::GetTicksMs()
   34.55 {
   34.56     return timeGetTime();
   34.57 }
   34.58 
   34.59 UInt64 Timer::GetTicks()
   34.60 {
   34.61     DWORD  ticks = timeGetTime();
   34.62     UInt64 result;
   34.63 
   34.64     // On Win32 QueryPerformanceFrequency is unreliable due to SMP and
   34.65     // performance levels, so use this logic to detect wrapping and track
   34.66     // high bits.
   34.67     ::EnterCriticalSection(&WinAPI_GetTimeCS);
   34.68 
   34.69     if (WinAPI_OldTime > ticks)
   34.70         WinAPI_WrapCounter++;
   34.71     WinAPI_OldTime = ticks;
   34.72 
   34.73     result = (UInt64(WinAPI_WrapCounter) << 32) | ticks;
   34.74     ::LeaveCriticalSection(&WinAPI_GetTimeCS);
   34.75 
   34.76     return result * MksPerMs;
   34.77 }
   34.78 
   34.79 UInt64 Timer::GetRawTicks()
   34.80 {
   34.81     LARGE_INTEGER li;
   34.82     QueryPerformanceCounter(&li);
   34.83     return li.QuadPart;
   34.84 }
   34.85 
   34.86 UInt64 Timer::GetRawFrequency()
   34.87 {
   34.88     static UInt64 perfFreq = 0;
   34.89     if (perfFreq == 0)
   34.90     {
   34.91         LARGE_INTEGER freq;
   34.92         QueryPerformanceFrequency(&freq);
   34.93         perfFreq = freq.QuadPart;
   34.94     }
   34.95     return perfFreq;
   34.96 }
   34.97 
   34.98 void Timer::initializeTimerSystem()
   34.99 {
  34.100     timeBeginPeriod(1);
  34.101     InitializeCriticalSection(&WinAPI_GetTimeCS);
  34.102 
  34.103 }
  34.104 void Timer::shutdownTimerSystem()
  34.105 {
  34.106     DeleteCriticalSection(&WinAPI_GetTimeCS);
  34.107     timeEndPeriod(1);
  34.108 }
  34.109 
  34.110 #else   // !OVR_OS_WIN32
  34.111 
  34.112 
  34.113 //------------------------------------------------------------------------
  34.114 // *** Standard OS Timer     
  34.115 
  34.116 UInt32 Timer::GetTicksMs()
  34.117 {
  34.118     return (UInt32)(GetProfileTicks() / 1000);
  34.119 }
  34.120 // The profile ticks implementation is just fine for a normal timer.
  34.121 UInt64 Timer::GetTicks()
  34.122 {
  34.123     return GetProfileTicks();
  34.124 }
  34.125 
  34.126 void Timer::initializeTimerSystem()
  34.127 {
  34.128 }
  34.129 void Timer::shutdownTimerSystem()
  34.130 {
  34.131 }
  34.132 
  34.133 UInt64  Timer::GetRawTicks()
  34.134 {
  34.135     // TODO: prefer rdtsc when available?
  34.136 
  34.137     // Return microseconds.
  34.138     struct timeval tv;
  34.139     UInt64 result;
  34.140 
  34.141     gettimeofday(&tv, 0);
  34.142 
  34.143     result = (UInt64)tv.tv_sec * 1000000;
  34.144     result += tv.tv_usec;
  34.145 
  34.146     return result;
  34.147 }
  34.148 
  34.149 UInt64 Timer::GetRawFrequency()
  34.150 {
  34.151     return MksPerSecond;
  34.152 }
  34.153 
  34.154 #endif  // !OVR_OS_WIN32
  34.155 
  34.156 
  34.157 
  34.158 } // OVR
  34.159 
  34.160 \ No newline at end of file
  34.161 +/************************************************************************************
  34.162 +
  34.163 +Filename    :   OVR_Timer.cpp
  34.164 +Content     :   Provides static functions for precise timing
  34.165 +Created     :   September 19, 2012
  34.166 +Notes       : 
  34.167 +
  34.168 +Copyright   :   Copyright 2012 Oculus VR, Inc. All Rights reserved.
  34.169 +
  34.170 +Use of this software is subject to the terms of the Oculus license
  34.171 +agreement provided at the time of installation or download, or which
  34.172 +otherwise accompanies this software in either electronic or hard copy form.
  34.173 +
  34.174 +************************************************************************************/
  34.175 +
  34.176 +#include "OVR_Timer.h"
  34.177 +
  34.178 +#if defined (OVR_OS_WIN32)
  34.179 +#include <windows.h>
  34.180 +
  34.181 +#else
  34.182 +#include <sys/time.h>
  34.183 +#endif
  34.184 +
  34.185 +namespace OVR {
  34.186 +
  34.187 +//-----------------------------------------------------------------------------------
  34.188 +// ***** Timer Class
  34.189 +
  34.190 +UInt64 Timer::GetProfileTicks()
  34.191 +{
  34.192 +    return (GetRawTicks() * MksPerSecond) / GetRawFrequency();
  34.193 +}
  34.194 +double Timer::GetProfileSeconds()
  34.195 +{
  34.196 +    static UInt64 StartTime = GetProfileTicks();
  34.197 +    return TicksToSeconds(GetProfileTicks()-StartTime);
  34.198 +}
  34.199 +
  34.200 +
  34.201 +//------------------------------------------------------------------------
  34.202 +// *** Win32 Specific Timer
  34.203 +
  34.204 +#if (defined (OVR_OS_WIN32))
  34.205 +
  34.206 +CRITICAL_SECTION WinAPI_GetTimeCS;
  34.207 +volatile UInt32  WinAPI_OldTime = 0;
  34.208 +volatile UInt32  WinAPI_WrapCounter = 0;
  34.209 +
  34.210 +
  34.211 +UInt32 Timer::GetTicksMs()
  34.212 +{
  34.213 +    return timeGetTime();
  34.214 +}
  34.215 +
  34.216 +UInt64 Timer::GetTicks()
  34.217 +{
  34.218 +    DWORD  ticks = timeGetTime();
  34.219 +    UInt64 result;
  34.220 +
  34.221 +    // On Win32 QueryPerformanceFrequency is unreliable due to SMP and
  34.222 +    // performance levels, so use this logic to detect wrapping and track
  34.223 +    // high bits.
  34.224 +    ::EnterCriticalSection(&WinAPI_GetTimeCS);
  34.225 +
  34.226 +    if (WinAPI_OldTime > ticks)
  34.227 +        WinAPI_WrapCounter++;
  34.228 +    WinAPI_OldTime = ticks;
  34.229 +
  34.230 +    result = (UInt64(WinAPI_WrapCounter) << 32) | ticks;
  34.231 +    ::LeaveCriticalSection(&WinAPI_GetTimeCS);
  34.232 +
  34.233 +    return result * MksPerMs;
  34.234 +}
  34.235 +
  34.236 +UInt64 Timer::GetRawTicks()
  34.237 +{
  34.238 +    LARGE_INTEGER li;
  34.239 +    QueryPerformanceCounter(&li);
  34.240 +    return li.QuadPart;
  34.241 +}
  34.242 +
  34.243 +UInt64 Timer::GetRawFrequency()
  34.244 +{
  34.245 +    static UInt64 perfFreq = 0;
  34.246 +    if (perfFreq == 0)
  34.247 +    {
  34.248 +        LARGE_INTEGER freq;
  34.249 +        QueryPerformanceFrequency(&freq);
  34.250 +        perfFreq = freq.QuadPart;
  34.251 +    }
  34.252 +    return perfFreq;
  34.253 +}
  34.254 +
  34.255 +void Timer::initializeTimerSystem()
  34.256 +{
  34.257 +    timeBeginPeriod(1);
  34.258 +    InitializeCriticalSection(&WinAPI_GetTimeCS);
  34.259 +
  34.260 +}
  34.261 +void Timer::shutdownTimerSystem()
  34.262 +{
  34.263 +    DeleteCriticalSection(&WinAPI_GetTimeCS);
  34.264 +    timeEndPeriod(1);
  34.265 +}
  34.266 +
  34.267 +#else   // !OVR_OS_WIN32
  34.268 +
  34.269 +
  34.270 +//------------------------------------------------------------------------
  34.271 +// *** Standard OS Timer     
  34.272 +
  34.273 +UInt32 Timer::GetTicksMs()
  34.274 +{
  34.275 +    return (UInt32)(GetProfileTicks() / 1000);
  34.276 +}
  34.277 +// The profile ticks implementation is just fine for a normal timer.
  34.278 +UInt64 Timer::GetTicks()
  34.279 +{
  34.280 +    return GetProfileTicks();
  34.281 +}
  34.282 +
  34.283 +void Timer::initializeTimerSystem()
  34.284 +{
  34.285 +}
  34.286 +void Timer::shutdownTimerSystem()
  34.287 +{
  34.288 +}
  34.289 +
  34.290 +UInt64  Timer::GetRawTicks()
  34.291 +{
  34.292 +    // TODO: prefer rdtsc when available?
  34.293 +
  34.294 +    // Return microseconds.
  34.295 +    struct timeval tv;
  34.296 +    UInt64 result;
  34.297 +
  34.298 +    gettimeofday(&tv, 0);
  34.299 +
  34.300 +    result = (UInt64)tv.tv_sec * 1000000;
  34.301 +    result += tv.tv_usec;
  34.302 +
  34.303 +    return result;
  34.304 +}
  34.305 +
  34.306 +UInt64 Timer::GetRawFrequency()
  34.307 +{
  34.308 +    return MksPerSecond;
  34.309 +}
  34.310 +
  34.311 +#endif  // !OVR_OS_WIN32
  34.312 +
  34.313 +
  34.314 +
  34.315 +} // OVR
  34.316 +
    35.1 --- a/libovr/Src/Kernel/OVR_Timer.h	Sat Sep 14 17:51:03 2013 +0300
    35.2 +++ b/libovr/Src/Kernel/OVR_Timer.h	Sun Sep 15 04:10:05 2013 +0300
    35.3 @@ -1,1 +1,100 @@
    35.4 -/************************************************************************************
    35.5 
    35.6 PublicHeader:   OVR
    35.7 Filename    :   OVR_Timer.h
    35.8 Content     :   Provides static functions for precise timing
    35.9 Created     :   September 19, 2012
   35.10 Notes       : 
   35.11 
   35.12 Copyright   :   Copyright 2012 Oculus VR, Inc. All Rights reserved.
   35.13 
   35.14 Use of this software is subject to the terms of the Oculus license
   35.15 agreement provided at the time of installation or download, or which
   35.16 otherwise accompanies this software in either electronic or hard copy form.
   35.17 
   35.18 ************************************************************************************/
   35.19 
   35.20 #ifndef OVR_Timer_h
   35.21 #define OVR_Timer_h
   35.22 
   35.23 #include "OVR_Types.h"
   35.24 
   35.25 namespace OVR {
   35.26     
   35.27 //-----------------------------------------------------------------------------------
   35.28 // ***** Timer
   35.29 
   35.30 // Timer class defines a family of static functions used for application
   35.31 // timing and profiling.
   35.32 
   35.33 class Timer
   35.34 {
   35.35 public:
   35.36     enum {
   35.37         MsPerSecond     = 1000, // Milliseconds in one second.
   35.38         MksPerMs        = 1000, // Microseconds in one millisecond.
   35.39         MksPerSecond    = MsPerSecond * MksPerMs
   35.40     };
   35.41 
   35.42 
   35.43     // ***** Timing APIs for Application    
   35.44     // These APIs should be used to guide animation and other program functions
   35.45     // that require precision.
   35.46 
   35.47     // Returns ticks in milliseconds, as a 32-bit number. May wrap around every
   35.48     // 49.2 days. Use either time difference of two values of GetTicks to avoid
   35.49     // wrap-around.  GetTicksMs may perform better then GetTicks.
   35.50     static UInt32  OVR_STDCALL GetTicksMs();
   35.51 
   35.52     // GetTicks returns general-purpose high resolution application timer value,
   35.53     // measured in microseconds (mks, or 1/1000000 of a second). The actual precision
   35.54     // is system-specific and may be much lower, such as 1 ms.
   35.55     static UInt64  OVR_STDCALL GetTicks();
   35.56 
   35.57     
   35.58     // ***** Profiling APIs.
   35.59     // These functions should be used for profiling, but may have system specific
   35.60     // artifacts that make them less appropriate for general system use.
   35.61     // On Win32, for example these rely on QueryPerformanceConter  may have
   35.62     // problems with thread-core switching and power modes.
   35.63 
   35.64     // Return a hi-res timer value in mks (1/1000000 of a sec).
   35.65     // Generally you want to call this at the start and end of an
   35.66     // operation, and pass the difference to
   35.67     // TicksToSeconds() to find out how long the operation took. 
   35.68     static UInt64  OVR_STDCALL GetProfileTicks();
   35.69 
   35.70     // More convenient zero-based profile timer in seconds. First call initializes 
   35.71     // the "zero" value; future calls return the difference. Not thread safe for first call.
   35.72     // Due to low precision of Double, may malfunction after long runtime.
   35.73     static double  OVR_STDCALL GetProfileSeconds();
   35.74 
   35.75     // Get the raw cycle counter value, providing the maximum possible timer resolution.
   35.76     static UInt64  OVR_STDCALL GetRawTicks();
   35.77     static UInt64  OVR_STDCALL GetRawFrequency();
   35.78 
   35.79     
   35.80     // ***** Tick and time unit conversion.
   35.81 
   35.82     // Convert micro-second ticks value into seconds value.
   35.83     static inline double TicksToSeconds(UInt64 ticks)
   35.84     {
   35.85         return static_cast<double>(ticks) * (1.0 / (double)MksPerSecond);
   35.86     }
   35.87     // Convert Raw or frequency-unit ticks to seconds based on specified frequency.
   35.88     static inline double RawTicksToSeconds(UInt64 rawTicks, UInt64 rawFrequency)
   35.89     {
   35.90         return static_cast<double>(rawTicks) * rawFrequency;
   35.91     }
   35.92 
   35.93 private:
   35.94     friend class System;
   35.95     // System called during program startup/shutdown.
   35.96     static void initializeTimerSystem();
   35.97     static void shutdownTimerSystem();
   35.98 };
   35.99 
  35.100 
  35.101 } // Scaleform::Timer
  35.102 
  35.103 #endif
  35.104 \ No newline at end of file
  35.105 +/************************************************************************************
  35.106 +
  35.107 +PublicHeader:   OVR
  35.108 +Filename    :   OVR_Timer.h
  35.109 +Content     :   Provides static functions for precise timing
  35.110 +Created     :   September 19, 2012
  35.111 +Notes       : 
  35.112 +
  35.113 +Copyright   :   Copyright 2012 Oculus VR, Inc. All Rights reserved.
  35.114 +
  35.115 +Use of this software is subject to the terms of the Oculus license
  35.116 +agreement provided at the time of installation or download, or which
  35.117 +otherwise accompanies this software in either electronic or hard copy form.
  35.118 +
  35.119 +************************************************************************************/
  35.120 +
  35.121 +#ifndef OVR_Timer_h
  35.122 +#define OVR_Timer_h
  35.123 +
  35.124 +#include "OVR_Types.h"
  35.125 +
  35.126 +namespace OVR {
  35.127 +    
  35.128 +//-----------------------------------------------------------------------------------
  35.129 +// ***** Timer
  35.130 +
  35.131 +// Timer class defines a family of static functions used for application
  35.132 +// timing and profiling.
  35.133 +
  35.134 +class Timer
  35.135 +{
  35.136 +public:
  35.137 +    enum {
  35.138 +        MsPerSecond     = 1000, // Milliseconds in one second.
  35.139 +        MksPerMs        = 1000, // Microseconds in one millisecond.
  35.140 +        MksPerSecond    = MsPerSecond * MksPerMs
  35.141 +    };
  35.142 +
  35.143 +
  35.144 +    // ***** Timing APIs for Application    
  35.145 +    // These APIs should be used to guide animation and other program functions
  35.146 +    // that require precision.
  35.147 +
  35.148 +    // Returns ticks in milliseconds, as a 32-bit number. May wrap around every
  35.149 +    // 49.2 days. Use either time difference of two values of GetTicks to avoid
  35.150 +    // wrap-around.  GetTicksMs may perform better then GetTicks.
  35.151 +    static UInt32  OVR_STDCALL GetTicksMs();
  35.152 +
  35.153 +    // GetTicks returns general-purpose high resolution application timer value,
  35.154 +    // measured in microseconds (mks, or 1/1000000 of a second). The actual precision
  35.155 +    // is system-specific and may be much lower, such as 1 ms.
  35.156 +    static UInt64  OVR_STDCALL GetTicks();
  35.157 +
  35.158 +    
  35.159 +    // ***** Profiling APIs.
  35.160 +    // These functions should be used for profiling, but may have system specific
  35.161 +    // artifacts that make them less appropriate for general system use.
  35.162 +    // On Win32, for example these rely on QueryPerformanceConter  may have
  35.163 +    // problems with thread-core switching and power modes.
  35.164 +
  35.165 +    // Return a hi-res timer value in mks (1/1000000 of a sec).
  35.166 +    // Generally you want to call this at the start and end of an
  35.167 +    // operation, and pass the difference to
  35.168 +    // TicksToSeconds() to find out how long the operation took. 
  35.169 +    static UInt64  OVR_STDCALL GetProfileTicks();
  35.170 +
  35.171 +    // More convenient zero-based profile timer in seconds. First call initializes 
  35.172 +    // the "zero" value; future calls return the difference. Not thread safe for first call.
  35.173 +    // Due to low precision of Double, may malfunction after long runtime.
  35.174 +    static double  OVR_STDCALL GetProfileSeconds();
  35.175 +
  35.176 +    // Get the raw cycle counter value, providing the maximum possible timer resolution.
  35.177 +    static UInt64  OVR_STDCALL GetRawTicks();
  35.178 +    static UInt64  OVR_STDCALL GetRawFrequency();
  35.179 +
  35.180 +    
  35.181 +    // ***** Tick and time unit conversion.
  35.182 +
  35.183 +    // Convert micro-second ticks value into seconds value.
  35.184 +    static inline double TicksToSeconds(UInt64 ticks)
  35.185 +    {
  35.186 +        return static_cast<double>(ticks) * (1.0 / (double)MksPerSecond);
  35.187 +    }
  35.188 +    // Convert Raw or frequency-unit ticks to seconds based on specified frequency.
  35.189 +    static inline double RawTicksToSeconds(UInt64 rawTicks, UInt64 rawFrequency)
  35.190 +    {
  35.191 +        return static_cast<double>(rawTicks) * rawFrequency;
  35.192 +    }
  35.193 +
  35.194 +private:
  35.195 +    friend class System;
  35.196 +    // System called during program startup/shutdown.
  35.197 +    static void initializeTimerSystem();
  35.198 +    static void shutdownTimerSystem();
  35.199 +};
  35.200 +
  35.201 +
  35.202 +} // Scaleform::Timer
  35.203 +
  35.204 +#endif
    36.1 --- a/libovr/Src/Kernel/OVR_Types.h	Sat Sep 14 17:51:03 2013 +0300
    36.2 +++ b/libovr/Src/Kernel/OVR_Types.h	Sun Sep 15 04:10:05 2013 +0300
    36.3 @@ -1,1 +1,456 @@
    36.4 -/************************************************************************************
    36.5 
    36.6 PublicHeader:   OVR.h
    36.7 Filename    :   OVR_Types.h
    36.8 Content     :   Standard library defines and simple types
    36.9 Created     :   September 19, 2012
   36.10 Notes       : 
   36.11 
   36.12 Copyright   :   Copyright 2012 Oculus VR, Inc. All Rights reserved.
   36.13 
   36.14 Use of this software is subject to the terms of the Oculus license
   36.15 agreement provided at the time of installation or download, or which
   36.16 otherwise accompanies this software in either electronic or hard copy form.
   36.17 
   36.18 ************************************************************************************/
   36.19 
   36.20 #ifndef OVR_Types_H
   36.21 #define OVR_Types_H
   36.22 
   36.23 //-----------------------------------------------------------------------------------
   36.24 // ****** Operating System
   36.25 //
   36.26 // Type definitions exist for the following operating systems: (OVR_OS_x)
   36.27 //
   36.28 //    WIN32    - Win32 (Windows 95/98/ME and Windows NT/2000/XP)
   36.29 //    DARWIN   - Darwin OS (Mac OS X)
   36.30 //    LINUX    - Linux
   36.31 //    ANDROID  - Android
   36.32 //    IPHONE   - iPhone
   36.33 
   36.34 #if (defined(__APPLE__) && (defined(__GNUC__) ||\
   36.35      defined(__xlC__) || defined(__xlc__))) || defined(__MACOS__)
   36.36 #  if (defined(__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__) || defined(__IPHONE_OS_VERSION_MIN_REQUIRED))
   36.37 #    define OVR_OS_IPHONE
   36.38 #  else
   36.39 #    define OVR_OS_DARWIN
   36.40 #    define OVR_OS_MAC
   36.41 #  endif
   36.42 #elif (defined(WIN64) || defined(_WIN64) || defined(__WIN64__))
   36.43 #  define OVR_OS_WIN32
   36.44 #elif (defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__NT__))
   36.45 #  define OVR_OS_WIN32
   36.46 #elif defined(__linux__) || defined(__linux)
   36.47 #  define OVR_OS_LINUX
   36.48 #else
   36.49 #  define OVR_OS_OTHER
   36.50 #endif
   36.51 
   36.52 #if defined(ANDROID)
   36.53 #  define OVR_OS_ANDROID
   36.54 #endif
   36.55 
   36.56 
   36.57 //-----------------------------------------------------------------------------------
   36.58 // ***** CPU Architecture
   36.59 //
   36.60 // The following CPUs are defined: (OVR_CPU_x)
   36.61 //
   36.62 //    X86        - x86 (IA-32)
   36.63 //    X86_64     - x86_64 (amd64)
   36.64 //    PPC        - PowerPC
   36.65 //    PPC64      - PowerPC64
   36.66 //    MIPS       - MIPS
   36.67 //    OTHER      - CPU for which no special support is present or needed
   36.68 
   36.69 
   36.70 #if defined(__x86_64__) || defined(WIN64) || defined(_WIN64) || defined(__WIN64__)
   36.71 #  define OVR_CPU_X86_64
   36.72 #  define OVR_64BIT_POINTERS
   36.73 #elif defined(__i386__) || defined(OVR_OS_WIN32)
   36.74 #  define OVR_CPU_X86
   36.75 #elif defined(__powerpc64__)
   36.76 #  define OVR_CPU_PPC64
   36.77 #elif defined(__ppc__)
   36.78 #  define OVR_CPU_PPC
   36.79 #elif defined(__mips__) || defined(__MIPSEL__)
   36.80 #  define OVR_CPU_MIPS
   36.81 #elif defined(__arm__)
   36.82 #  define OVR_CPU_ARM
   36.83 #else
   36.84 #  define OVR_CPU_OTHER
   36.85 #endif
   36.86 
   36.87 //-----------------------------------------------------------------------------------
   36.88 // ***** Co-Processor Architecture
   36.89 //
   36.90 // The following co-processors are defined: (OVR_CPU_x)
   36.91 //
   36.92 //    SSE        - Available on all modern x86 processors.
   36.93 //    Altivec    - Available on all modern ppc processors.
   36.94 //    Neon       - Available on some armv7+ processors.
   36.95 
   36.96 #if defined(__SSE__) || defined(OVR_OS_WIN32)
   36.97 #  define  OVR_CPU_SSE
   36.98 #endif // __SSE__
   36.99 
  36.100 #if defined( __ALTIVEC__ )
  36.101 #  define OVR_CPU_ALTIVEC
  36.102 #endif // __ALTIVEC__
  36.103 
  36.104 #if defined(__ARM_NEON__)
  36.105 #  define OVR_CPU_ARM_NEON
  36.106 #endif // __ARM_NEON__
  36.107 
  36.108 
  36.109 //-----------------------------------------------------------------------------------
  36.110 // ***** Compiler
  36.111 //
  36.112 //  The following compilers are defined: (OVR_CC_x)
  36.113 //
  36.114 //     MSVC     - Microsoft Visual C/C++
  36.115 //     INTEL    - Intel C++ for Linux / Windows
  36.116 //     GNU      - GNU C++
  36.117 //     ARM      - ARM C/C++
  36.118 
  36.119 #if defined(__INTEL_COMPILER)
  36.120 // Intel 4.0                    = 400
  36.121 // Intel 5.0                    = 500
  36.122 // Intel 6.0                    = 600
  36.123 // Intel 8.0                    = 800
  36.124 // Intel 9.0                    = 900
  36.125 #  define OVR_CC_INTEL       __INTEL_COMPILER
  36.126 
  36.127 #elif defined(_MSC_VER)
  36.128 // MSVC 5.0                     = 1100
  36.129 // MSVC 6.0                     = 1200
  36.130 // MSVC 7.0 (VC2002)            = 1300
  36.131 // MSVC 7.1 (VC2003)            = 1310
  36.132 // MSVC 8.0 (VC2005)            = 1400
  36.133 // MSVC 9.0 (VC2008)            = 1500
  36.134 // MSVC 10.0 (VC2010)           = 1600
  36.135 #  define OVR_CC_MSVC        _MSC_VER
  36.136 
  36.137 #elif defined(__GNUC__)
  36.138 #  define OVR_CC_GNU
  36.139 
  36.140 #elif defined(__CC_ARM)
  36.141 #  define OVR_CC_ARM
  36.142 
  36.143 #else
  36.144 #  error "Oculus does not support this Compiler"
  36.145 #endif
  36.146 
  36.147 
  36.148 //-----------------------------------------------------------------------------------
  36.149 // ***** Compiler Warnings
  36.150 
  36.151 // Disable MSVC warnings
  36.152 #if defined(OVR_CC_MSVC)
  36.153 #  pragma warning(disable : 4127)    // Inconsistent dll linkage
  36.154 #  pragma warning(disable : 4530)    // Exception handling
  36.155 #  if (OVR_CC_MSVC<1300)
  36.156 #    pragma warning(disable : 4514)  // Unreferenced inline function has been removed
  36.157 #    pragma warning(disable : 4710)  // Function not inlined
  36.158 #    pragma warning(disable : 4714)  // _force_inline not inlined
  36.159 #    pragma warning(disable : 4786)  // Debug variable name longer than 255 chars
  36.160 #  endif // (OVR_CC_MSVC<1300)
  36.161 #endif // (OVR_CC_MSVC)
  36.162 
  36.163 
  36.164 
  36.165 // *** Linux Unicode - must come before Standard Includes
  36.166 
  36.167 #ifdef OVR_OS_LINUX
  36.168 // Use glibc unicode functions on linux.
  36.169 #  ifndef  _GNU_SOURCE
  36.170 #    define _GNU_SOURCE
  36.171 #  endif
  36.172 #endif
  36.173 
  36.174 //-----------------------------------------------------------------------------------
  36.175 // ***** Standard Includes
  36.176 //
  36.177 #include    <stddef.h>
  36.178 #include    <limits.h>
  36.179 #include    <float.h>
  36.180 
  36.181 
  36.182 // MSVC Based Memory Leak checking - for now
  36.183 #if defined(OVR_CC_MSVC) && defined(OVR_BUILD_DEBUG)
  36.184 #  define _CRTDBG_MAP_ALLOC
  36.185 #  include <stdlib.h>
  36.186 #  include <crtdbg.h>
  36.187 
  36.188 // Uncomment this to help debug memory leaks under Visual Studio in OVR apps only.
  36.189 // This shouldn't be defined in customer releases.
  36.190 #  ifndef OVR_DEFINE_NEW
  36.191 #    define OVR_DEFINE_NEW new(__FILE__, __LINE__)
  36.192 #    define new OVR_DEFINE_NEW
  36.193 #  endif
  36.194 
  36.195 #endif
  36.196 
  36.197 
  36.198 //-----------------------------------------------------------------------------------
  36.199 // ***** Type definitions for Common Systems
  36.200 
  36.201 namespace OVR {
  36.202 
  36.203 typedef char            Char;
  36.204 
  36.205 // Pointer-sized integer
  36.206 typedef size_t          UPInt;
  36.207 typedef ptrdiff_t       SPInt;
  36.208 
  36.209 
  36.210 #if defined(OVR_OS_WIN32)
  36.211 
  36.212 typedef char            SByte;  // 8 bit Integer (Byte)
  36.213 typedef unsigned char   UByte;
  36.214 typedef short           SInt16; // 16 bit Integer (Word)
  36.215 typedef unsigned short  UInt16;
  36.216 typedef long            SInt32; // 32 bit Integer
  36.217 typedef unsigned long   UInt32;
  36.218 typedef __int64         SInt64; // 64 bit Integer (QWord)
  36.219 typedef unsigned __int64 UInt64;
  36.220 
  36.221  
  36.222 #elif defined(OVR_OS_MAC) || defined(OVR_OS_IPHONE) || defined(OVR_CC_GNU)
  36.223 
  36.224 typedef int             SByte  __attribute__((__mode__ (__QI__)));
  36.225 typedef unsigned int    UByte  __attribute__((__mode__ (__QI__)));
  36.226 typedef int             SInt16 __attribute__((__mode__ (__HI__)));
  36.227 typedef unsigned int    UInt16 __attribute__((__mode__ (__HI__)));
  36.228 typedef int             SInt32 __attribute__((__mode__ (__SI__)));
  36.229 typedef unsigned int    UInt32 __attribute__((__mode__ (__SI__)));
  36.230 typedef int             SInt64 __attribute__((__mode__ (__DI__)));
  36.231 typedef unsigned int    UInt64 __attribute__((__mode__ (__DI__)));
  36.232 
  36.233 #else
  36.234 
  36.235 #include <sys/types.h>
  36.236 typedef int8_t          SByte;
  36.237 typedef uint8_t         UByte;
  36.238 typedef int16_t         SInt16;
  36.239 typedef uint16_t        UInt16;
  36.240 typedef int32_t         SInt32;
  36.241 typedef uint32_t        UInt32;
  36.242 typedef int64_t         SInt64;
  36.243 typedef uint64_t        UInt64;
  36.244 
  36.245 #endif
  36.246 
  36.247 
  36.248 // ***** BaseTypes Namespace
  36.249 
  36.250 // BaseTypes namespace is explicitly declared to allow base types to be used
  36.251 // by customers directly without other contents of OVR namespace.
  36.252 //
  36.253 // Its is expected that GFx samples will declare 'using namespace OVR::BaseTypes'
  36.254 // to allow using these directly without polluting the target scope with other
  36.255 // OVR declarations, such as Ptr<>, String or Mutex.
  36.256 namespace BaseTypes
  36.257 {
  36.258     using OVR::UPInt;
  36.259     using OVR::SPInt;
  36.260     using OVR::UByte;
  36.261     using OVR::SByte;
  36.262     using OVR::UInt16;
  36.263     using OVR::SInt16;
  36.264     using OVR::UInt32;
  36.265     using OVR::SInt32;
  36.266     using OVR::UInt64;
  36.267     using OVR::SInt64;
  36.268 } // OVR::BaseTypes
  36.269 
  36.270 } // OVR
  36.271 
  36.272 
  36.273 //-----------------------------------------------------------------------------------
  36.274 // ***** Macro Definitions
  36.275 //
  36.276 // We define the following:
  36.277 //
  36.278 //  OVR_BYTE_ORDER      - Defined to either OVR_LITTLE_ENDIAN or OVR_BIG_ENDIAN
  36.279 //  OVR_FORCE_INLINE    - Forces inline expansion of function
  36.280 //  OVR_ASM             - Assembly language prefix
  36.281 //  OVR_STR             - Prefixes string with L"" if building unicode
  36.282 // 
  36.283 //  OVR_STDCALL         - Use stdcall calling convention (Pascal arg order)
  36.284 //  OVR_CDECL           - Use cdecl calling convention (C argument order)
  36.285 //  OVR_FASTCALL        - Use fastcall calling convention (registers)
  36.286 //
  36.287 
  36.288 // Byte order constants, OVR_BYTE_ORDER is defined to be one of these.
  36.289 #define OVR_LITTLE_ENDIAN       1
  36.290 #define OVR_BIG_ENDIAN          2
  36.291 
  36.292 
  36.293 // Force inline substitute - goes before function declaration
  36.294 #if defined(OVR_CC_MSVC)
  36.295 #  define OVR_FORCE_INLINE  __forceinline
  36.296 #elif defined(OVR_CC_GNU)
  36.297 #  define OVR_FORCE_INLINE  __attribute__((always_inline)) inline
  36.298 #else
  36.299 #  define OVR_FORCE_INLINE  inline
  36.300 #endif  // OVR_CC_MSVC
  36.301 
  36.302 
  36.303 #if defined(OVR_OS_WIN32)
  36.304     
  36.305     // ***** Win32
  36.306 
  36.307     // Byte order
  36.308     #define OVR_BYTE_ORDER    OVR_LITTLE_ENDIAN
  36.309 
  36.310     // Calling convention - goes after function return type but before function name
  36.311     #ifdef __cplusplus_cli
  36.312     #  define OVR_FASTCALL      __stdcall
  36.313     #else
  36.314     #  define OVR_FASTCALL      __fastcall
  36.315     #endif
  36.316 
  36.317     #define OVR_STDCALL         __stdcall
  36.318     #define OVR_CDECL           __cdecl
  36.319 
  36.320 
  36.321     // Assembly macros
  36.322     #if defined(OVR_CC_MSVC)
  36.323     #  define OVR_ASM           _asm
  36.324     #else
  36.325     #  define OVR_ASM           asm
  36.326     #endif // (OVR_CC_MSVC)
  36.327 
  36.328     #ifdef UNICODE
  36.329     #  define OVR_STR(str)      L##str
  36.330     #else
  36.331     #  define OVR_STR(str)      str
  36.332     #endif // UNICODE
  36.333 
  36.334 #else
  36.335 
  36.336     // **** Standard systems
  36.337 
  36.338     #if (defined(BYTE_ORDER) && (BYTE_ORDER == BIG_ENDIAN))|| \
  36.339         (defined(_BYTE_ORDER) && (_BYTE_ORDER == _BIG_ENDIAN))
  36.340     #  define OVR_BYTE_ORDER    OVR_BIG_ENDIAN
  36.341     #elif (defined(__ARMEB__) || defined(OVR_CPU_PPC) || defined(OVR_CPU_PPC64))
  36.342     #  define OVR_BYTE_ORDER    OVR_BIG_ENDIAN
  36.343     #else
  36.344     #  define OVR_BYTE_ORDER    OVR_LITTLE_ENDIAN
  36.345     #endif
  36.346     
  36.347     // Assembly macros
  36.348     #define OVR_ASM                  __asm__
  36.349     #define OVR_ASM_PROC(procname)   OVR_ASM
  36.350     #define OVR_ASM_END              OVR_ASM
  36.351     
  36.352     // Calling convention - goes after function return type but before function name
  36.353     #define OVR_FASTCALL
  36.354     #define OVR_STDCALL
  36.355     #define OVR_CDECL
  36.356 
  36.357 #endif // defined(OVR_OS_WIN32)
  36.358 
  36.359 
  36.360 
  36.361 //-----------------------------------------------------------------------------------
  36.362 // ***** OVR_DEBUG_BREAK, OVR_ASSERT
  36.363 //
  36.364 // If not in debug build, macros do nothing
  36.365 #ifndef OVR_BUILD_DEBUG
  36.366 
  36.367 #  define OVR_DEBUG_BREAK  ((void)0)
  36.368 #  define OVR_ASSERT(p)    ((void)0)
  36.369 
  36.370 #else 
  36.371 
  36.372 // Microsoft Win32 specific debugging support
  36.373 #if defined(OVR_OS_WIN32)
  36.374 #  ifdef OVR_CPU_X86
  36.375 #    if defined(__cplusplus_cli)
  36.376 #      define OVR_DEBUG_BREAK   do { __debugbreak(); } while(0)
  36.377 #    elif defined(OVR_CC_GNU)
  36.378 #      define OVR_DEBUG_BREAK   do { OVR_ASM("int $3\n\t"); } while(0)
  36.379 #    else
  36.380 #      define OVR_DEBUG_BREAK   do { OVR_ASM int 3 } while (0)
  36.381 #    endif
  36.382 #  else
  36.383 #    define OVR_DEBUG_BREAK     do { __debugbreak(); } while(0)
  36.384 #  endif
  36.385 // Unix specific debugging support
  36.386 #elif defined(OVR_CPU_X86) || defined(OVR_CPU_X86_64)
  36.387 #  define OVR_DEBUG_BREAK       do { OVR_ASM("int $3\n\t"); } while(0)
  36.388 #else
  36.389 #  define OVR_DEBUG_BREAK       do { *((int *) 0) = 1; } while(0)
  36.390 #endif
  36.391 
  36.392 // This will cause compiler breakpoint
  36.393 #define OVR_ASSERT(p)           do { if (!(p))  { OVR_DEBUG_BREAK; } } while(0)
  36.394 
  36.395 #endif // OVR_BUILD_DEBUG
  36.396 
  36.397 
  36.398 // Compile-time assert; produces compiler error if condition is false
  36.399 #define OVR_COMPILER_ASSERT(x)  { int zero = 0; switch(zero) {case 0: case x:;} }
  36.400 
  36.401 
  36.402 
  36.403 //-----------------------------------------------------------------------------------
  36.404 // ***** OVR_UNUSED - Unused Argument handling
  36.405 
  36.406 // Macro to quiet compiler warnings about unused parameters/variables.
  36.407 #if defined(OVR_CC_GNU)
  36.408 #  define   OVR_UNUSED(a)   do {__typeof__ (&a) __attribute__ ((unused)) __tmp = &a; } while(0)
  36.409 #else
  36.410 #  define   OVR_UNUSED(a)   (a)
  36.411 #endif
  36.412 
  36.413 #define     OVR_UNUSED1(a1) OVR_UNUSED(a1)
  36.414 #define     OVR_UNUSED2(a1,a2) OVR_UNUSED(a1); OVR_UNUSED(a2)
  36.415 #define     OVR_UNUSED3(a1,a2,a3) OVR_UNUSED2(a1,a2); OVR_UNUSED(a3)
  36.416 #define     OVR_UNUSED4(a1,a2,a3,a4) OVR_UNUSED3(a1,a2,a3); OVR_UNUSED(a4)
  36.417 #define     OVR_UNUSED5(a1,a2,a3,a4,a5) OVR_UNUSED4(a1,a2,a3,a4); OVR_UNUSED(a5)
  36.418 #define     OVR_UNUSED6(a1,a2,a3,a4,a5,a6) OVR_UNUSED4(a1,a2,a3,a4); OVR_UNUSED2(a5,a6)
  36.419 #define     OVR_UNUSED7(a1,a2,a3,a4,a5,a6,a7) OVR_UNUSED4(a1,a2,a3,a4); OVR_UNUSED3(a5,a6,a7)
  36.420 #define     OVR_UNUSED8(a1,a2,a3,a4,a5,a6,a7,a8) OVR_UNUSED4(a1,a2,a3,a4); OVR_UNUSED4(a5,a6,a7,a8)
  36.421 #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)
  36.422 
  36.423 
  36.424 //-----------------------------------------------------------------------------------
  36.425 // ***** Configuration Macros
  36.426 
  36.427 // SF Build type
  36.428 #ifdef OVR_BUILD_DEBUG
  36.429 #  define OVR_BUILD_STRING  "Debug"
  36.430 #else
  36.431 #  define OVR_BUILD_STRING  "Release"
  36.432 #endif
  36.433 
  36.434 
  36.435 //// Enables SF Debugging information
  36.436 //# define OVR_BUILD_DEBUG
  36.437 
  36.438 // OVR_DEBUG_STATEMENT injects a statement only in debug builds.
  36.439 // OVR_DEBUG_SELECT injects first argument in debug builds, second argument otherwise.
  36.440 #ifdef OVR_BUILD_DEBUG
  36.441 #define OVR_DEBUG_STATEMENT(s)   s
  36.442 #define OVR_DEBUG_SELECT(d, nd)  d
  36.443 #else
  36.444 #define OVR_DEBUG_STATEMENT(s)
  36.445 #define OVR_DEBUG_SELECT(d, nd)  nd
  36.446 #endif
  36.447 
  36.448 
  36.449 #define OVR_ENABLE_THREADS
  36.450 //
  36.451 // Prevents OVR from defining new within
  36.452 // type macros, so developers can override
  36.453 // new using the #define new new(...) trick
  36.454 // - used with OVR_DEFINE_NEW macro
  36.455 //# define OVR_BUILD_DEFINE_NEW
  36.456 //
  36.457 
  36.458 
  36.459 #endif  // OVR_Types_h
  36.460 \ No newline at end of file
  36.461 +/************************************************************************************
  36.462 +
  36.463 +PublicHeader:   OVR.h
  36.464 +Filename    :   OVR_Types.h
  36.465 +Content     :   Standard library defines and simple types
  36.466 +Created     :   September 19, 2012
  36.467 +Notes       : 
  36.468 +
  36.469 +Copyright   :   Copyright 2012 Oculus VR, Inc. All Rights reserved.
  36.470 +
  36.471 +Use of this software is subject to the terms of the Oculus license
  36.472 +agreement provided at the time of installation or download, or which
  36.473 +otherwise accompanies this software in either electronic or hard copy form.
  36.474 +
  36.475 +************************************************************************************/
  36.476 +
  36.477 +#ifndef OVR_Types_H
  36.478 +#define OVR_Types_H
  36.479 +
  36.480 +//-----------------------------------------------------------------------------------
  36.481 +// ****** Operating System
  36.482 +//
  36.483 +// Type definitions exist for the following operating systems: (OVR_OS_x)
  36.484 +//
  36.485 +//    WIN32    - Win32 (Windows 95/98/ME and Windows NT/2000/XP)
  36.486 +//    DARWIN   - Darwin OS (Mac OS X)
  36.487 +//    LINUX    - Linux
  36.488 +//    ANDROID  - Android
  36.489 +//    IPHONE   - iPhone
  36.490 +
  36.491 +#if (defined(__APPLE__) && (defined(__GNUC__) ||\
  36.492 +     defined(__xlC__) || defined(__xlc__))) || defined(__MACOS__)
  36.493 +#  if (defined(__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__) || defined(__IPHONE_OS_VERSION_MIN_REQUIRED))
  36.494 +#    define OVR_OS_IPHONE
  36.495 +#  else
  36.496 +#    define OVR_OS_DARWIN
  36.497 +#    define OVR_OS_MAC
  36.498 +#  endif
  36.499 +#elif (defined(WIN64) || defined(_WIN64) || defined(__WIN64__))
  36.500 +#  define OVR_OS_WIN32
  36.501 +#elif (defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__NT__))
  36.502 +#  define OVR_OS_WIN32
  36.503 +#elif defined(__linux__) || defined(__linux)
  36.504 +#  define OVR_OS_LINUX
  36.505 +#else
  36.506 +#  define OVR_OS_OTHER
  36.507 +#endif
  36.508 +
  36.509 +#if defined(ANDROID)
  36.510 +#  define OVR_OS_ANDROID
  36.511 +#endif
  36.512 +
  36.513 +
  36.514 +//-----------------------------------------------------------------------------------
  36.515 +// ***** CPU Architecture
  36.516 +//
  36.517 +// The following CPUs are defined: (OVR_CPU_x)
  36.518 +//
  36.519 +//    X86        - x86 (IA-32)
  36.520 +//    X86_64     - x86_64 (amd64)
  36.521 +//    PPC        - PowerPC
  36.522 +//    PPC64      - PowerPC64
  36.523 +//    MIPS       - MIPS
  36.524 +//    OTHER      - CPU for which no special support is present or needed
  36.525 +
  36.526 +
  36.527 +#if defined(__x86_64__) || defined(WIN64) || defined(_WIN64) || defined(__WIN64__)
  36.528 +#  define OVR_CPU_X86_64
  36.529 +#  define OVR_64BIT_POINTERS
  36.530 +#elif defined(__i386__) || defined(OVR_OS_WIN32)
  36.531 +#  define OVR_CPU_X86
  36.532 +#elif defined(__powerpc64__)
  36.533 +#  define OVR_CPU_PPC64
  36.534 +#elif defined(__ppc__)
  36.535 +#  define OVR_CPU_PPC
  36.536 +#elif defined(__mips__) || defined(__MIPSEL__)
  36.537 +#  define OVR_CPU_MIPS
  36.538 +#elif defined(__arm__)
  36.539 +#  define OVR_CPU_ARM
  36.540 +#else
  36.541 +#  define OVR_CPU_OTHER
  36.542 +#endif
  36.543 +
  36.544 +//-----------------------------------------------------------------------------------
  36.545 +// ***** Co-Processor Architecture
  36.546 +//
  36.547 +// The following co-processors are defined: (OVR_CPU_x)
  36.548 +//
  36.549 +//    SSE        - Available on all modern x86 processors.
  36.550 +//    Altivec    - Available on all modern ppc processors.
  36.551 +//    Neon       - Available on some armv7+ processors.
  36.552 +
  36.553 +#if defined(__SSE__) || defined(OVR_OS_WIN32)
  36.554 +#  define  OVR_CPU_SSE
  36.555 +#endif // __SSE__
  36.556 +
  36.557 +#if defined( __ALTIVEC__ )
  36.558 +#  define OVR_CPU_ALTIVEC
  36.559 +#endif // __ALTIVEC__
  36.560 +
  36.561 +#if defined(__ARM_NEON__)
  36.562 +#  define OVR_CPU_ARM_NEON
  36.563 +#endif // __ARM_NEON__
  36.564 +
  36.565 +
  36.566 +//-----------------------------------------------------------------------------------
  36.567 +// ***** Compiler
  36.568 +//
  36.569 +//  The following compilers are defined: (OVR_CC_x)
  36.570 +//
  36.571 +//     MSVC     - Microsoft Visual C/C++
  36.572 +//     INTEL    - Intel C++ for Linux / Windows
  36.573 +//     GNU      - GNU C++
  36.574 +//     ARM      - ARM C/C++
  36.575 +
  36.576 +#if defined(__INTEL_COMPILER)
  36.577 +// Intel 4.0                    = 400
  36.578 +// Intel 5.0                    = 500
  36.579 +// Intel 6.0                    = 600
  36.580 +// Intel 8.0                    = 800
  36.581 +// Intel 9.0                    = 900
  36.582 +#  define OVR_CC_INTEL       __INTEL_COMPILER
  36.583 +
  36.584 +#elif defined(_MSC_VER)
  36.585 +// MSVC 5.0                     = 1100
  36.586 +// MSVC 6.0                     = 1200
  36.587 +// MSVC 7.0 (VC2002)            = 1300
  36.588 +// MSVC 7.1 (VC2003)            = 1310
  36.589 +// MSVC 8.0 (VC2005)            = 1400
  36.590 +// MSVC 9.0 (VC2008)            = 1500
  36.591 +// MSVC 10.0 (VC2010)           = 1600
  36.592 +#  define OVR_CC_MSVC        _MSC_VER
  36.593 +
  36.594 +#elif defined(__GNUC__)
  36.595 +#  define OVR_CC_GNU
  36.596 +
  36.597 +#elif defined(__CC_ARM)
  36.598 +#  define OVR_CC_ARM
  36.599 +
  36.600 +#else
  36.601 +#  error "Oculus does not support this Compiler"
  36.602 +#endif
  36.603 +
  36.604 +
  36.605 +//-----------------------------------------------------------------------------------
  36.606 +// ***** Compiler Warnings
  36.607 +
  36.608 +// Disable MSVC warnings
  36.609 +#if defined(OVR_CC_MSVC)
  36.610 +#  pragma warning(disable : 4127)    // Inconsistent dll linkage
  36.611 +#  pragma warning(disable : 4530)    // Exception handling
  36.612 +#  if (OVR_CC_MSVC<1300)
  36.613 +#    pragma warning(disable : 4514)  // Unreferenced inline function has been removed
  36.614 +#    pragma warning(disable : 4710)  // Function not inlined
  36.615 +#    pragma warning(disable : 4714)  // _force_inline not inlined
  36.616 +#    pragma warning(disable : 4786)  // Debug variable name longer than 255 chars
  36.617 +#  endif // (OVR_CC_MSVC<1300)
  36.618 +#endif // (OVR_CC_MSVC)
  36.619 +
  36.620 +
  36.621 +
  36.622 +// *** Linux Unicode - must come before Standard Includes
  36.623 +
  36.624 +#ifdef OVR_OS_LINUX
  36.625 +// Use glibc unicode functions on linux.
  36.626 +#  ifndef  _GNU_SOURCE
  36.627 +#    define _GNU_SOURCE
  36.628 +#  endif
  36.629 +#endif
  36.630 +
  36.631 +//-----------------------------------------------------------------------------------
  36.632 +// ***** Standard Includes
  36.633 +//
  36.634 +#include    <stddef.h>
  36.635 +#include    <limits.h>
  36.636 +#include    <float.h>
  36.637 +
  36.638 +
  36.639 +// MSVC Based Memory Leak checking - for now
  36.640 +#if defined(OVR_CC_MSVC) && defined(OVR_BUILD_DEBUG)
  36.641 +#  define _CRTDBG_MAP_ALLOC
  36.642 +#  include <stdlib.h>
  36.643 +#  include <crtdbg.h>
  36.644 +
  36.645 +// Uncomment this to help debug memory leaks under Visual Studio in OVR apps only.
  36.646 +// This shouldn't be defined in customer releases.
  36.647 +#  ifndef OVR_DEFINE_NEW
  36.648 +#    define OVR_DEFINE_NEW new(__FILE__, __LINE__)
  36.649 +#    define new OVR_DEFINE_NEW
  36.650 +#  endif
  36.651 +
  36.652 +#endif
  36.653 +
  36.654 +
  36.655 +//-----------------------------------------------------------------------------------
  36.656 +// ***** Type definitions for Common Systems
  36.657 +
  36.658 +namespace OVR {
  36.659 +
  36.660 +typedef char            Char;
  36.661 +
  36.662 +// Pointer-sized integer
  36.663 +typedef size_t          UPInt;
  36.664 +typedef ptrdiff_t       SPInt;
  36.665 +
  36.666 +
  36.667 +#if defined(OVR_OS_WIN32)
  36.668 +
  36.669 +typedef char            SByte;  // 8 bit Integer (Byte)
  36.670 +typedef unsigned char   UByte;
  36.671 +typedef short           SInt16; // 16 bit Integer (Word)
  36.672 +typedef unsigned short  UInt16;
  36.673 +typedef long            SInt32; // 32 bit Integer
  36.674 +typedef unsigned long   UInt32;
  36.675 +typedef __int64         SInt64; // 64 bit Integer (QWord)
  36.676 +typedef unsigned __int64 UInt64;
  36.677 +
  36.678 + 
  36.679 +#elif defined(OVR_OS_MAC) || defined(OVR_OS_IPHONE) || defined(OVR_CC_GNU)
  36.680 +
  36.681 +typedef int             SByte  __attribute__((__mode__ (__QI__)));
  36.682 +typedef unsigned int    UByte  __attribute__((__mode__ (__QI__)));
  36.683 +typedef int             SInt16 __attribute__((__mode__ (__HI__)));
  36.684 +typedef unsigned int    UInt16 __attribute__((__mode__ (__HI__)));
  36.685 +typedef int             SInt32 __attribute__((__mode__ (__SI__)));
  36.686 +typedef unsigned int    UInt32 __attribute__((__mode__ (__SI__)));
  36.687 +typedef int             SInt64 __attribute__((__mode__ (__DI__)));
  36.688 +typedef unsigned int    UInt64 __attribute__((__mode__ (__DI__)));
  36.689 +
  36.690 +#else
  36.691 +
  36.692 +#include <sys/types.h>
  36.693 +typedef int8_t          SByte;
  36.694 +typedef uint8_t         UByte;
  36.695 +typedef int16_t         SInt16;
  36.696 +typedef uint16_t        UInt16;
  36.697 +typedef int32_t         SInt32;
  36.698 +typedef uint32_t        UInt32;
  36.699 +typedef int64_t         SInt64;
  36.700 +typedef uint64_t        UInt64;
  36.701 +
  36.702 +#endif
  36.703 +
  36.704 +
  36.705 +// ***** BaseTypes Namespace
  36.706 +
  36.707 +// BaseTypes namespace is explicitly declared to allow base types to be used
  36.708 +// by customers directly without other contents of OVR namespace.
  36.709 +//
  36.710 +// Its is expected that GFx samples will declare 'using namespace OVR::BaseTypes'
  36.711 +// to allow using these directly without polluting the target scope with other
  36.712 +// OVR declarations, such as Ptr<>, String or Mutex.
  36.713 +namespace BaseTypes
  36.714 +{
  36.715 +    using OVR::UPInt;
  36.716 +    using OVR::SPInt;
  36.717 +    using OVR::UByte;
  36.718 +    using OVR::SByte;
  36.719 +    using OVR::UInt16;
  36.720 +    using OVR::SInt16;
  36.721 +    using OVR::UInt32;
  36.722 +    using OVR::SInt32;
  36.723 +    using OVR::UInt64;
  36.724 +    using OVR::SInt64;
  36.725 +} // OVR::BaseTypes
  36.726 +
  36.727 +} // OVR
  36.728 +
  36.729 +
  36.730 +//-----------------------------------------------------------------------------------
  36.731 +// ***** Macro Definitions
  36.732 +//
  36.733 +// We define the following:
  36.734 +//
  36.735 +//  OVR_BYTE_ORDER      - Defined to either OVR_LITTLE_ENDIAN or OVR_BIG_ENDIAN
  36.736 +//  OVR_FORCE_INLINE    - Forces inline expansion of function
  36.737 +//  OVR_ASM             - Assembly language prefix
  36.738 +//  OVR_STR             - Prefixes string with L"" if building unicode
  36.739 +// 
  36.740 +//  OVR_STDCALL         - Use stdcall calling convention (Pascal arg order)
  36.741 +//  OVR_CDECL           - Use cdecl calling convention (C argument order)
  36.742 +//  OVR_FASTCALL        - Use fastcall calling convention (registers)
  36.743 +//
  36.744 +
  36.745 +// Byte order constants, OVR_BYTE_ORDER is defined to be one of these.
  36.746 +#define OVR_LITTLE_ENDIAN       1
  36.747 +#define OVR_BIG_ENDIAN          2
  36.748 +
  36.749 +
  36.750 +// Force inline substitute - goes before function declaration
  36.751 +#if defined(OVR_CC_MSVC)
  36.752 +#  define OVR_FORCE_INLINE  __forceinline
  36.753 +#elif defined(OVR_CC_GNU)
  36.754 +#  define OVR_FORCE_INLINE  __attribute__((always_inline)) inline
  36.755 +#else
  36.756 +#  define OVR_FORCE_INLINE  inline
  36.757 +#endif  // OVR_CC_MSVC
  36.758 +
  36.759 +
  36.760 +#if defined(OVR_OS_WIN32)
  36.761 +    
  36.762 +    // ***** Win32
  36.763 +
  36.764 +    // Byte order
  36.765 +    #define OVR_BYTE_ORDER    OVR_LITTLE_ENDIAN
  36.766 +
  36.767 +    // Calling convention - goes after function return type but before function name
  36.768 +    #ifdef __cplusplus_cli
  36.769 +    #  define OVR_FASTCALL      __stdcall
  36.770 +    #else
  36.771 +    #  define OVR_FASTCALL      __fastcall
  36.772 +    #endif
  36.773 +
  36.774 +    #define OVR_STDCALL         __stdcall
  36.775 +    #define OVR_CDECL           __cdecl
  36.776 +
  36.777 +
  36.778 +    // Assembly macros
  36.779 +    #if defined(OVR_CC_MSVC)
  36.780 +    #  define OVR_ASM           _asm
  36.781 +    #else
  36.782 +    #  define OVR_ASM           asm
  36.783 +    #endif // (OVR_CC_MSVC)
  36.784 +
  36.785 +    #ifdef UNICODE
  36.786 +    #  define OVR_STR(str)      L##str
  36.787 +    #else
  36.788 +    #  define OVR_STR(str)      str
  36.789 +    #endif // UNICODE
  36.790 +
  36.791 +#else
  36.792 +
  36.793 +    // **** Standard systems
  36.794 +
  36.795 +    #if (defined(BYTE_ORDER) && (BYTE_ORDER == BIG_ENDIAN))|| \
  36.796 +        (defined(_BYTE_ORDER) && (_BYTE_ORDER == _BIG_ENDIAN))
  36.797 +    #  define OVR_BYTE_ORDER    OVR_BIG_ENDIAN
  36.798 +    #elif (defined(__ARMEB__) || defined(OVR_CPU_PPC) || defined(OVR_CPU_PPC64))
  36.799 +    #  define OVR_BYTE_ORDER    OVR_BIG_ENDIAN
  36.800 +    #else
  36.801 +    #  define OVR_BYTE_ORDER    OVR_LITTLE_ENDIAN
  36.802 +    #endif
  36.803 +    
  36.804 +    // Assembly macros
  36.805 +    #define OVR_ASM                  __asm__
  36.806 +    #define OVR_ASM_PROC(procname)   OVR_ASM
  36.807 +    #define OVR_ASM_END              OVR_ASM
  36.808 +    
  36.809 +    // Calling convention - goes after function return type but before function name
  36.810 +    #define OVR_FASTCALL
  36.811 +    #define OVR_STDCALL
  36.812 +    #define OVR_CDECL
  36.813 +
  36.814 +#endif // defined(OVR_OS_WIN32)
  36.815 +
  36.816 +
  36.817 +
  36.818 +//-----------------------------------------------------------------------------------
  36.819 +// ***** OVR_DEBUG_BREAK, OVR_ASSERT
  36.820 +//
  36.821 +// If not in debug build, macros do nothing
  36.822 +#ifndef OVR_BUILD_DEBUG
  36.823 +
  36.824 +#  define OVR_DEBUG_BREAK  ((void)0)
  36.825 +#  define OVR_ASSERT(p)    ((void)0)
  36.826 +
  36.827 +#else 
  36.828 +
  36.829 +// Microsoft Win32 specific debugging support
  36.830 +#if defined(OVR_OS_WIN32)
  36.831 +#  ifdef OVR_CPU_X86
  36.832 +#    if defined(__cplusplus_cli)
  36.833 +#      define OVR_DEBUG_BREAK   do { __debugbreak(); } while(0)
  36.834 +#    elif defined(OVR_CC_GNU)
  36.835 +#      define OVR_DEBUG_BREAK   do { OVR_ASM("int $3\n\t"); } while(0)
  36.836 +#    else
  36.837 +#      define OVR_DEBUG_BREAK   do { OVR_ASM int 3 } while (0)
  36.838 +#    endif
  36.839 +#  else
  36.840 +#    define OVR_DEBUG_BREAK     do { __debugbreak(); } while(0)
  36.841 +#  endif
  36.842 +// Unix specific debugging support
  36.843 +#elif defined(OVR_CPU_X86) || defined(OVR_CPU_X86_64)
  36.844 +#  define OVR_DEBUG_BREAK       do { OVR_ASM("int $3\n\t"); } while(0)
  36.845 +#else
  36.846 +#  define OVR_DEBUG_BREAK       do { *((int *) 0) = 1; } while(0)
  36.847 +#endif
  36.848 +
  36.849 +// This will cause compiler breakpoint
  36.850 +#define OVR_ASSERT(p)           do { if (!(p))  { OVR_DEBUG_BREAK; } } while(0)
  36.851 +
  36.852 +#endif // OVR_BUILD_DEBUG
  36.853 +
  36.854 +
  36.855 +// Compile-time assert; produces compiler error if condition is false
  36.856 +#define OVR_COMPILER_ASSERT(x)  { int zero = 0; switch(zero) {case 0: case x:;} }
  36.857 +
  36.858 +
  36.859 +
  36.860 +//-----------------------------------------------------------------------------------
  36.861 +// ***** OVR_UNUSED - Unused Argument handling
  36.862 +
  36.863 +// Macro to quiet compiler warnings about unused parameters/variables.
  36.864 +#if defined(OVR_CC_GNU)
  36.865 +#  define   OVR_UNUSED(a)   do {__typeof__ (&a) __attribute__ ((unused)) __tmp = &a; } while(0)
  36.866 +#else
  36.867 +#  define   OVR_UNUSED(a)   (a)
  36.868 +#endif
  36.869 +
  36.870 +#define     OVR_UNUSED1(a1) OVR_UNUSED(a1)
  36.871 +#define     OVR_UNUSED2(a1,a2) OVR_UNUSED(a1); OVR_UNUSED(a2)
  36.872 +#define     OVR_UNUSED3(a1,a2,a3) OVR_UNUSED2(a1,a2); OVR_UNUSED(a3)
  36.873 +#define     OVR_UNUSED4(a1,a2,a3,a4) OVR_UNUSED3(a1,a2,a3); OVR_UNUSED(a4)
  36.874 +#define     OVR_UNUSED5(a1,a2,a3,a4,a5) OVR_UNUSED4(a1,a2,a3,a4); OVR_UNUSED(a5)
  36.875 +#define     OVR_UNUSED6(a1,a2,a3,a4,a5,a6) OVR_UNUSED4(a1,a2,a3,a4); OVR_UNUSED2(a5,a6)
  36.876 +#define     OVR_UNUSED7(a1,a2,a3,a4,a5,a6,a7) OVR_UNUSED4(a1,a2,a3,a4); OVR_UNUSED3(a5,a6,a7)
  36.877 +#define     OVR_UNUSED8(a1,a2,a3,a4,a5,a6,a7,a8) OVR_UNUSED4(a1,a2,a3,a4); OVR_UNUSED4(a5,a6,a7,a8)
  36.878 +#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)
  36.879 +
  36.880 +
  36.881 +//-----------------------------------------------------------------------------------
  36.882 +// ***** Configuration Macros
  36.883 +
  36.884 +// SF Build type
  36.885 +#ifdef OVR_BUILD_DEBUG
  36.886 +#  define OVR_BUILD_STRING  "Debug"
  36.887 +#else
  36.888 +#  define OVR_BUILD_STRING  "Release"
  36.889 +#endif
  36.890 +
  36.891 +
  36.892 +//// Enables SF Debugging information
  36.893 +//# define OVR_BUILD_DEBUG
  36.894 +
  36.895 +// OVR_DEBUG_STATEMENT injects a statement only in debug builds.
  36.896 +// OVR_DEBUG_SELECT injects first argument in debug builds, second argument otherwise.
  36.897 +#ifdef OVR_BUILD_DEBUG
  36.898 +#define OVR_DEBUG_STATEMENT(s)   s
  36.899 +#define OVR_DEBUG_SELECT(d, nd)  d
  36.900 +#else
  36.901 +#define OVR_DEBUG_STATEMENT(s)
  36.902 +#define OVR_DEBUG_SELECT(d, nd)  nd
  36.903 +#endif
  36.904 +
  36.905 +
  36.906 +#define OVR_ENABLE_THREADS
  36.907 +//
  36.908 +// Prevents OVR from defining new within
  36.909 +// type macros, so developers can override
  36.910 +// new using the #define new new(...) trick
  36.911 +// - used with OVR_DEFINE_NEW macro
  36.912 +//# define OVR_BUILD_DEFINE_NEW
  36.913 +//
  36.914 +
  36.915 +
  36.916 +#endif  // OVR_Types_h
    37.1 --- a/libovr/Src/Kernel/OVR_UTF8Util.cpp	Sat Sep 14 17:51:03 2013 +0300
    37.2 +++ b/libovr/Src/Kernel/OVR_UTF8Util.cpp	Sun Sep 15 04:10:05 2013 +0300
    37.3 @@ -1,1 +1,545 @@
    37.4 -/**************************************************************************
    37.5 
    37.6 Filename    :   OVR_UTF8Util.cpp
    37.7 Content     :   UTF8 Unicode character encoding/decoding support
    37.8 Created     :   September 19, 2012
    37.9 Notes       : 
   37.10 Notes       :   Much useful info at "UTF-8 and Unicode FAQ"
   37.11                 http://www.cl.cam.ac.uk/~mgk25/unicode.html
   37.12 
   37.13 Copyright   :   Copyright 2012 Oculus VR, Inc. All Rights reserved.
   37.14 
   37.15 Use of this software is subject to the terms of the Oculus license
   37.16 agreement provided at the time of installation or download, or which
   37.17 otherwise accompanies this software in either electronic or hard copy form.
   37.18 
   37.19 ************************************************************************************/
   37.20 
   37.21 #include "OVR_UTF8Util.h"
   37.22 
   37.23 namespace OVR { namespace UTF8Util {
   37.24 
   37.25 SPInt OVR_STDCALL GetLength(const char* buf, SPInt buflen)
   37.26 {
   37.27     const char* p = buf;
   37.28     SPInt length = 0;
   37.29 
   37.30     if (buflen != -1)
   37.31     {
   37.32         while (p - buf < buflen)
   37.33         {
   37.34             // We should be able to have ASStrings with 0 in the middle.
   37.35             UTF8Util::DecodeNextChar_Advance0(&p);
   37.36             length++;
   37.37         }
   37.38     }
   37.39     else
   37.40     {
   37.41         while (UTF8Util::DecodeNextChar_Advance0(&p))
   37.42             length++;
   37.43     }
   37.44     
   37.45     return length;
   37.46 }
   37.47 
   37.48 UInt32 OVR_STDCALL GetCharAt(SPInt index, const char* putf8str, SPInt length)
   37.49 {
   37.50     const char* buf = putf8str;
   37.51     UInt32  c = 0;
   37.52 
   37.53     if (length != -1)
   37.54     {
   37.55         while (buf - putf8str < length)
   37.56         {           
   37.57             c = UTF8Util::DecodeNextChar_Advance0(&buf);
   37.58             if (index == 0)
   37.59                 return c;
   37.60             index--;
   37.61         }
   37.62 
   37.63         return c;
   37.64     }
   37.65 
   37.66     do 
   37.67     {
   37.68         c = UTF8Util::DecodeNextChar_Advance0(&buf);
   37.69         index--;
   37.70 
   37.71         if (c == 0)
   37.72         {
   37.73             // We've hit the end of the string; don't go further.
   37.74             OVR_ASSERT(index == 0);
   37.75             return c;
   37.76         }
   37.77     } while (index >= 0);
   37.78 
   37.79     return c;
   37.80 }
   37.81 
   37.82 SPInt OVR_STDCALL GetByteIndex(SPInt index, const char *putf8str, SPInt length)
   37.83 {
   37.84     const char* buf = putf8str;
   37.85 
   37.86     if (length != -1)
   37.87     {
   37.88         while ((buf - putf8str) < length && index > 0)
   37.89         {
   37.90             UTF8Util::DecodeNextChar_Advance0(&buf);
   37.91             index--;
   37.92         }
   37.93 
   37.94         return buf-putf8str;
   37.95     }
   37.96 
   37.97     while (index > 0) 
   37.98     {
   37.99         UInt32 c = UTF8Util::DecodeNextChar_Advance0(&buf);
  37.100         index--;
  37.101 
  37.102         if (c == 0)
  37.103             return buf-putf8str;
  37.104     };
  37.105 
  37.106     return buf-putf8str;
  37.107 }
  37.108 
  37.109 int OVR_STDCALL GetEncodeCharSize(UInt32 ucs_character)
  37.110 {
  37.111     if (ucs_character <= 0x7F)
  37.112         return 1;
  37.113     else if (ucs_character <= 0x7FF)
  37.114         return 2;
  37.115     else if (ucs_character <= 0xFFFF)
  37.116         return 3;
  37.117     else if (ucs_character <= 0x1FFFFF)
  37.118         return 4;
  37.119     else if (ucs_character <= 0x3FFFFFF)
  37.120         return 5;
  37.121     else if (ucs_character <= 0x7FFFFFFF)
  37.122         return 6;
  37.123     else
  37.124         return 0;
  37.125 }
  37.126 
  37.127 UInt32 OVR_STDCALL DecodeNextChar_Advance0(const char** putf8Buffer)
  37.128 {
  37.129     UInt32  uc;
  37.130     char    c;
  37.131     
  37.132     // Security considerations:
  37.133     //
  37.134     // Changed, this is now only the case for DecodeNextChar:
  37.135     //  - If we hit a zero byte, we want to return 0 without stepping
  37.136     //    the buffer pointer past the 0. th
  37.137     //
  37.138     // If we hit an "overlong sequence"; i.e. a character encoded
  37.139     // in a longer multibyte string than is necessary, then we
  37.140     // need to discard the character.  This is so attackers can't
  37.141     // disguise dangerous characters or character sequences --
  37.142     // there is only one valid encoding for each character.
  37.143     //
  37.144     // If we decode characters { 0xD800 .. 0xDFFF } or { 0xFFFE,
  37.145     // 0xFFFF } then we ignore them; they are not valid in UTF-8.
  37.146     
  37.147     // This isn't actually an invalid character; it's a valid char that
  37.148     // looks like an inverted question mark.
  37.149 #define INVALID_CHAR 0x0FFFD
  37.150     
  37.151 #define FIRST_BYTE(mask, shift)     \
  37.152     uc = (c & (mask)) << (shift);
  37.153     
  37.154 #define NEXT_BYTE(shift) \
  37.155     c = **putf8Buffer;   \
  37.156     if (c == 0) return 0; /* end of buffer, do not advance */   \
  37.157     if ((c & 0xC0) != 0x80) return INVALID_CHAR; /* standard check */  \
  37.158     (*putf8Buffer)++;    \
  37.159     uc |= (c & 0x3F) << shift;
  37.160     
  37.161     c = **putf8Buffer;
  37.162     (*putf8Buffer)++;
  37.163     if (c == 0)
  37.164         return 0;   // End of buffer.
  37.165     
  37.166     if ((c & 0x80) == 0) return (UInt32) c; // Conventional 7-bit ASCII.
  37.167     
  37.168     // Multi-byte sequences.
  37.169     if ((c & 0xE0) == 0xC0)
  37.170     {
  37.171         // Two-byte sequence.
  37.172         FIRST_BYTE(0x1F, 6);
  37.173         NEXT_BYTE(0);
  37.174         if (uc < 0x80) return INVALID_CHAR;  // overlong
  37.175         return uc;
  37.176     }
  37.177     else if ((c & 0xF0) == 0xE0)
  37.178     {
  37.179         // Three-byte sequence.
  37.180         FIRST_BYTE(0x0F, 12);
  37.181         NEXT_BYTE(6);
  37.182         NEXT_BYTE(0);
  37.183         if (uc < 0x800) return INVALID_CHAR; // overlong
  37.184         // Not valid ISO 10646, but Flash requires these to work
  37.185         // see AS3 test e15_5_3_2_3 for String.fromCharCode().charCodeAt(0)
  37.186         // if (uc >= 0x0D800 && uc <= 0x0DFFF) return INVALID_CHAR;
  37.187         // if (uc == 0x0FFFE || uc == 0x0FFFF) return INVALID_CHAR; // not valid ISO 10646
  37.188         return uc;
  37.189     }
  37.190     else if ((c & 0xF8) == 0xF0)
  37.191     {
  37.192         // Four-byte sequence.
  37.193         FIRST_BYTE(0x07, 18);
  37.194         NEXT_BYTE(12);
  37.195         NEXT_BYTE(6);
  37.196         NEXT_BYTE(0);
  37.197         if (uc < 0x010000) return INVALID_CHAR;  // overlong
  37.198         return uc;
  37.199     }
  37.200     else if ((c & 0xFC) == 0xF8)
  37.201     {
  37.202         // Five-byte sequence.
  37.203         FIRST_BYTE(0x03, 24);
  37.204         NEXT_BYTE(18);
  37.205         NEXT_BYTE(12);
  37.206         NEXT_BYTE(6);
  37.207         NEXT_BYTE(0);
  37.208         if (uc < 0x0200000) return INVALID_CHAR; // overlong
  37.209         return uc;
  37.210     }
  37.211     else if ((c & 0xFE) == 0xFC)
  37.212     {
  37.213         // Six-byte sequence.
  37.214         FIRST_BYTE(0x01, 30);
  37.215         NEXT_BYTE(24);
  37.216         NEXT_BYTE(18);
  37.217         NEXT_BYTE(12);
  37.218         NEXT_BYTE(6);
  37.219         NEXT_BYTE(0);
  37.220         if (uc < 0x04000000) return INVALID_CHAR;    // overlong
  37.221         return uc;
  37.222     }
  37.223     else
  37.224     {
  37.225         // Invalid.
  37.226         return INVALID_CHAR;
  37.227     }
  37.228 }
  37.229 
  37.230 
  37.231 void OVR_STDCALL EncodeChar(char* pbuffer, SPInt* pindex, UInt32 ucs_character)
  37.232 {
  37.233     if (ucs_character <= 0x7F)
  37.234     {
  37.235         // Plain single-byte ASCII.
  37.236         pbuffer[(*pindex)++] = (char) ucs_character;
  37.237     }
  37.238     else if (ucs_character <= 0x7FF)
  37.239     {
  37.240         // Two bytes.
  37.241         pbuffer[(*pindex)++] = 0xC0 | (char)(ucs_character >> 6);
  37.242         pbuffer[(*pindex)++] = 0x80 | (char)((ucs_character >> 0) & 0x3F);
  37.243     }
  37.244     else if (ucs_character <= 0xFFFF)
  37.245     {
  37.246         // Three bytes.
  37.247         pbuffer[(*pindex)++] = 0xE0 | (char)(ucs_character >> 12);
  37.248         pbuffer[(*pindex)++] = 0x80 | (char)((ucs_character >> 6) & 0x3F);
  37.249         pbuffer[(*pindex)++] = 0x80 | (char)((ucs_character >> 0) & 0x3F);
  37.250     }
  37.251     else if (ucs_character <= 0x1FFFFF)
  37.252     {
  37.253         // Four bytes.
  37.254         pbuffer[(*pindex)++] = 0xF0 | (char)(ucs_character >> 18);
  37.255         pbuffer[(*pindex)++] = 0x80 | (char)((ucs_character >> 12) & 0x3F);
  37.256         pbuffer[(*pindex)++] = 0x80 | (char)((ucs_character >> 6) & 0x3F);
  37.257         pbuffer[(*pindex)++] = 0x80 | (char)((ucs_character >> 0) & 0x3F);
  37.258     }
  37.259     else if (ucs_character <= 0x3FFFFFF)
  37.260     {
  37.261         // Five bytes.
  37.262         pbuffer[(*pindex)++] = 0xF8 | (char)(ucs_character >> 24);
  37.263         pbuffer[(*pindex)++] = 0x80 | (char)((ucs_character >> 18) & 0x3F);
  37.264         pbuffer[(*pindex)++] = 0x80 | (char)((ucs_character >> 12) & 0x3F);
  37.265         pbuffer[(*pindex)++] = 0x80 | (char)((ucs_character >> 6) & 0x3F);
  37.266         pbuffer[(*pindex)++] = 0x80 | (char)((ucs_character >> 0) & 0x3F);
  37.267     }
  37.268     else if (ucs_character <= 0x7FFFFFFF)
  37.269     {
  37.270         // Six bytes.
  37.271         pbuffer[(*pindex)++] = 0xFC | (char)(ucs_character >> 30);
  37.272         pbuffer[(*pindex)++] = 0x80 | (char)((ucs_character >> 24) & 0x3F);
  37.273         pbuffer[(*pindex)++] = 0x80 | (char)((ucs_character >> 18) & 0x3F);
  37.274         pbuffer[(*pindex)++] = 0x80 | (char)((ucs_character >> 12) & 0x3F);
  37.275         pbuffer[(*pindex)++] = 0x80 | (char)((ucs_character >> 6) & 0x3F);
  37.276         pbuffer[(*pindex)++] = 0x80 | (char)((ucs_character >> 0) & 0x3F);
  37.277     }
  37.278     else
  37.279     {
  37.280         // Invalid char; don't encode anything.
  37.281     }
  37.282 }
  37.283 
  37.284 SPInt OVR_STDCALL GetEncodeStringSize(const wchar_t* pchar, SPInt length)
  37.285 {
  37.286     SPInt len = 0;
  37.287     if (length != -1)
  37.288         for (int i = 0; i < length; i++)
  37.289         {
  37.290             len += GetEncodeCharSize(pchar[i]);
  37.291         }
  37.292     else
  37.293         for (int i = 0;; i++)
  37.294         {
  37.295             if (pchar[i] == 0)
  37.296                 return len;
  37.297             len += GetEncodeCharSize(pchar[i]);
  37.298         }
  37.299     return len;
  37.300 }
  37.301 
  37.302 void OVR_STDCALL EncodeString(char *pbuff, const wchar_t* pchar, SPInt length)
  37.303 {
  37.304     SPInt ofs = 0;
  37.305     if (length != -1)
  37.306     {
  37.307         for (int i = 0; i < length; i++)
  37.308         {            
  37.309             EncodeChar(pbuff, &ofs, pchar[i]);
  37.310         }
  37.311     }
  37.312     else
  37.313     {
  37.314         for (int i = 0;; i++)
  37.315         {
  37.316             if (pchar[i] == 0)
  37.317                 break;
  37.318             EncodeChar(pbuff, &ofs, pchar[i]);
  37.319         }
  37.320     }
  37.321     pbuff[ofs] = 0;
  37.322 }
  37.323 
  37.324 UPInt OVR_STDCALL DecodeString(wchar_t *pbuff, const char* putf8str, SPInt bytesLen)
  37.325 {
  37.326     wchar_t *pbegin = pbuff;
  37.327     if (bytesLen == -1)
  37.328     {
  37.329         while (1)
  37.330         {
  37.331             UInt32 ch = DecodeNextChar_Advance0(&putf8str);
  37.332             if (ch == 0)
  37.333                 break;
  37.334             else if (ch >= 0xFFFF)
  37.335                 ch = 0xFFFD;
  37.336             *pbuff++ = wchar_t(ch);
  37.337         }
  37.338     }
  37.339     else
  37.340     {
  37.341         const char* p = putf8str;
  37.342         while ((p - putf8str) < bytesLen)
  37.343         {
  37.344             UInt32 ch = DecodeNextChar_Advance0(&p);
  37.345             if (ch >= 0xFFFF)
  37.346                 ch = 0xFFFD;
  37.347             *pbuff++ = wchar_t(ch);
  37.348         }
  37.349     }
  37.350 
  37.351     *pbuff = 0;
  37.352     return pbuff - pbegin;
  37.353 }
  37.354 
  37.355 
  37.356 #ifdef UTF8_UNIT_TEST
  37.357 
  37.358 // Compile this test case with something like:
  37.359 //
  37.360 // gcc utf8.cpp -g -I.. -DUTF8_UNIT_TEST -lstdc++ -o utf8_test
  37.361 //
  37.362 //    or
  37.363 //
  37.364 // cl utf8.cpp -Zi -Od -DUTF8_UNIT_TEST -I..
  37.365 //
  37.366 // If possible, try running the test program with the first arg
  37.367 // pointing at the file:
  37.368 //
  37.369 // http://www.cl.cam.ac.uk/~mgk25/ucs/examples/UTF-8-test.txt
  37.370 // 
  37.371 // and examine the results by eye to make sure they are acceptable to
  37.372 // you.
  37.373 
  37.374 
  37.375 #include "base/utility.h"
  37.376 #include <stdio.h>
  37.377 
  37.378 
  37.379 bool    check_equal(const char* utf8_in, const UInt32* ucs_in)
  37.380 {
  37.381     for (;;)
  37.382     {
  37.383         UInt32  next_ucs = *ucs_in++;
  37.384         UInt32  next_ucs_from_utf8 = utf8::decode_next_unicode_character(&utf8_in);
  37.385         if (next_ucs != next_ucs_from_utf8)
  37.386         {
  37.387             return false;
  37.388         }
  37.389         if (next_ucs == 0)
  37.390         {
  37.391             OVR_ASSERT(next_ucs_from_utf8 == 0);
  37.392             break;
  37.393         }
  37.394     }
  37.395     
  37.396     return true;
  37.397 }
  37.398 
  37.399 
  37.400 void    log_ascii(const char* line)
  37.401 {
  37.402     for (;;)
  37.403     {
  37.404         unsigned char   c = (unsigned char) *line++;
  37.405         if (c == 0)
  37.406         {
  37.407             // End of line.
  37.408             return;
  37.409         }
  37.410         else if (c != '\n'
  37.411             && (c < 32 || c > 127))
  37.412         {
  37.413             // Non-printable as plain ASCII.
  37.414             printf("<0x%02X>", (int) c);
  37.415         }
  37.416         else
  37.417         {
  37.418             printf("%c", c);
  37.419         }
  37.420     }
  37.421 }
  37.422 
  37.423 
  37.424 void    log_ucs(const UInt32* line)
  37.425 {
  37.426     for (;;)
  37.427     {
  37.428         UInt32  uc = *line++;
  37.429         if (uc == 0)
  37.430         {
  37.431             // End of line.
  37.432             return;
  37.433         }
  37.434         else if (uc != '\n'
  37.435             && (uc < 32 || uc > 127))
  37.436         {
  37.437             // Non-printable as plain ASCII.
  37.438             printf("<U-%04X>", uc);
  37.439         }
  37.440         else
  37.441         {
  37.442             printf("%c", (char) uc);
  37.443         }
  37.444     }
  37.445 }
  37.446 
  37.447 
  37.448 // Simple canned test.
  37.449 int main(int argc, const char* argv[])
  37.450 {
  37.451     {
  37.452         const char* test8 = "Ignacio Castaño";
  37.453         const UInt32    test32[] =
  37.454         {
  37.455             0x49, 0x67, 0x6E, 0x61, 0x63,
  37.456                 0x69, 0x6F, 0x20, 0x43, 0x61,
  37.457                 0x73, 0x74, 0x61, 0xF1, 0x6F,
  37.458                 0x00
  37.459         };
  37.460         
  37.461         OVR_ASSERT(check_equal(test8, test32));
  37.462     }
  37.463         
  37.464         // If user passed an arg, try reading the file as UTF-8 encoded text.
  37.465         if (argc > 1)
  37.466         {
  37.467             const char* filename = argv[1];
  37.468             FILE*   fp = fopen(filename, "rb");
  37.469             if (fp == NULL)
  37.470             {
  37.471                 printf("Can't open file '%s'\n", filename);
  37.472                 return 1;
  37.473             }
  37.474             
  37.475             // Read lines from the file, encode/decode them, and highlight discrepancies.
  37.476             const int LINE_SIZE = 200;  // max line size
  37.477             char    line_buffer_utf8[LINE_SIZE];
  37.478             char    reencoded_utf8[6 * LINE_SIZE];
  37.479             UInt32  line_buffer_ucs[LINE_SIZE];
  37.480             
  37.481             int byte_counter = 0;
  37.482             for (;;)
  37.483             {
  37.484                 int c = fgetc(fp);
  37.485                 if (c == EOF)
  37.486                 {
  37.487                     // Done.
  37.488                     break;
  37.489                 }
  37.490                 line_buffer_utf8[byte_counter++] = c;
  37.491                 if (c == '\n' || byte_counter >= LINE_SIZE - 2)
  37.492                 {
  37.493                     // End of line.  Process the line.
  37.494                     line_buffer_utf8[byte_counter++] = 0;   // terminate.
  37.495                     
  37.496                     // Decode into UCS.
  37.497                     const char* p = line_buffer_utf8;
  37.498                     UInt32* q = line_buffer_ucs;
  37.499                     for (;;)
  37.500                     {
  37.501                         UInt32  uc = UTF8Util::DecodeNextChar(&p);
  37.502                         *q++ = uc;
  37.503                         
  37.504                         OVR_ASSERT(q < line_buffer_ucs + LINE_SIZE);
  37.505                         OVR_ASSERT(p < line_buffer_utf8 + LINE_SIZE);
  37.506                         
  37.507                         if (uc == 0) break;
  37.508                     }
  37.509                     
  37.510                     // Encode back into UTF-8.
  37.511                     q = line_buffer_ucs;
  37.512                     int index = 0;
  37.513                     for (;;)
  37.514                     {
  37.515                         UInt32  uc = *q++;
  37.516                         OVR_ASSERT(index < LINE_SIZE * 6 - 6);
  37.517                         int last_index = index;
  37.518                         UTF8Util::EncodeChar(reencoded_utf8, &index, uc);
  37.519                         OVR_ASSERT(index <= last_index + 6);
  37.520                         if (uc == 0) break;
  37.521                     }
  37.522                     
  37.523                     // This can be useful for debugging.
  37.524 #if 0
  37.525                     // Show the UCS and the re-encoded UTF-8.
  37.526                     log_ucs(line_buffer_ucs);
  37.527                     log_ascii(reencoded_utf8);
  37.528 #endif // 0
  37.529                     
  37.530                     OVR_ASSERT(check_equal(line_buffer_utf8, line_buffer_ucs));
  37.531                     OVR_ASSERT(check_equal(reencoded_utf8, line_buffer_ucs));
  37.532                     
  37.533                     // Start next line.
  37.534                     byte_counter = 0;
  37.535                 }
  37.536             }
  37.537             
  37.538             fclose(fp);
  37.539         }
  37.540         
  37.541         return 0;
  37.542 }
  37.543 
  37.544 
  37.545 #endif // UTF8_UNIT_TEST
  37.546 
  37.547 }} // namespace UTF8Util::OVR
  37.548 
  37.549 \ No newline at end of file
  37.550 +/**************************************************************************
  37.551 +
  37.552 +Filename    :   OVR_UTF8Util.cpp
  37.553 +Content     :   UTF8 Unicode character encoding/decoding support
  37.554 +Created     :   September 19, 2012
  37.555 +Notes       : 
  37.556 +Notes       :   Much useful info at "UTF-8 and Unicode FAQ"
  37.557 +                http://www.cl.cam.ac.uk/~mgk25/unicode.html
  37.558 +
  37.559 +Copyright   :   Copyright 2012 Oculus VR, Inc. All Rights reserved.
  37.560 +
  37.561 +Use of this software is subject to the terms of the Oculus license
  37.562 +agreement provided at the time of installation or download, or which
  37.563 +otherwise accompanies this software in either electronic or hard copy form.
  37.564 +
  37.565 +************************************************************************************/
  37.566 +
  37.567 +#include "OVR_UTF8Util.h"
  37.568 +
  37.569 +namespace OVR { namespace UTF8Util {
  37.570 +
  37.571 +SPInt OVR_STDCALL GetLength(const char* buf, SPInt buflen)
  37.572 +{
  37.573 +    const char* p = buf;
  37.574 +    SPInt length = 0;
  37.575 +
  37.576 +    if (buflen != -1)
  37.577 +    {
  37.578 +        while (p - buf < buflen)
  37.579 +        {
  37.580 +            // We should be able to have ASStrings with 0 in the middle.
  37.581 +            UTF8Util::DecodeNextChar_Advance0(&p);
  37.582 +            length++;
  37.583 +        }
  37.584 +    }
  37.585 +    else
  37.586 +    {
  37.587 +        while (UTF8Util::DecodeNextChar_Advance0(&p))
  37.588 +            length++;
  37.589 +    }
  37.590 +    
  37.591 +    return length;
  37.592 +}
  37.593 +
  37.594 +UInt32 OVR_STDCALL GetCharAt(SPInt index, const char* putf8str, SPInt length)
  37.595 +{
  37.596 +    const char* buf = putf8str;
  37.597 +    UInt32  c = 0;
  37.598 +
  37.599 +    if (length != -1)
  37.600 +    {
  37.601 +        while (buf - putf8str < length)
  37.602 +        {           
  37.603 +            c = UTF8Util::DecodeNextChar_Advance0(&buf);
  37.604 +            if (index == 0)
  37.605 +                return c;
  37.606 +            index--;
  37.607 +        }
  37.608 +
  37.609 +        return c;
  37.610 +    }
  37.611 +
  37.612 +    do 
  37.613 +    {
  37.614 +        c = UTF8Util::DecodeNextChar_Advance0(&buf);
  37.615 +        index--;
  37.616 +
  37.617 +        if (c == 0)
  37.618 +        {
  37.619 +            // We've hit the end of the string; don't go further.
  37.620 +            OVR_ASSERT(index == 0);
  37.621 +            return c;
  37.622 +        }
  37.623 +    } while (index >= 0);
  37.624 +
  37.625 +    return c;
  37.626 +}
  37.627 +
  37.628 +SPInt OVR_STDCALL GetByteIndex(SPInt index, const char *putf8str, SPInt length)
  37.629 +{
  37.630 +    const char* buf = putf8str;
  37.631 +
  37.632 +    if (length != -1)
  37.633 +    {
  37.634 +        while ((buf - putf8str) < length && index > 0)
  37.635 +        {
  37.636 +            UTF8Util::DecodeNextChar_Advance0(&buf);
  37.637 +            index--;
  37.638 +        }
  37.639 +
  37.640 +        return buf-putf8str;
  37.641 +    }
  37.642 +
  37.643 +    while (index > 0) 
  37.644 +    {
  37.645 +        UInt32 c = UTF8Util::DecodeNextChar_Advance0(&buf);
  37.646 +        index--;
  37.647 +
  37.648 +        if (c == 0)
  37.649 +            return buf-putf8str;
  37.650 +    };
  37.651 +
  37.652 +    return buf-putf8str;
  37.653 +}
  37.654 +
  37.655 +int OVR_STDCALL GetEncodeCharSize(UInt32 ucs_character)
  37.656 +{
  37.657 +    if (ucs_character <= 0x7F)
  37.658 +        return 1;
  37.659 +    else if (ucs_character <= 0x7FF)
  37.660 +        return 2;
  37.661 +    else if (ucs_character <= 0xFFFF)
  37.662 +        return 3;
  37.663 +    else if (ucs_character <= 0x1FFFFF)
  37.664 +        return 4;
  37.665 +    else if (ucs_character <= 0x3FFFFFF)
  37.666 +        return 5;
  37.667 +    else if (ucs_character <= 0x7FFFFFFF)
  37.668 +        return 6;
  37.669 +    else
  37.670 +        return 0;
  37.671 +}
  37.672 +
  37.673 +UInt32 OVR_STDCALL DecodeNextChar_Advance0(const char** putf8Buffer)
  37.674 +{
  37.675 +    UInt32  uc;
  37.676 +    char    c;
  37.677 +    
  37.678 +    // Security considerations:
  37.679 +    //
  37.680 +    // Changed, this is now only the case for DecodeNextChar:
  37.681 +    //  - If we hit a zero byte, we want to return 0 without stepping
  37.682 +    //    the buffer pointer past the 0. th
  37.683 +    //
  37.684 +    // If we hit an "overlong sequence"; i.e. a character encoded
  37.685 +    // in a longer multibyte string than is necessary, then we
  37.686 +    // need to discard the character.  This is so attackers can't
  37.687 +    // disguise dangerous characters or character sequences --
  37.688 +    // there is only one valid encoding for each character.
  37.689 +    //
  37.690 +    // If we decode characters { 0xD800 .. 0xDFFF } or { 0xFFFE,
  37.691 +    // 0xFFFF } then we ignore them; they are not valid in UTF-8.
  37.692 +    
  37.693 +    // This isn't actually an invalid character; it's a valid char that
  37.694 +    // looks like an inverted question mark.
  37.695 +#define INVALID_CHAR 0x0FFFD
  37.696 +    
  37.697 +#define FIRST_BYTE(mask, shift)     \
  37.698 +    uc = (c & (mask)) << (shift);
  37.699 +    
  37.700 +#define NEXT_BYTE(shift) \
  37.701 +    c = **putf8Buffer;   \
  37.702 +    if (c == 0) return 0; /* end of buffer, do not advance */   \
  37.703 +    if ((c & 0xC0) != 0x80) return INVALID_CHAR; /* standard check */  \
  37.704 +    (*putf8Buffer)++;    \
  37.705 +    uc |= (c & 0x3F) << shift;
  37.706 +    
  37.707 +    c = **putf8Buffer;
  37.708 +    (*putf8Buffer)++;
  37.709 +    if (c == 0)
  37.710 +        return 0;   // End of buffer.
  37.711 +    
  37.712 +    if ((c & 0x80) == 0) return (UInt32) c; // Conventional 7-bit ASCII.
  37.713 +    
  37.714 +    // Multi-byte sequences.
  37.715 +    if ((c & 0xE0) == 0xC0)
  37.716 +    {
  37.717 +        // Two-byte sequence.
  37.718 +        FIRST_BYTE(0x1F, 6);
  37.719 +        NEXT_BYTE(0);
  37.720 +        if (uc < 0x80) return INVALID_CHAR;  // overlong
  37.721 +        return uc;
  37.722 +    }
  37.723 +    else if ((c & 0xF0) == 0xE0)
  37.724 +    {
  37.725 +        // Three-byte sequence.
  37.726 +        FIRST_BYTE(0x0F, 12);
  37.727 +        NEXT_BYTE(6);
  37.728 +        NEXT_BYTE(0);
  37.729 +        if (uc < 0x800) return INVALID_CHAR; // overlong
  37.730 +        // Not valid ISO 10646, but Flash requires these to work
  37.731 +        // see AS3 test e15_5_3_2_3 for String.fromCharCode().charCodeAt(0)
  37.732 +        // if (uc >= 0x0D800 && uc <= 0x0DFFF) return INVALID_CHAR;
  37.733 +        // if (uc == 0x0FFFE || uc == 0x0FFFF) return INVALID_CHAR; // not valid ISO 10646
  37.734 +        return uc;
  37.735 +    }
  37.736 +    else if ((c & 0xF8) == 0xF0)
  37.737 +    {
  37.738 +        // Four-byte sequence.
  37.739 +        FIRST_BYTE(0x07, 18);
  37.740 +        NEXT_BYTE(12);
  37.741 +        NEXT_BYTE(6);
  37.742 +        NEXT_BYTE(0);
  37.743 +        if (uc < 0x010000) return INVALID_CHAR;  // overlong
  37.744 +        return uc;
  37.745 +    }
  37.746 +    else if ((c & 0xFC) == 0xF8)
  37.747 +    {
  37.748 +        // Five-byte sequence.
  37.749 +        FIRST_BYTE(0x03, 24);
  37.750 +        NEXT_BYTE(18);
  37.751 +        NEXT_BYTE(12);
  37.752 +        NEXT_BYTE(6);
  37.753 +        NEXT_BYTE(0);
  37.754 +        if (uc < 0x0200000) return INVALID_CHAR; // overlong
  37.755 +        return uc;
  37.756 +    }
  37.757 +    else if ((c & 0xFE) == 0xFC)
  37.758 +    {
  37.759 +        // Six-byte sequence.
  37.760 +        FIRST_BYTE(0x01, 30);
  37.761 +        NEXT_BYTE(24);
  37.762 +        NEXT_BYTE(18);
  37.763 +        NEXT_BYTE(12);
  37.764 +        NEXT_BYTE(6);
  37.765 +        NEXT_BYTE(0);
  37.766 +        if (uc < 0x04000000) return INVALID_CHAR;    // overlong
  37.767 +        return uc;
  37.768 +    }
  37.769 +    else
  37.770 +    {
  37.771 +        // Invalid.
  37.772 +        return INVALID_CHAR;
  37.773 +    }
  37.774 +}
  37.775 +
  37.776 +
  37.777 +void OVR_STDCALL EncodeChar(char* pbuffer, SPInt* pindex, UInt32 ucs_character)
  37.778 +{
  37.779 +    if (ucs_character <= 0x7F)
  37.780 +    {
  37.781 +        // Plain single-byte ASCII.
  37.782 +        pbuffer[(*pindex)++] = (char) ucs_character;
  37.783 +    }
  37.784 +    else if (ucs_character <= 0x7FF)
  37.785 +    {
  37.786 +        // Two bytes.
  37.787 +        pbuffer[(*pindex)++] = 0xC0 | (char)(ucs_character >> 6);
  37.788 +        pbuffer[(*pindex)++] = 0x80 | (char)((ucs_character >> 0) & 0x3F);
  37.789 +    }
  37.790 +    else if (ucs_character <= 0xFFFF)
  37.791 +    {
  37.792 +        // Three bytes.
  37.793 +        pbuffer[(*pindex)++] = 0xE0 | (char)(ucs_character >> 12);
  37.794 +        pbuffer[(*pindex)++] = 0x80 | (char)((ucs_character >> 6) & 0x3F);
  37.795 +        pbuffer[(*pindex)++] = 0x80 | (char)((ucs_character >> 0) & 0x3F);
  37.796 +    }
  37.797 +    else if (ucs_character <= 0x1FFFFF)
  37.798 +    {
  37.799 +        // Four bytes.
  37.800 +        pbuffer[(*pindex)++] = 0xF0 | (char)(ucs_character >> 18);
  37.801 +        pbuffer[(*pindex)++] = 0x80 | (char)((ucs_character >> 12) & 0x3F);
  37.802 +        pbuffer[(*pindex)++] = 0x80 | (char)((ucs_character >> 6) & 0x3F);
  37.803 +        pbuffer[(*pindex)++] = 0x80 | (char)((ucs_character >> 0) & 0x3F);
  37.804 +    }
  37.805 +    else if (ucs_character <= 0x3FFFFFF)
  37.806 +    {
  37.807 +        // Five bytes.
  37.808 +        pbuffer[(*pindex)++] = 0xF8 | (char)(ucs_character >> 24);
  37.809 +        pbuffer[(*pindex)++] = 0x80 | (char)((ucs_character >> 18) & 0x3F);
  37.810 +        pbuffer[(*pindex)++] = 0x80 | (char)((ucs_character >> 12) & 0x3F);
  37.811 +        pbuffer[(*pindex)++] = 0x80 | (char)((ucs_character >> 6) & 0x3F);
  37.812 +        pbuffer[(*pindex)++] = 0x80 | (char)((ucs_character >> 0) & 0x3F);
  37.813 +    }
  37.814 +    else if (ucs_character <= 0x7FFFFFFF)
  37.815 +    {
  37.816 +        // Six bytes.
  37.817 +        pbuffer[(*pindex)++] = 0xFC | (char)(ucs_character >> 30);
  37.818 +        pbuffer[(*pindex)++] = 0x80 | (char)((ucs_character >> 24) & 0x3F);
  37.819 +        pbuffer[(*pindex)++] = 0x80 | (char)((ucs_character >> 18) & 0x3F);
  37.820 +        pbuffer[(*pindex)++] = 0x80 | (char)((ucs_character >> 12) & 0x3F);
  37.821 +        pbuffer[(*pindex)++] = 0x80 | (char)((ucs_character >> 6) & 0x3F);
  37.822 +        pbuffer[(*pindex)++] = 0x80 | (char)((ucs_character >> 0) & 0x3F);
  37.823 +    }
  37.824 +    else
  37.825 +    {
  37.826 +        // Invalid char; don't encode anything.
  37.827 +    }
  37.828 +}
  37.829 +
  37.830 +SPInt OVR_STDCALL GetEncodeStringSize(const wchar_t* pchar, SPInt length)
  37.831 +{
  37.832 +    SPInt len = 0;
  37.833 +    if (length != -1)
  37.834 +        for (int i = 0; i < length; i++)
  37.835 +        {
  37.836 +            len += GetEncodeCharSize(pchar[i]);
  37.837 +        }
  37.838 +    else
  37.839 +        for (int i = 0;; i++)
  37.840 +        {
  37.841 +            if (pchar[i] == 0)
  37.842 +                return len;
  37.843 +            len += GetEncodeCharSize(pchar[i]);
  37.844 +        }
  37.845 +    return len;
  37.846 +}
  37.847 +
  37.848 +void OVR_STDCALL EncodeString(char *pbuff, const wchar_t* pchar, SPInt length)
  37.849 +{
  37.850 +    SPInt ofs = 0;
  37.851 +    if (length != -1)
  37.852 +    {
  37.853 +        for (int i = 0; i < length; i++)
  37.854 +        {            
  37.855 +            EncodeChar(pbuff, &ofs, pchar[i]);
  37.856 +        }
  37.857 +    }
  37.858 +    else
  37.859 +    {
  37.860 +        for (int i = 0;; i++)
  37.861 +        {
  37.862 +            if (pchar[i] == 0)
  37.863 +                break;
  37.864 +            EncodeChar(pbuff, &ofs, pchar[i]);
  37.865 +        }
  37.866 +    }
  37.867 +    pbuff[ofs] = 0;
  37.868 +}
  37.869 +
  37.870 +UPInt OVR_STDCALL DecodeString(wchar_t *pbuff, const char* putf8str, SPInt bytesLen)
  37.871 +{
  37.872 +    wchar_t *pbegin = pbuff;
  37.873 +    if (bytesLen == -1)
  37.874 +    {
  37.875 +        while (1)
  37.876 +        {
  37.877 +            UInt32 ch = DecodeNextChar_Advance0(&putf8str);
  37.878 +            if (ch == 0)
  37.879 +                break;
  37.880 +            else if (ch >= 0xFFFF)
  37.881 +                ch = 0xFFFD;
  37.882 +            *pbuff++ = wchar_t(ch);
  37.883 +        }
  37.884 +    }
  37.885 +    else
  37.886 +    {
  37.887 +        const char* p = putf8str;
  37.888 +        while ((p - putf8str) < bytesLen)
  37.889 +        {
  37.890 +            UInt32 ch = DecodeNextChar_Advance0(&p);
  37.891 +            if (ch >= 0xFFFF)
  37.892 +                ch = 0xFFFD;
  37.893 +            *pbuff++ = wchar_t(ch);
  37.894 +        }
  37.895 +    }
  37.896 +
  37.897 +    *pbuff = 0;
  37.898 +    return pbuff - pbegin;
  37.899 +}
  37.900 +
  37.901 +
  37.902 +#ifdef UTF8_UNIT_TEST
  37.903 +
  37.904 +// Compile this test case with something like:
  37.905 +//
  37.906 +// gcc utf8.cpp -g -I.. -DUTF8_UNIT_TEST -lstdc++ -o utf8_test
  37.907 +//
  37.908 +//    or
  37.909 +//
  37.910 +// cl utf8.cpp -Zi -Od -DUTF8_UNIT_TEST -I..
  37.911 +//
  37.912 +// If possible, try running the test program with the first arg
  37.913 +// pointing at the file:
  37.914 +//
  37.915 +// http://www.cl.cam.ac.uk/~mgk25/ucs/examples/UTF-8-test.txt
  37.916 +// 
  37.917 +// and examine the results by eye to make sure they are acceptable to
  37.918 +// you.
  37.919 +
  37.920 +
  37.921 +#include "base/utility.h"
  37.922 +#include <stdio.h>
  37.923 +
  37.924 +
  37.925 +bool    check_equal(const char* utf8_in, const UInt32* ucs_in)
  37.926 +{
  37.927 +    for (;;)
  37.928 +    {
  37.929 +        UInt32  next_ucs = *ucs_in++;
  37.930 +        UInt32  next_ucs_from_utf8 = utf8::decode_next_unicode_character(&utf8_in);
  37.931 +        if (next_ucs != next_ucs_from_utf8)
  37.932 +        {
  37.933 +            return false;
  37.934 +        }
  37.935 +        if (next_ucs == 0)
  37.936 +        {
  37.937 +            OVR_ASSERT(next_ucs_from_utf8 == 0);
  37.938 +            break;
  37.939 +        }
  37.940 +    }
  37.941 +    
  37.942 +    return true;
  37.943 +}
  37.944 +
  37.945 +
  37.946 +void    log_ascii(const char* line)
  37.947 +{
  37.948 +    for (;;)
  37.949 +    {
  37.950 +        unsigned char   c = (unsigned char) *line++;
  37.951 +        if (c == 0)
  37.952 +        {
  37.953 +            // End of line.
  37.954 +            return;
  37.955 +        }
  37.956 +        else if (c != '\n'
  37.957 +            && (c < 32 || c > 127))
  37.958 +        {
  37.959 +            // Non-printable as plain ASCII.
  37.960 +            printf("<0x%02X>", (int) c);
  37.961 +        }
  37.962 +        else
  37.963 +        {
  37.964 +            printf("%c", c);
  37.965 +        }
  37.966 +    }
  37.967 +}
  37.968 +
  37.969 +
  37.970 +void    log_ucs(const UInt32* line)
  37.971 +{
  37.972 +    for (;;)
  37.973 +    {
  37.974 +        UInt32  uc = *line++;
  37.975 +        if (uc == 0)
  37.976 +        {
  37.977 +            // End of line.
  37.978 +            return;
  37.979 +        }
  37.980 +        else if (uc != '\n'
  37.981 +            && (uc < 32 || uc > 127))
  37.982 +        {
  37.983 +            // Non-printable as plain ASCII.
  37.984 +            printf("<U-%04X>", uc);
  37.985 +        }
  37.986 +        else
  37.987 +        {
  37.988 +            printf("%c", (char) uc);
  37.989 +        }
  37.990 +    }
  37.991 +}
  37.992 +
  37.993 +
  37.994 +// Simple canned test.
  37.995 +int main(int argc, const char* argv[])
  37.996 +{
  37.997 +    {
  37.998 +        const char* test8 = "Ignacio Castaño";
  37.999 +        const UInt32    test32[] =
 37.1000 +        {
 37.1001 +            0x49, 0x67, 0x6E, 0x61, 0x63,
 37.1002 +                0x69, 0x6F, 0x20, 0x43, 0x61,
 37.1003 +                0x73, 0x74, 0x61, 0xF1, 0x6F,
 37.1004 +                0x00
 37.1005 +        };
 37.1006 +        
 37.1007 +        OVR_ASSERT(check_equal(test8, test32));
 37.1008 +    }
 37.1009 +        
 37.1010 +        // If user passed an arg, try reading the file as UTF-8 encoded text.
 37.1011 +        if (argc > 1)
 37.1012 +        {
 37.1013 +            const char* filename = argv[1];
 37.1014 +            FILE*   fp = fopen(filename, "rb");
 37.1015 +            if (fp == NULL)
 37.1016 +            {
 37.1017 +                printf("Can't open file '%s'\n", filename);
 37.1018 +                return 1;
 37.1019 +            }
 37.1020 +            
 37.1021 +            // Read lines from the file, encode/decode them, and highlight discrepancies.
 37.1022 +            const int LINE_SIZE = 200;  // max line size
 37.1023 +            char    line_buffer_utf8[LINE_SIZE];
 37.1024 +            char    reencoded_utf8[6 * LINE_SIZE];
 37.1025 +            UInt32  line_buffer_ucs[LINE_SIZE];
 37.1026 +            
 37.1027 +            int byte_counter = 0;
 37.1028 +            for (;;)
 37.1029 +            {
 37.1030 +                int c = fgetc(fp);
 37.1031 +                if (c == EOF)
 37.1032 +                {
 37.1033 +                    // Done.
 37.1034 +                    break;
 37.1035 +                }
 37.1036 +                line_buffer_utf8[byte_counter++] = c;
 37.1037 +                if (c == '\n' || byte_counter >= LINE_SIZE - 2)
 37.1038 +                {
 37.1039 +                    // End of line.  Process the line.
 37.1040 +                    line_buffer_utf8[byte_counter++] = 0;   // terminate.
 37.1041 +                    
 37.1042 +                    // Decode into UCS.
 37.1043 +                    const char* p = line_buffer_utf8;
 37.1044 +                    UInt32* q = line_buffer_ucs;
 37.1045 +                    for (;;)
 37.1046 +                    {
 37.1047 +                        UInt32  uc = UTF8Util::DecodeNextChar(&p);
 37.1048 +                        *q++ = uc;
 37.1049 +                        
 37.1050 +                        OVR_ASSERT(q < line_buffer_ucs + LINE_SIZE);
 37.1051 +                        OVR_ASSERT(p < line_buffer_utf8 + LINE_SIZE);
 37.1052 +                        
 37.1053 +                        if (uc == 0) break;
 37.1054 +                    }
 37.1055 +                    
 37.1056 +                    // Encode back into UTF-8.
 37.1057 +                    q = line_buffer_ucs;
 37.1058 +                    int index = 0;
 37.1059 +                    for (;;)
 37.1060 +                    {
 37.1061 +                        UInt32  uc = *q++;
 37.1062 +                        OVR_ASSERT(index < LINE_SIZE * 6 - 6);
 37.1063 +                        int last_index = index;
 37.1064 +                        UTF8Util::EncodeChar(reencoded_utf8, &index, uc);
 37.1065 +                        OVR_ASSERT(index <= last_index + 6);
 37.1066 +                        if (uc == 0) break;
 37.1067 +                    }
 37.1068 +                    
 37.1069 +                    // This can be useful for debugging.
 37.1070 +#if 0
 37.1071 +                    // Show the UCS and the re-encoded UTF-8.
 37.1072 +                    log_ucs(line_buffer_ucs);
 37.1073 +                    log_ascii(reencoded_utf8);
 37.1074 +#endif // 0
 37.1075 +                    
 37.1076 +                    OVR_ASSERT(check_equal(line_buffer_utf8, line_buffer_ucs));
 37.1077 +                    OVR_ASSERT(check_equal(reencoded_utf8, line_buffer_ucs));
 37.1078 +                    
 37.1079 +                    // Start next line.
 37.1080 +                    byte_counter = 0;
 37.1081 +                }
 37.1082 +            }
 37.1083 +            
 37.1084 +            fclose(fp);
 37.1085 +        }
 37.1086 +        
 37.1087 +        return 0;
 37.1088 +}
 37.1089 +
 37.1090 +
 37.1091 +#endif // UTF8_UNIT_TEST
 37.1092 +
 37.1093 +}} // namespace UTF8Util::OVR
 37.1094 +
    38.1 --- a/libovr/Src/Kernel/OVR_UTF8Util.h	Sat Sep 14 17:51:03 2013 +0300
    38.2 +++ b/libovr/Src/Kernel/OVR_UTF8Util.h	Sun Sep 15 04:10:05 2013 +0300
    38.3 @@ -1,1 +1,88 @@
    38.4 -/************************************************************************************
    38.5 
    38.6 PublicHeader:   OVR.h
    38.7 Filename    :   OVR_UTF8Util.h
    38.8 Content     :   UTF8 Unicode character encoding/decoding support
    38.9 Created     :   September 19, 2012
   38.10 Notes       : 
   38.11 
   38.12 Copyright   :   Copyright 2012 Oculus VR, Inc. All Rights reserved.
   38.13 
   38.14 Use of this software is subject to the terms of the Oculus license
   38.15 agreement provided at the time of installation or download, or which
   38.16 otherwise accompanies this software in either electronic or hard copy form.
   38.17 
   38.18 ************************************************************************************/
   38.19 
   38.20 #ifndef OVR_UTF8Util_h
   38.21 #define OVR_UTF8Util_h
   38.22 
   38.23 #include "OVR_Types.h"
   38.24 
   38.25 namespace OVR { namespace UTF8Util {
   38.26 
   38.27 //-----------------------------------------------------------------------------------
   38.28 
   38.29 // *** UTF8 string length and indexing.
   38.30 
   38.31 // Determines the length of UTF8 string in characters.
   38.32 // If source length is specified (in bytes), null 0 character is counted properly.
   38.33 SPInt    OVR_STDCALL GetLength(const char* putf8str, SPInt length = -1);
   38.34 
   38.35 // Gets a decoded UTF8 character at index; you can access up to the index returned
   38.36 // by GetLength. 0 will be returned for out of bounds access.
   38.37 UInt32   OVR_STDCALL GetCharAt(SPInt index, const char* putf8str, SPInt length = -1);
   38.38 
   38.39 // Converts UTF8 character index into byte offset.
   38.40 // -1 is returned if index was out of bounds.
   38.41 SPInt    OVR_STDCALL GetByteIndex(SPInt index, const char* putf8str, SPInt length = -1);
   38.42 
   38.43 
   38.44 // *** 16-bit Unicode string Encoding/Decoding routines.
   38.45 
   38.46 // Determines the number of bytes necessary to encode a string.
   38.47 // Does not count the terminating 0 (null) character.
   38.48 SPInt    OVR_STDCALL GetEncodeStringSize(const wchar_t* pchar, SPInt length = -1);
   38.49 
   38.50 // Encodes a unicode (UCS-2 only) string into a buffer. The size of buffer must be at
   38.51 // least GetEncodeStringSize() + 1.
   38.52 void     OVR_STDCALL EncodeString(char *pbuff, const wchar_t* pchar, SPInt length = -1);
   38.53 
   38.54 // Decode UTF8 into a wchar_t buffer. Must have GetLength()+1 characters available.
   38.55 // Characters over 0xFFFF are replaced with 0xFFFD.
   38.56 // Returns the length of resulting string (number of characters)
   38.57 UPInt    OVR_STDCALL DecodeString(wchar_t *pbuff, const char* putf8str, SPInt bytesLen = -1);
   38.58 
   38.59 
   38.60 // *** Individual character Encoding/Decoding.
   38.61 
   38.62 // Determined the number of bytes necessary to encode a UCS character.
   38.63 int      OVR_STDCALL GetEncodeCharSize(UInt32 ucsCharacter);
   38.64 
   38.65 // Encodes the given UCS character into the given UTF-8 buffer.
   38.66 // Writes the data starting at buffer[offset], and 
   38.67 // increments offset by the number of bytes written.
   38.68 // May write up to 6 bytes, so make sure there's room in the buffer
   38.69 void     OVR_STDCALL EncodeChar(char* pbuffer, SPInt* poffset, UInt32 ucsCharacter);
   38.70 
   38.71 // Return the next Unicode character in the UTF-8 encoded buffer.
   38.72 // Invalid UTF-8 sequences produce a U+FFFD character as output.
   38.73 // Advances *utf8_buffer past the character returned. Pointer advance
   38.74 // occurs even if the terminating 0 character is hit, since that allows
   38.75 // strings with middle '\0' characters to be supported.
   38.76 UInt32   OVR_STDCALL DecodeNextChar_Advance0(const char** putf8Buffer);
   38.77 
   38.78 // Safer version of DecodeNextChar, which doesn't advance pointer if
   38.79 // null character is hit.
   38.80 inline UInt32 DecodeNextChar(const char** putf8Buffer)
   38.81 {
   38.82     UInt32 ch = DecodeNextChar_Advance0(putf8Buffer);
   38.83     if (ch == 0)
   38.84         (*putf8Buffer)--;
   38.85     return ch;
   38.86 }
   38.87 
   38.88 
   38.89 }} // OVR::UTF8Util
   38.90 
   38.91 #endif
   38.92 \ No newline at end of file
   38.93 +/************************************************************************************
   38.94 +
   38.95 +PublicHeader:   OVR.h
   38.96 +Filename    :   OVR_UTF8Util.h
   38.97 +Content     :   UTF8 Unicode character encoding/decoding support
   38.98 +Created     :   September 19, 2012
   38.99 +Notes       : 
  38.100 +
  38.101 +Copyright   :   Copyright 2012 Oculus VR, Inc. All Rights reserved.
  38.102 +
  38.103 +Use of this software is subject to the terms of the Oculus license
  38.104 +agreement provided at the time of installation or download, or which
  38.105 +otherwise accompanies this software in either electronic or hard copy form.
  38.106 +
  38.107 +************************************************************************************/
  38.108 +
  38.109 +#ifndef OVR_UTF8Util_h
  38.110 +#define OVR_UTF8Util_h
  38.111 +
  38.112 +#include "OVR_Types.h"
  38.113 +
  38.114 +namespace OVR { namespace UTF8Util {
  38.115 +
  38.116 +//-----------------------------------------------------------------------------------
  38.117 +
  38.118 +// *** UTF8 string length and indexing.
  38.119 +
  38.120 +// Determines the length of UTF8 string in characters.
  38.121 +// If source length is specified (in bytes), null 0 character is counted properly.
  38.122 +SPInt    OVR_STDCALL GetLength(const char* putf8str, SPInt length = -1);
  38.123 +
  38.124 +// Gets a decoded UTF8 character at index; you can access up to the index returned
  38.125 +// by GetLength. 0 will be returned for out of bounds access.
  38.126 +UInt32   OVR_STDCALL GetCharAt(SPInt index, const char* putf8str, SPInt length = -1);
  38.127 +
  38.128 +// Converts UTF8 character index into byte offset.
  38.129 +// -1 is returned if index was out of bounds.
  38.130 +SPInt    OVR_STDCALL GetByteIndex(SPInt index, const char* putf8str, SPInt length = -1);
  38.131 +
  38.132 +
  38.133 +// *** 16-bit Unicode string Encoding/Decoding routines.
  38.134 +
  38.135 +// Determines the number of bytes necessary to encode a string.
  38.136 +// Does not count the terminating 0 (null) character.
  38.137 +SPInt    OVR_STDCALL GetEncodeStringSize(const wchar_t* pchar, SPInt length = -1);
  38.138 +
  38.139 +// Encodes a unicode (UCS-2 only) string into a buffer. The size of buffer must be at
  38.140 +// least GetEncodeStringSize() + 1.
  38.141 +void     OVR_STDCALL EncodeString(char *pbuff, const wchar_t* pchar, SPInt length = -1);
  38.142 +
  38.143 +// Decode UTF8 into a wchar_t buffer. Must have GetLength()+1 characters available.
  38.144 +// Characters over 0xFFFF are replaced with 0xFFFD.
  38.145 +// Returns the length of resulting string (number of characters)
  38.146 +UPInt    OVR_STDCALL DecodeString(wchar_t *pbuff, const char* putf8str, SPInt bytesLen = -1);
  38.147 +
  38.148 +
  38.149 +// *** Individual character Encoding/Decoding.
  38.150 +
  38.151 +// Determined the number of bytes necessary to encode a UCS character.
  38.152 +int      OVR_STDCALL GetEncodeCharSize(UInt32 ucsCharacter);
  38.153 +
  38.154 +// Encodes the given UCS character into the given UTF-8 buffer.
  38.155 +// Writes the data starting at buffer[offset], and 
  38.156 +// increments offset by the number of bytes written.
  38.157 +// May write up to 6 bytes, so make sure there's room in the buffer
  38.158 +void     OVR_STDCALL EncodeChar(char* pbuffer, SPInt* poffset, UInt32 ucsCharacter);
  38.159 +
  38.160 +// Return the next Unicode character in the UTF-8 encoded buffer.
  38.161 +// Invalid UTF-8 sequences produce a U+FFFD character as output.
  38.162 +// Advances *utf8_buffer past the character returned. Pointer advance
  38.163 +// occurs even if the terminating 0 character is hit, since that allows
  38.164 +// strings with middle '\0' characters to be supported.
  38.165 +UInt32   OVR_STDCALL DecodeNextChar_Advance0(const char** putf8Buffer);
  38.166 +
  38.167 +// Safer version of DecodeNextChar, which doesn't advance pointer if
  38.168 +// null character is hit.
  38.169 +inline UInt32 DecodeNextChar(const char** putf8Buffer)
  38.170 +{
  38.171 +    UInt32 ch = DecodeNextChar_Advance0(putf8Buffer);
  38.172 +    if (ch == 0)
  38.173 +        (*putf8Buffer)--;
  38.174 +    return ch;
  38.175 +}
  38.176 +
  38.177 +
  38.178 +}} // OVR::UTF8Util
  38.179 +
  38.180 +#endif
    39.1 --- a/libovr/Src/Util/Util_LatencyTest.cpp	Sat Sep 14 17:51:03 2013 +0300
    39.2 +++ b/libovr/Src/Util/Util_LatencyTest.cpp	Sun Sep 15 04:10:05 2013 +0300
    39.3 @@ -1,1 +1,571 @@
    39.4 -/************************************************************************************
    39.5 
    39.6 Filename    :   Util_LatencyTest.cpp
    39.7 Content     :   Wraps the lower level LatencyTester interface and adds functionality.
    39.8 Created     :   February 14, 2013
    39.9 Authors     :   Lee Cooper
   39.10 
   39.11 Copyright   :   Copyright 2013 Oculus VR, Inc. All Rights reserved.
   39.12 
   39.13 Use of this software is subject to the terms of the Oculus license
   39.14 agreement provided at the time of installation or download, or which
   39.15 otherwise accompanies this software in either electronic or hard copy form.
   39.16 
   39.17 *************************************************************************************/
   39.18 
   39.19 #include "Util_LatencyTest.h"
   39.20 
   39.21 #include "../Kernel/OVR_Log.h"
   39.22 #include "../Kernel/OVR_Timer.h"
   39.23 
   39.24 namespace OVR { namespace Util {
   39.25 
   39.26 static const UInt32     TIME_TO_WAIT_FOR_SETTLE_PRE_CALIBRATION = 16*10;
   39.27 static const UInt32     TIME_TO_WAIT_FOR_SETTLE_POST_CALIBRATION = 16*10;
   39.28 static const UInt32     TIME_TO_WAIT_FOR_SETTLE_POST_MEASUREMENT = 16*5;
   39.29 static const UInt32     TIME_TO_WAIT_FOR_SETTLE_POST_MEASUREMENT_RANDOMNESS = 16*5;
   39.30 static const UInt32     DEFAULT_NUMBER_OF_SAMPLES = 10;                 // For both color 1->2 and color 2->1 transitions.
   39.31 static const UInt32     INITIAL_SAMPLES_TO_IGNORE = 4;
   39.32 static const UInt32     TIMEOUT_WAITING_FOR_TEST_STARTED = 1000;
   39.33 static const UInt32     TIMEOUT_WAITING_FOR_COLOR_DETECTED = 4000;
   39.34 static const Color      CALIBRATE_BLACK(0, 0, 0);
   39.35 static const Color      CALIBRATE_WHITE(255, 255, 255);
   39.36 static const Color      COLOR1(0, 0, 0);
   39.37 static const Color      COLOR2(255, 255, 255);
   39.38 static const Color      SENSOR_DETECT_THRESHOLD(128, 255, 255);
   39.39 static const float      BIG_FLOAT = 1000000.0f;
   39.40 static const float      SMALL_FLOAT = -1000000.0f;
   39.41 
   39.42 //-------------------------------------------------------------------------------------
   39.43 // ***** LatencyTest
   39.44 
   39.45 LatencyTest::LatencyTest(LatencyTestDevice* device)
   39.46  :  Handler(getThis())
   39.47 {
   39.48     if (device != NULL)
   39.49     {
   39.50         SetDevice(device);
   39.51     }
   39.52 
   39.53     reset();
   39.54 
   39.55     srand(Timer::GetTicksMs());
   39.56 }
   39.57 
   39.58 LatencyTest::~LatencyTest()
   39.59 {
   39.60      clearMeasurementResults();
   39.61 }
   39.62 
   39.63 bool LatencyTest::SetDevice(LatencyTestDevice* device)
   39.64 {
   39.65 
   39.66     if (device != Device)
   39.67     {
   39.68         if (device != NULL)
   39.69         {
   39.70             if (device->GetMessageHandler() != NULL)
   39.71             {
   39.72                 OVR_DEBUG_LOG(
   39.73                     ("LatencyTest::AttachToDevice failed - device %p already has handler", device));
   39.74                 return false;
   39.75             }
   39.76         }
   39.77 
   39.78         if (Device != NULL)
   39.79         {
   39.80             Device->SetMessageHandler(0);
   39.81         }
   39.82         Device = device;
   39.83 
   39.84         if (Device != NULL)
   39.85         {
   39.86             Device->SetMessageHandler(&Handler);
   39.87 
   39.88             // Set trigger threshold.
   39.89             LatencyTestConfiguration configuration(SENSOR_DETECT_THRESHOLD, false);     // No samples streaming.
   39.90             Device->SetConfiguration(configuration, true);
   39.91 
   39.92             // Set display to intial (3 dashes).
   39.93             LatencyTestDisplay ltd(2, 0x40400040);
   39.94             Device->SetDisplay(ltd);
   39.95         }
   39.96     }
   39.97 
   39.98     return true;
   39.99 }
  39.100 
  39.101 UInt32 LatencyTest::getRandomComponent(UInt32 range)
  39.102 {
  39.103     UInt32 val = rand() % range;
  39.104     return val;
  39.105 }
  39.106 
  39.107 void LatencyTest::BeginTest()
  39.108 {
  39.109      if (State == State_WaitingForButton)
  39.110     {
  39.111         // Set color to black and wait a while.
  39.112         RenderColor = CALIBRATE_BLACK;
  39.113 
  39.114         State = State_WaitingForSettlePreCalibrationColorBlack;
  39.115         OVR_DEBUG_LOG(("State_WaitingForButton -> State_WaitingForSettlePreCalibrationColorBlack."));
  39.116 
  39.117         setTimer(TIME_TO_WAIT_FOR_SETTLE_PRE_CALIBRATION);
  39.118     }
  39.119 }
  39.120 
  39.121 void LatencyTest::handleMessage(const Message& msg, LatencyTestMessageType latencyTestMessage)
  39.122 {
  39.123     // For debugging.
  39.124 /*  if (msg.Type == Message_LatencyTestSamples)
  39.125     {
  39.126         MessageLatencyTestSamples* pSamples = (MessageLatencyTestSamples*) &msg;
  39.127 
  39.128         if (pSamples->Samples.GetSize() > 0)
  39.129         {
  39.130             // Just show the first one for now.
  39.131             Color c = pSamples->Samples[0];
  39.132             OVR_DEBUG_LOG(("%d %d %d", c.R, c.G, c.B));
  39.133         }
  39.134         return;
  39.135     }
  39.136 */
  39.137 
  39.138     if (latencyTestMessage == LatencyTest_Timer)
  39.139     {
  39.140         if (!Device)
  39.141         {
  39.142             reset();
  39.143             return;
  39.144         }
  39.145         
  39.146         if (State == State_WaitingForSettlePreCalibrationColorBlack)
  39.147         {
  39.148             // Send calibrate message to device and wait a while.
  39.149             Device->SetCalibrate(CALIBRATE_BLACK);
  39.150 
  39.151             State = State_WaitingForSettlePostCalibrationColorBlack;
  39.152             OVR_DEBUG_LOG(("State_WaitingForSettlePreCalibrationColorBlack -> State_WaitingForSettlePostCalibrationColorBlack."));
  39.153 
  39.154             setTimer(TIME_TO_WAIT_FOR_SETTLE_POST_CALIBRATION);
  39.155         }
  39.156         else if (State == State_WaitingForSettlePostCalibrationColorBlack)
  39.157         {
  39.158             // Change color to white and wait a while.
  39.159             RenderColor = CALIBRATE_WHITE;
  39.160 
  39.161             State = State_WaitingForSettlePreCalibrationColorWhite;
  39.162             OVR_DEBUG_LOG(("State_WaitingForSettlePostCalibrationColorBlack -> State_WaitingForSettlePreCalibrationColorWhite."));
  39.163 
  39.164             setTimer(TIME_TO_WAIT_FOR_SETTLE_PRE_CALIBRATION);
  39.165         }
  39.166         else if (State == State_WaitingForSettlePreCalibrationColorWhite)
  39.167         {
  39.168             // Send calibrate message to device and wait a while.
  39.169             Device->SetCalibrate(CALIBRATE_WHITE);
  39.170 
  39.171             State = State_WaitingForSettlePostCalibrationColorWhite;
  39.172             OVR_DEBUG_LOG(("State_WaitingForSettlePreCalibrationColorWhite -> State_WaitingForSettlePostCalibrationColorWhite."));
  39.173 
  39.174             setTimer(TIME_TO_WAIT_FOR_SETTLE_POST_CALIBRATION);
  39.175         }
  39.176         else if (State == State_WaitingForSettlePostCalibrationColorWhite)
  39.177         {
  39.178             // Calibration is done. Switch to color 1 and wait for it to settle.
  39.179             RenderColor = COLOR1;
  39.180 
  39.181             State = State_WaitingForSettlePostMeasurement;
  39.182             OVR_DEBUG_LOG(("State_WaitingForSettlePostCalibrationColorWhite -> State_WaitingForSettlePostMeasurement."));
  39.183 
  39.184             UInt32 waitTime = TIME_TO_WAIT_FOR_SETTLE_POST_MEASUREMENT + getRandomComponent(TIME_TO_WAIT_FOR_SETTLE_POST_MEASUREMENT_RANDOMNESS);
  39.185             setTimer(waitTime);
  39.186         }
  39.187         else if (State == State_WaitingForSettlePostMeasurement)
  39.188         {
  39.189             // Prepare for next measurement.
  39.190 
  39.191             // Create a new result object.
  39.192             MeasurementResult* pResult = new MeasurementResult();
  39.193             Results.PushBack(pResult);
  39.194 
  39.195             State = State_WaitingToTakeMeasurement;
  39.196             OVR_DEBUG_LOG(("State_WaitingForSettlePostMeasurement -> State_WaitingToTakeMeasurement."));
  39.197         }
  39.198         else if (State == State_WaitingForTestStarted)
  39.199         {
  39.200             // We timed out waiting for 'TestStarted'. Abandon this measurement and setup for the next.
  39.201             getActiveResult()->TimedOutWaitingForTestStarted = true;
  39.202 
  39.203             State = State_WaitingForSettlePostMeasurement;
  39.204             OVR_DEBUG_LOG(("** Timed out waiting for 'TestStarted'."));
  39.205             OVR_DEBUG_LOG(("State_WaitingForTestStarted -> State_WaitingForSettlePostMeasurement."));
  39.206 
  39.207             UInt32 waitTime = TIME_TO_WAIT_FOR_SETTLE_POST_MEASUREMENT + getRandomComponent(TIME_TO_WAIT_FOR_SETTLE_POST_MEASUREMENT_RANDOMNESS);
  39.208             setTimer(waitTime);
  39.209         }
  39.210         else if (State == State_WaitingForColorDetected)
  39.211         {
  39.212             // We timed out waiting for 'ColorDetected'. Abandon this measurement and setup for the next.
  39.213             getActiveResult()->TimedOutWaitingForColorDetected = true;
  39.214 
  39.215             State = State_WaitingForSettlePostMeasurement;
  39.216             OVR_DEBUG_LOG(("** Timed out waiting for 'ColorDetected'."));
  39.217             OVR_DEBUG_LOG(("State_WaitingForColorDetected -> State_WaitingForSettlePostMeasurement."));
  39.218 
  39.219             UInt32 waitTime = TIME_TO_WAIT_FOR_SETTLE_POST_MEASUREMENT + getRandomComponent(TIME_TO_WAIT_FOR_SETTLE_POST_MEASUREMENT_RANDOMNESS);
  39.220             setTimer(waitTime);
  39.221         }
  39.222     }
  39.223     else if (latencyTestMessage == LatencyTest_ProcessInputs)
  39.224     {
  39.225         if (State == State_WaitingToTakeMeasurement)
  39.226         {
  39.227             if (!Device)
  39.228             {
  39.229                 reset();
  39.230                 return;
  39.231             }
  39.232             
  39.233             // Send 'StartTest' feature report with opposite target color.
  39.234             if (RenderColor == COLOR1)
  39.235             {
  39.236                 RenderColor = COLOR2;
  39.237             }
  39.238             else
  39.239             {
  39.240                 RenderColor = COLOR1;
  39.241             }
  39.242 
  39.243             getActiveResult()->TargetColor = RenderColor;
  39.244             
  39.245             // Record time so we can determine usb roundtrip time.
  39.246             getActiveResult()->StartTestTicksMicroS = Timer::GetTicks();
  39.247 
  39.248             Device->SetStartTest(RenderColor);
  39.249 
  39.250             State = State_WaitingForTestStarted;
  39.251             OVR_DEBUG_LOG(("State_WaitingToTakeMeasurement -> State_WaitingForTestStarted."));
  39.252 
  39.253             setTimer(TIMEOUT_WAITING_FOR_TEST_STARTED);
  39.254 
  39.255             LatencyTestDisplay ltd(2, 0x40090040);
  39.256             Device->SetDisplay(ltd);
  39.257         }
  39.258     }
  39.259     else if (msg.Type == Message_LatencyTestButton)
  39.260     {
  39.261         BeginTest();
  39.262     }
  39.263     else if (msg.Type == Message_LatencyTestStarted)
  39.264     {
  39.265         if (State == State_WaitingForTestStarted)
  39.266         {
  39.267             clearTimer();
  39.268 
  39.269             // Record time so we can determine usb roundtrip time.
  39.270             getActiveResult()->TestStartedTicksMicroS = Timer::GetTicks();
  39.271             
  39.272             State = State_WaitingForColorDetected;
  39.273             OVR_DEBUG_LOG(("State_WaitingForTestStarted -> State_WaitingForColorDetected."));
  39.274 
  39.275             setTimer(TIMEOUT_WAITING_FOR_COLOR_DETECTED);
  39.276         }
  39.277     }
  39.278     else if (msg.Type == Message_LatencyTestColorDetected)
  39.279     {
  39.280         if (State == State_WaitingForColorDetected)
  39.281         {
  39.282             // Record time to detect color.
  39.283             MessageLatencyTestColorDetected* pDetected = (MessageLatencyTestColorDetected*) &msg;
  39.284             UInt16 elapsedTime = pDetected->Elapsed;
  39.285             OVR_DEBUG_LOG(("Time to 'ColorDetected' = %d", elapsedTime));
  39.286             
  39.287             getActiveResult()->DeviceMeasuredElapsedMilliS = elapsedTime;
  39.288 
  39.289             if (areResultsComplete())
  39.290             {
  39.291                 // We're done.
  39.292                 processResults();
  39.293                 reset();
  39.294             }
  39.295             else
  39.296             {
  39.297                 // Run another measurement.
  39.298                 State = State_WaitingForSettlePostMeasurement;
  39.299                 OVR_DEBUG_LOG(("State_WaitingForColorDetected -> State_WaitingForSettlePostMeasurement."));
  39.300 
  39.301                 UInt32 waitTime = TIME_TO_WAIT_FOR_SETTLE_POST_MEASUREMENT + getRandomComponent(TIME_TO_WAIT_FOR_SETTLE_POST_MEASUREMENT_RANDOMNESS);
  39.302                 setTimer(waitTime);
  39.303 
  39.304                 LatencyTestDisplay ltd(2, 0x40400040);
  39.305                 Device->SetDisplay(ltd);
  39.306             }
  39.307         }
  39.308     }
  39.309     else if (msg.Type == Message_DeviceRemoved)
  39.310     {
  39.311         reset();
  39.312     }
  39.313 }
  39.314 
  39.315 LatencyTest::MeasurementResult* LatencyTest::getActiveResult()
  39.316 {
  39.317     OVR_ASSERT(!Results.IsEmpty());    
  39.318     return Results.GetLast();
  39.319 }
  39.320 
  39.321 void LatencyTest::setTimer(UInt32 timeMilliS)
  39.322 {
  39.323     ActiveTimerMilliS = timeMilliS;
  39.324 }
  39.325 
  39.326 void LatencyTest::clearTimer()
  39.327 {
  39.328     ActiveTimerMilliS = 0;
  39.329 }
  39.330 
  39.331 void LatencyTest::reset()
  39.332 {
  39.333     clearMeasurementResults();
  39.334     State = State_WaitingForButton;
  39.335 
  39.336     HaveOldTime = false;
  39.337     ActiveTimerMilliS = 0;
  39.338 }
  39.339 
  39.340 void LatencyTest::clearMeasurementResults()
  39.341 {
  39.342     while(!Results.IsEmpty())
  39.343     {
  39.344         MeasurementResult* pElem = Results.GetFirst();
  39.345         pElem->RemoveNode();
  39.346         delete pElem;
  39.347     }
  39.348 }
  39.349 
  39.350 LatencyTest::LatencyTestHandler::~LatencyTestHandler()
  39.351 {
  39.352     RemoveHandlerFromDevices();
  39.353 }
  39.354 
  39.355 void LatencyTest::LatencyTestHandler::OnMessage(const Message& msg)
  39.356 {
  39.357     pLatencyTestUtil->handleMessage(msg);
  39.358 }
  39.359 
  39.360 void LatencyTest::ProcessInputs()
  39.361 {
  39.362     updateForTimeouts();
  39.363     handleMessage(Message(), LatencyTest_ProcessInputs);
  39.364 }
  39.365 
  39.366 bool LatencyTest::DisplayScreenColor(Color& colorToDisplay)
  39.367 {
  39.368     updateForTimeouts();
  39.369 
  39.370     if (State == State_WaitingForButton)
  39.371     {
  39.372         return false;
  39.373     }
  39.374 
  39.375     colorToDisplay = RenderColor;
  39.376     return true;
  39.377 }
  39.378 
  39.379 const char*	LatencyTest::GetResultsString()
  39.380 {
  39.381 	if (!ResultsString.IsEmpty() && ReturnedResultString != ResultsString.ToCStr())
  39.382 	{
  39.383 		ReturnedResultString = ResultsString;
  39.384 		return ReturnedResultString.ToCStr();
  39.385 	}
  39.386     
  39.387 	return NULL;
  39.388 }
  39.389 
  39.390 bool LatencyTest::areResultsComplete()
  39.391 {
  39.392     UInt32 initialMeasurements = 0;
  39.393 
  39.394     UInt32 measurements1to2 = 0;
  39.395     UInt32 measurements2to1 = 0;
  39.396 
  39.397     MeasurementResult* pCurr = Results.GetFirst();
  39.398     while(true)
  39.399     {
  39.400         // Process.
  39.401         if (!pCurr->TimedOutWaitingForTestStarted &&
  39.402             !pCurr->TimedOutWaitingForColorDetected)
  39.403         {
  39.404             initialMeasurements++;
  39.405 
  39.406             if (initialMeasurements > INITIAL_SAMPLES_TO_IGNORE)
  39.407             {
  39.408                 if (pCurr->TargetColor == COLOR2)
  39.409                 {
  39.410                     measurements1to2++;
  39.411                 }
  39.412                 else
  39.413                 {
  39.414                     measurements2to1++;
  39.415                 }
  39.416             }
  39.417         }
  39.418 
  39.419         if (Results.IsLast(pCurr))
  39.420         {
  39.421             break;
  39.422         }
  39.423         pCurr = Results.GetNext(pCurr);
  39.424     }
  39.425 
  39.426     if (measurements1to2 >= DEFAULT_NUMBER_OF_SAMPLES &&
  39.427         measurements2to1 >= DEFAULT_NUMBER_OF_SAMPLES)
  39.428     {
  39.429         return true;
  39.430     }
  39.431 
  39.432     return false;
  39.433 }
  39.434 
  39.435 void LatencyTest::processResults()
  39.436 {
  39.437 
  39.438     UInt32 minTime1To2 = UINT_MAX;
  39.439     UInt32 maxTime1To2 = 0;
  39.440     float averageTime1To2 = 0.0f;
  39.441     UInt32 minTime2To1 = UINT_MAX;
  39.442     UInt32 maxTime2To1 = 0;
  39.443     float averageTime2To1 = 0.0f;
  39.444 
  39.445     float minUSBTripMilliS = BIG_FLOAT;
  39.446     float maxUSBTripMilliS = SMALL_FLOAT;
  39.447     float averageUSBTripMilliS = 0.0f;
  39.448     UInt32 countUSBTripTime = 0;
  39.449 
  39.450     UInt32 measurementsCount = 0;
  39.451     UInt32 measurements1to2 = 0;
  39.452     UInt32 measurements2to1 = 0;
  39.453 
  39.454     MeasurementResult* pCurr = Results.GetFirst();
  39.455     UInt32 count = 0;
  39.456     while(true)
  39.457     {
  39.458         count++;
  39.459 
  39.460         if (!pCurr->TimedOutWaitingForTestStarted &&
  39.461             !pCurr->TimedOutWaitingForColorDetected)
  39.462         {
  39.463             measurementsCount++;
  39.464 
  39.465             if (measurementsCount > INITIAL_SAMPLES_TO_IGNORE)
  39.466             {
  39.467                 if (pCurr->TargetColor == COLOR2)
  39.468                 {
  39.469                     measurements1to2++;
  39.470 
  39.471                     if (measurements1to2 <= DEFAULT_NUMBER_OF_SAMPLES)
  39.472                     {
  39.473                         UInt32 elapsed = pCurr->DeviceMeasuredElapsedMilliS;
  39.474 
  39.475                         minTime1To2 = Alg::Min(elapsed, minTime1To2);
  39.476                         maxTime1To2 = Alg::Max(elapsed, maxTime1To2);
  39.477 
  39.478                         averageTime1To2 += (float) elapsed;
  39.479                     }
  39.480                 }
  39.481                 else
  39.482                 {
  39.483                     measurements2to1++;
  39.484 
  39.485                     if (measurements2to1 <= DEFAULT_NUMBER_OF_SAMPLES)
  39.486                     {
  39.487                         UInt32 elapsed = pCurr->DeviceMeasuredElapsedMilliS;
  39.488 
  39.489                         minTime2To1 = Alg::Min(elapsed, minTime2To1);
  39.490                         maxTime2To1 = Alg::Max(elapsed, maxTime2To1);
  39.491 
  39.492                         averageTime2To1 += (float) elapsed;
  39.493                     }
  39.494                 }
  39.495 
  39.496                 float usbRountripElapsedMilliS = 0.001f * (float) (pCurr->TestStartedTicksMicroS - pCurr->StartTestTicksMicroS);
  39.497                 minUSBTripMilliS = Alg::Min(usbRountripElapsedMilliS, minUSBTripMilliS);
  39.498                 maxUSBTripMilliS = Alg::Max(usbRountripElapsedMilliS, maxUSBTripMilliS);
  39.499                 averageUSBTripMilliS += usbRountripElapsedMilliS;
  39.500                 countUSBTripTime++;
  39.501             }
  39.502         }
  39.503 
  39.504         if (measurements1to2 >= DEFAULT_NUMBER_OF_SAMPLES &&
  39.505             measurements2to1 >= DEFAULT_NUMBER_OF_SAMPLES)
  39.506         {
  39.507             break;
  39.508         }
  39.509 
  39.510         if (Results.IsLast(pCurr))
  39.511         {
  39.512             break;
  39.513         }
  39.514         pCurr = Results.GetNext(pCurr);
  39.515     }
  39.516 
  39.517     averageTime1To2 /= (float) DEFAULT_NUMBER_OF_SAMPLES;      
  39.518     averageTime2To1 /= (float) DEFAULT_NUMBER_OF_SAMPLES;
  39.519 
  39.520     averageUSBTripMilliS /= countUSBTripTime;
  39.521     
  39.522     float finalResult = 0.5f * (averageTime1To2 + averageTime2To1);
  39.523     finalResult += averageUSBTripMilliS;
  39.524 
  39.525     ResultsString.Clear();
  39.526     ResultsString.AppendFormat("RESULT=%.1f (add half Tracker period) [b->w %d|%.1f|%d] [w->b %d|%.1f|%d] [usb rndtrp %.1f|%.1f|%.1f] [cnt %d] [tmouts %d]",  
  39.527                 finalResult, 
  39.528                 minTime1To2, averageTime1To2, maxTime1To2, 
  39.529                 minTime2To1, averageTime2To1, maxTime2To1,
  39.530                 minUSBTripMilliS, averageUSBTripMilliS, maxUSBTripMilliS,
  39.531                 DEFAULT_NUMBER_OF_SAMPLES*2, count - measurementsCount);
  39.532     
  39.533     // Display result on latency tester display.
  39.534     LatencyTestDisplay ltd(1, (int)finalResult);
  39.535     Device->SetDisplay(ltd);
  39.536 }
  39.537 
  39.538 void LatencyTest::updateForTimeouts()
  39.539 {
  39.540     if (!HaveOldTime)
  39.541     {
  39.542         HaveOldTime = true;
  39.543         OldTime = Timer::GetTicksMs();
  39.544         return;
  39.545     }
  39.546 
  39.547     UInt32 newTime = Timer::GetTicksMs();
  39.548     UInt32 elapsedMilliS = newTime - OldTime;
  39.549     if (newTime < OldTime)
  39.550     {
  39.551         elapsedMilliS = OldTime - newTime;
  39.552         elapsedMilliS = UINT_MAX - elapsedMilliS;
  39.553     }
  39.554     OldTime = newTime;
  39.555 
  39.556     elapsedMilliS = Alg::Min(elapsedMilliS, (UInt32) 100);   // Clamp at 100mS in case we're not being called very often.
  39.557 
  39.558 
  39.559     if (ActiveTimerMilliS == 0)
  39.560     {
  39.561         return;
  39.562     }
  39.563 
  39.564     if (elapsedMilliS >= ActiveTimerMilliS)
  39.565     {
  39.566         ActiveTimerMilliS = 0;
  39.567         handleMessage(Message(), LatencyTest_Timer);
  39.568         return;
  39.569     }
  39.570 
  39.571     ActiveTimerMilliS -= elapsedMilliS;
  39.572 }
  39.573 
  39.574 }} // namespace OVR::Util
  39.575 \ No newline at end of file
  39.576 +/************************************************************************************
  39.577 +
  39.578 +Filename    :   Util_LatencyTest.cpp
  39.579 +Content     :   Wraps the lower level LatencyTester interface and adds functionality.
  39.580 +Created     :   February 14, 2013
  39.581 +Authors     :   Lee Cooper
  39.582 +
  39.583 +Copyright   :   Copyright 2013 Oculus VR, Inc. All Rights reserved.
  39.584 +
  39.585 +Use of this software is subject to the terms of the Oculus license
  39.586 +agreement provided at the time of installation or download, or which
  39.587 +otherwise accompanies this software in either electronic or hard copy form.
  39.588 +
  39.589 +*************************************************************************************/
  39.590 +
  39.591 +#include "Util_LatencyTest.h"
  39.592 +
  39.593 +#include "../Kernel/OVR_Log.h"
  39.594 +#include "../Kernel/OVR_Timer.h"
  39.595 +
  39.596 +namespace OVR { namespace Util {
  39.597 +
  39.598 +static const UInt32     TIME_TO_WAIT_FOR_SETTLE_PRE_CALIBRATION = 16*10;
  39.599 +static const UInt32     TIME_TO_WAIT_FOR_SETTLE_POST_CALIBRATION = 16*10;
  39.600 +static const UInt32     TIME_TO_WAIT_FOR_SETTLE_POST_MEASUREMENT = 16*5;
  39.601 +static const UInt32     TIME_TO_WAIT_FOR_SETTLE_POST_MEASUREMENT_RANDOMNESS = 16*5;
  39.602 +static const UInt32     DEFAULT_NUMBER_OF_SAMPLES = 10;                 // For both color 1->2 and color 2->1 transitions.
  39.603 +static const UInt32     INITIAL_SAMPLES_TO_IGNORE = 4;
  39.604 +static const UInt32     TIMEOUT_WAITING_FOR_TEST_STARTED = 1000;
  39.605 +static const UInt32     TIMEOUT_WAITING_FOR_COLOR_DETECTED = 4000;
  39.606 +static const Color      CALIBRATE_BLACK(0, 0, 0);
  39.607 +static const Color      CALIBRATE_WHITE(255, 255, 255);
  39.608 +static const Color      COLOR1(0, 0, 0);
  39.609 +static const Color      COLOR2(255, 255, 255);
  39.610 +static const Color      SENSOR_DETECT_THRESHOLD(128, 255, 255);
  39.611 +static const float      BIG_FLOAT = 1000000.0f;
  39.612 +static const float      SMALL_FLOAT = -1000000.0f;
  39.613 +
  39.614 +//-------------------------------------------------------------------------------------
  39.615 +// ***** LatencyTest
  39.616 +
  39.617 +LatencyTest::LatencyTest(LatencyTestDevice* device)
  39.618 + :  Handler(getThis())
  39.619 +{
  39.620 +    if (device != NULL)
  39.621 +    {
  39.622 +        SetDevice(device);
  39.623 +    }
  39.624 +
  39.625 +    reset();
  39.626 +
  39.627 +    srand(Timer::GetTicksMs());
  39.628 +}
  39.629 +
  39.630 +LatencyTest::~LatencyTest()
  39.631 +{
  39.632 +     clearMeasurementResults();
  39.633 +}
  39.634 +
  39.635 +bool LatencyTest::SetDevice(LatencyTestDevice* device)
  39.636 +{
  39.637 +
  39.638 +    if (device != Device)
  39.639 +    {
  39.640 +        if (device != NULL)
  39.641 +        {
  39.642 +            if (device->GetMessageHandler() != NULL)
  39.643 +            {
  39.644 +                OVR_DEBUG_LOG(
  39.645 +                    ("LatencyTest::AttachToDevice failed - device %p already has handler", device));
  39.646 +                return false;
  39.647 +            }
  39.648 +        }
  39.649 +
  39.650 +        if (Device != NULL)
  39.651 +        {
  39.652 +            Device->SetMessageHandler(0);
  39.653 +        }
  39.654 +        Device = device;
  39.655 +
  39.656 +        if (Device != NULL)
  39.657 +        {
  39.658 +            Device->SetMessageHandler(&Handler);
  39.659 +
  39.660 +            // Set trigger threshold.
  39.661 +            LatencyTestConfiguration configuration(SENSOR_DETECT_THRESHOLD, false);     // No samples streaming.
  39.662 +            Device->SetConfiguration(configuration, true);
  39.663 +
  39.664 +            // Set display to intial (3 dashes).
  39.665 +            LatencyTestDisplay ltd(2, 0x40400040);
  39.666 +            Device->SetDisplay(ltd);
  39.667 +        }
  39.668 +    }
  39.669 +
  39.670 +    return true;
  39.671 +}
  39.672 +
  39.673 +UInt32 LatencyTest::getRandomComponent(UInt32 range)
  39.674 +{
  39.675 +    UInt32 val = rand() % range;
  39.676 +    return val;
  39.677 +}
  39.678 +
  39.679 +void LatencyTest::BeginTest()
  39.680 +{
  39.681 +     if (State == State_WaitingForButton)
  39.682 +    {
  39.683 +        // Set color to black and wait a while.
  39.684 +        RenderColor = CALIBRATE_BLACK;
  39.685 +
  39.686 +        State = State_WaitingForSettlePreCalibrationColorBlack;
  39.687 +        OVR_DEBUG_LOG(("State_WaitingForButton -> State_WaitingForSettlePreCalibrationColorBlack."));
  39.688 +
  39.689 +        setTimer(TIME_TO_WAIT_FOR_SETTLE_PRE_CALIBRATION);
  39.690 +    }
  39.691 +}
  39.692 +
  39.693 +void LatencyTest::handleMessage(const Message& msg, LatencyTestMessageType latencyTestMessage)
  39.694 +{
  39.695 +    // For debugging.
  39.696 +/*  if (msg.Type == Message_LatencyTestSamples)
  39.697 +    {
  39.698 +        MessageLatencyTestSamples* pSamples = (MessageLatencyTestSamples*) &msg;
  39.699 +
  39.700 +        if (pSamples->Samples.GetSize() > 0)
  39.701 +        {
  39.702 +            // Just show the first one for now.
  39.703 +            Color c = pSamples->Samples[0];
  39.704 +            OVR_DEBUG_LOG(("%d %d %d", c.R, c.G, c.B));
  39.705 +        }
  39.706 +        return;
  39.707 +    }
  39.708 +*/
  39.709 +
  39.710 +    if (latencyTestMessage == LatencyTest_Timer)
  39.711 +    {
  39.712 +        if (!Device)
  39.713 +        {
  39.714 +            reset();
  39.715 +            return;
  39.716 +        }
  39.717 +        
  39.718 +        if (State == State_WaitingForSettlePreCalibrationColorBlack)
  39.719 +        {
  39.720 +            // Send calibrate message to device and wait a while.
  39.721 +            Device->SetCalibrate(CALIBRATE_BLACK);
  39.722 +
  39.723 +            State = State_WaitingForSettlePostCalibrationColorBlack;
  39.724 +            OVR_DEBUG_LOG(("State_WaitingForSettlePreCalibrationColorBlack -> State_WaitingForSettlePostCalibrationColorBlack."));
  39.725 +
  39.726 +            setTimer(TIME_TO_WAIT_FOR_SETTLE_POST_CALIBRATION);
  39.727 +        }
  39.728 +        else if (State == State_WaitingForSettlePostCalibrationColorBlack)
  39.729 +        {
  39.730 +            // Change color to white and wait a while.
  39.731 +            RenderColor = CALIBRATE_WHITE;
  39.732 +
  39.733 +            State = State_WaitingForSettlePreCalibrationColorWhite;
  39.734 +            OVR_DEBUG_LOG(("State_WaitingForSettlePostCalibrationColorBlack -> State_WaitingForSettlePreCalibrationColorWhite."));
  39.735 +
  39.736 +            setTimer(TIME_TO_WAIT_FOR_SETTLE_PRE_CALIBRATION);
  39.737 +        }
  39.738 +        else if (State == State_WaitingForSettlePreCalibrationColorWhite)
  39.739 +        {
  39.740 +            // Send calibrate message to device and wait a while.
  39.741 +            Device->SetCalibrate(CALIBRATE_WHITE);
  39.742 +
  39.743 +            State = State_WaitingForSettlePostCalibrationColorWhite;
  39.744 +            OVR_DEBUG_LOG(("State_WaitingForSettlePreCalibrationColorWhite -> State_WaitingForSettlePostCalibrationColorWhite."));
  39.745 +
  39.746 +            setTimer(TIME_TO_WAIT_FOR_SETTLE_POST_CALIBRATION);
  39.747 +        }
  39.748 +        else if (State == State_WaitingForSettlePostCalibrationColorWhite)
  39.749 +        {
  39.750 +            // Calibration is done. Switch to color 1 and wait for it to settle.
  39.751 +            RenderColor = COLOR1;
  39.752 +
  39.753 +            State = State_WaitingForSettlePostMeasurement;
  39.754 +            OVR_DEBUG_LOG(("State_WaitingForSettlePostCalibrationColorWhite -> State_WaitingForSettlePostMeasurement."));
  39.755 +
  39.756 +            UInt32 waitTime = TIME_TO_WAIT_FOR_SETTLE_POST_MEASUREMENT + getRandomComponent(TIME_TO_WAIT_FOR_SETTLE_POST_MEASUREMENT_RANDOMNESS);
  39.757 +            setTimer(waitTime);
  39.758 +        }
  39.759 +        else if (State == State_WaitingForSettlePostMeasurement)
  39.760 +        {
  39.761 +            // Prepare for next measurement.
  39.762 +
  39.763 +            // Create a new result object.
  39.764 +            MeasurementResult* pResult = new MeasurementResult();
  39.765 +            Results.PushBack(pResult);
  39.766 +
  39.767 +            State = State_WaitingToTakeMeasurement;
  39.768 +            OVR_DEBUG_LOG(("State_WaitingForSettlePostMeasurement -> State_WaitingToTakeMeasurement."));
  39.769 +        }
  39.770 +        else if (State == State_WaitingForTestStarted)
  39.771 +        {
  39.772 +            // We timed out waiting for 'TestStarted'. Abandon this measurement and setup for the next.
  39.773 +            getActiveResult()->TimedOutWaitingForTestStarted = true;
  39.774 +
  39.775 +            State = State_WaitingForSettlePostMeasurement;
  39.776 +            OVR_DEBUG_LOG(("** Timed out waiting for 'TestStarted'."));
  39.777 +            OVR_DEBUG_LOG(("State_WaitingForTestStarted -> State_WaitingForSettlePostMeasurement."));
  39.778 +
  39.779 +            UInt32 waitTime = TIME_TO_WAIT_FOR_SETTLE_POST_MEASUREMENT + getRandomComponent(TIME_TO_WAIT_FOR_SETTLE_POST_MEASUREMENT_RANDOMNESS);
  39.780 +            setTimer(waitTime);
  39.781 +        }
  39.782 +        else if (State == State_WaitingForColorDetected)
  39.783 +        {
  39.784 +            // We timed out waiting for 'ColorDetected'. Abandon this measurement and setup for the next.
  39.785 +            getActiveResult()->TimedOutWaitingForColorDetected = true;
  39.786 +
  39.787 +            State = State_WaitingForSettlePostMeasurement;
  39.788 +            OVR_DEBUG_LOG(("** Timed out waiting for 'ColorDetected'."));
  39.789 +            OVR_DEBUG_LOG(("State_WaitingForColorDetected -> State_WaitingForSettlePostMeasurement."));
  39.790 +
  39.791 +            UInt32 waitTime = TIME_TO_WAIT_FOR_SETTLE_POST_MEASUREMENT + getRandomComponent(TIME_TO_WAIT_FOR_SETTLE_POST_MEASUREMENT_RANDOMNESS);
  39.792 +            setTimer(waitTime);
  39.793 +        }
  39.794 +    }
  39.795 +    else if (latencyTestMessage == LatencyTest_ProcessInputs)
  39.796 +    {
  39.797 +        if (State == State_WaitingToTakeMeasurement)
  39.798 +        {
  39.799 +            if (!Device)
  39.800 +            {
  39.801 +                reset();
  39.802 +                return;
  39.803 +            }
  39.804 +            
  39.805 +            // Send 'StartTest' feature report with opposite target color.
  39.806 +            if (RenderColor == COLOR1)
  39.807 +            {
  39.808 +                RenderColor = COLOR2;
  39.809 +            }
  39.810 +            else
  39.811 +            {
  39.812 +                RenderColor = COLOR1;
  39.813 +            }
  39.814 +
  39.815 +            getActiveResult()->TargetColor = RenderColor;
  39.816 +            
  39.817 +            // Record time so we can determine usb roundtrip time.
  39.818 +            getActiveResult()->StartTestTicksMicroS = Timer::GetTicks();
  39.819 +
  39.820 +            Device->SetStartTest(RenderColor);
  39.821 +
  39.822 +            State = State_WaitingForTestStarted;
  39.823 +            OVR_DEBUG_LOG(("State_WaitingToTakeMeasurement -> State_WaitingForTestStarted."));
  39.824 +
  39.825 +            setTimer(TIMEOUT_WAITING_FOR_TEST_STARTED);
  39.826 +
  39.827 +            LatencyTestDisplay ltd(2, 0x40090040);
  39.828 +            Device->SetDisplay(ltd);
  39.829 +        }
  39.830 +    }
  39.831 +    else if (msg.Type == Message_LatencyTestButton)
  39.832 +    {
  39.833 +        BeginTest();
  39.834 +    }
  39.835 +    else if (msg.Type == Message_LatencyTestStarted)
  39.836 +    {
  39.837 +        if (State == State_WaitingForTestStarted)
  39.838 +        {
  39.839 +            clearTimer();
  39.840 +
  39.841 +            // Record time so we can determine usb roundtrip time.
  39.842 +            getActiveResult()->TestStartedTicksMicroS = Timer::GetTicks();
  39.843 +            
  39.844 +            State = State_WaitingForColorDetected;
  39.845 +            OVR_DEBUG_LOG(("State_WaitingForTestStarted -> State_WaitingForColorDetected."));
  39.846 +
  39.847 +            setTimer(TIMEOUT_WAITING_FOR_COLOR_DETECTED);
  39.848 +        }
  39.849 +    }
  39.850 +    else if (msg.Type == Message_LatencyTestColorDetected)
  39.851 +    {
  39.852 +        if (State == State_WaitingForColorDetected)
  39.853 +        {
  39.854 +            // Record time to detect color.
  39.855 +            MessageLatencyTestColorDetected* pDetected = (MessageLatencyTestColorDetected*) &msg;
  39.856 +            UInt16 elapsedTime = pDetected->Elapsed;
  39.857 +            OVR_DEBUG_LOG(("Time to 'ColorDetected' = %d", elapsedTime));
  39.858 +            
  39.859 +            getActiveResult()->DeviceMeasuredElapsedMilliS = elapsedTime;
  39.860 +
  39.861 +            if (areResultsComplete())
  39.862 +            {
  39.863 +                // We're done.
  39.864 +                processResults();
  39.865 +                reset();
  39.866 +            }
  39.867 +            else
  39.868 +            {
  39.869 +                // Run another measurement.
  39.870 +                State = State_WaitingForSettlePostMeasurement;
  39.871 +                OVR_DEBUG_LOG(("State_WaitingForColorDetected -> State_WaitingForSettlePostMeasurement."));
  39.872 +
  39.873 +                UInt32 waitTime = TIME_TO_WAIT_FOR_SETTLE_POST_MEASUREMENT + getRandomComponent(TIME_TO_WAIT_FOR_SETTLE_POST_MEASUREMENT_RANDOMNESS);
  39.874 +                setTimer(waitTime);
  39.875 +
  39.876 +                LatencyTestDisplay ltd(2, 0x40400040);
  39.877 +                Device->SetDisplay(ltd);
  39.878 +            }
  39.879 +        }
  39.880 +    }
  39.881 +    else if (msg.Type == Message_DeviceRemoved)
  39.882 +    {
  39.883 +        reset();
  39.884 +    }
  39.885 +}
  39.886 +
  39.887 +LatencyTest::MeasurementResult* LatencyTest::getActiveResult()
  39.888 +{
  39.889 +    OVR_ASSERT(!Results.IsEmpty());    
  39.890 +    return Results.GetLast();
  39.891 +}
  39.892 +
  39.893 +void LatencyTest::setTimer(UInt32 timeMilliS)
  39.894 +{
  39.895 +    ActiveTimerMilliS = timeMilliS;
  39.896 +}
  39.897 +
  39.898 +void LatencyTest::clearTimer()
  39.899 +{
  39.900 +    ActiveTimerMilliS = 0;
  39.901 +}
  39.902 +
  39.903 +void LatencyTest::reset()
  39.904 +{
  39.905 +    clearMeasurementResults();
  39.906 +    State = State_WaitingForButton;
  39.907 +
  39.908 +    HaveOldTime = false;
  39.909 +    ActiveTimerMilliS = 0;
  39.910 +}
  39.911 +
  39.912 +void LatencyTest::clearMeasurementResults()
  39.913 +{
  39.914 +    while(!Results.IsEmpty())
  39.915 +    {
  39.916 +        MeasurementResult* pElem = Results.GetFirst();
  39.917 +        pElem->RemoveNode();
  39.918 +        delete pElem;
  39.919 +    }
  39.920 +}
  39.921 +
  39.922 +LatencyTest::LatencyTestHandler::~LatencyTestHandler()
  39.923 +{
  39.924 +    RemoveHandlerFromDevices();
  39.925 +}
  39.926 +
  39.927 +void LatencyTest::LatencyTestHandler::OnMessage(const Message& msg)
  39.928 +{
  39.929 +    pLatencyTestUtil->handleMessage(msg);
  39.930 +}
  39.931 +
  39.932 +void LatencyTest::ProcessInputs()
  39.933 +{
  39.934 +    updateForTimeouts();
  39.935 +    handleMessage(Message(), LatencyTest_ProcessInputs);
  39.936 +}
  39.937 +
  39.938 +bool LatencyTest::DisplayScreenColor(Color& colorToDisplay)
  39.939 +{
  39.940 +    updateForTimeouts();
  39.941 +
  39.942 +    if (State == State_WaitingForButton)
  39.943 +    {
  39.944 +        return false;
  39.945 +    }
  39.946 +
  39.947 +    colorToDisplay = RenderColor;
  39.948 +    return true;
  39.949 +}
  39.950 +
  39.951 +const char*	LatencyTest::GetResultsString()
  39.952 +{
  39.953 +	if (!ResultsString.IsEmpty() && ReturnedResultString != ResultsString.ToCStr())
  39.954 +	{
  39.955 +		ReturnedResultString = ResultsString;
  39.956 +		return ReturnedResultString.ToCStr();
  39.957 +	}
  39.958 +    
  39.959 +	return NULL;
  39.960 +}
  39.961 +
  39.962 +bool LatencyTest::areResultsComplete()
  39.963 +{
  39.964 +    UInt32 initialMeasurements = 0;
  39.965 +
  39.966 +    UInt32 measurements1to2 = 0;
  39.967 +    UInt32 measurements2to1 = 0;
  39.968 +
  39.969 +    MeasurementResult* pCurr = Results.GetFirst();
  39.970 +    while(true)
  39.971 +    {
  39.972 +        // Process.
  39.973 +        if (!pCurr->TimedOutWaitingForTestStarted &&
  39.974 +            !pCurr->TimedOutWaitingForColorDetected)
  39.975 +        {
  39.976 +            initialMeasurements++;
  39.977 +
  39.978 +            if (initialMeasurements > INITIAL_SAMPLES_TO_IGNORE)
  39.979 +            {
  39.980 +                if (pCurr->TargetColor == COLOR2)
  39.981 +                {
  39.982 +                    measurements1to2++;
  39.983 +                }
  39.984 +                else
  39.985 +                {
  39.986 +                    measurements2to1++;
  39.987 +                }
  39.988 +            }
  39.989 +        }
  39.990 +
  39.991 +        if (Results.IsLast(pCurr))
  39.992 +        {
  39.993 +            break;
  39.994 +        }
  39.995 +        pCurr = Results.GetNext(pCurr);
  39.996 +    }
  39.997 +
  39.998 +    if (measurements1to2 >= DEFAULT_NUMBER_OF_SAMPLES &&
  39.999 +        measurements2to1 >= DEFAULT_NUMBER_OF_SAMPLES)
 39.1000 +    {
 39.1001 +        return true;
 39.1002 +    }
 39.1003 +
 39.1004 +    return false;
 39.1005 +}
 39.1006 +
 39.1007 +void LatencyTest::processResults()
 39.1008 +{
 39.1009 +
 39.1010 +    UInt32 minTime1To2 = UINT_MAX;
 39.1011 +    UInt32 maxTime1To2 = 0;
 39.1012 +    float averageTime1To2 = 0.0f;
 39.1013 +    UInt32 minTime2To1 = UINT_MAX;
 39.1014 +    UInt32 maxTime2To1 = 0;
 39.1015 +    float averageTime2To1 = 0.0f;
 39.1016 +
 39.1017 +    float minUSBTripMilliS = BIG_FLOAT;
 39.1018 +    float maxUSBTripMilliS = SMALL_FLOAT;
 39.1019 +    float averageUSBTripMilliS = 0.0f;
 39.1020 +    UInt32 countUSBTripTime = 0;
 39.1021 +
 39.1022 +    UInt32 measurementsCount = 0;
 39.1023 +    UInt32 measurements1to2 = 0;
 39.1024 +    UInt32 measurements2to1 = 0;
 39.1025 +
 39.1026 +    MeasurementResult* pCurr = Results.GetFirst();
 39.1027 +    UInt32 count = 0;
 39.1028 +    while(true)
 39.1029 +    {
 39.1030 +        count++;
 39.1031 +
 39.1032 +        if (!pCurr->TimedOutWaitingForTestStarted &&
 39.1033 +            !pCurr->TimedOutWaitingForColorDetected)
 39.1034 +        {
 39.1035 +            measurementsCount++;
 39.1036 +
 39.1037 +            if (measurementsCount > INITIAL_SAMPLES_TO_IGNORE)
 39.1038 +            {
 39.1039 +                if (pCurr->TargetColor == COLOR2)
 39.1040 +                {
 39.1041 +                    measurements1to2++;
 39.1042 +
 39.1043 +                    if (measurements1to2 <= DEFAULT_NUMBER_OF_SAMPLES)
 39.1044 +                    {
 39.1045 +                        UInt32 elapsed = pCurr->DeviceMeasuredElapsedMilliS;
 39.1046 +
 39.1047 +                        minTime1To2 = Alg::Min(elapsed, minTime1To2);
 39.1048 +                        maxTime1To2 = Alg::Max(elapsed, maxTime1To2);
 39.1049 +
 39.1050 +                        averageTime1To2 += (float) elapsed;
 39.1051 +                    }
 39.1052 +                }
 39.1053 +                else
 39.1054 +                {
 39.1055 +                    measurements2to1++;
 39.1056 +
 39.1057 +                    if (measurements2to1 <= DEFAULT_NUMBER_OF_SAMPLES)
 39.1058 +                    {
 39.1059 +                        UInt32 elapsed = pCurr->DeviceMeasuredElapsedMilliS;
 39.1060 +
 39.1061 +                        minTime2To1 = Alg::Min(elapsed, minTime2To1);
 39.1062 +                        maxTime2To1 = Alg::Max(elapsed, maxTime2To1);
 39.1063 +
 39.1064 +                        averageTime2To1 += (float) elapsed;
 39.1065 +                    }
 39.1066 +                }
 39.1067 +
 39.1068 +                float usbRountripElapsedMilliS = 0.001f * (float) (pCurr->TestStartedTicksMicroS - pCurr->StartTestTicksMicroS);
 39.1069 +                minUSBTripMilliS = Alg::Min(usbRountripElapsedMilliS, minUSBTripMilliS);
 39.1070 +                maxUSBTripMilliS = Alg::Max(usbRountripElapsedMilliS, maxUSBTripMilliS);
 39.1071 +                averageUSBTripMilliS += usbRountripElapsedMilliS;
 39.1072 +                countUSBTripTime++;
 39.1073 +            }
 39.1074 +        }
 39.1075 +
 39.1076 +        if (measurements1to2 >= DEFAULT_NUMBER_OF_SAMPLES &&
 39.1077 +            measurements2to1 >= DEFAULT_NUMBER_OF_SAMPLES)
 39.1078 +        {
 39.1079 +            break;
 39.1080 +        }
 39.1081 +
 39.1082 +        if (Results.IsLast(pCurr))
 39.1083 +        {
 39.1084 +            break;
 39.1085 +        }
 39.1086 +        pCurr = Results.GetNext(pCurr);
 39.1087 +    }
 39.1088 +
 39.1089 +    averageTime1To2 /= (float) DEFAULT_NUMBER_OF_SAMPLES;      
 39.1090 +    averageTime2To1 /= (float) DEFAULT_NUMBER_OF_SAMPLES;
 39.1091 +
 39.1092 +    averageUSBTripMilliS /= countUSBTripTime;
 39.1093 +    
 39.1094 +    float finalResult = 0.5f * (averageTime1To2 + averageTime2To1);
 39.1095 +    finalResult += averageUSBTripMilliS;
 39.1096 +
 39.1097 +    ResultsString.Clear();
 39.1098 +    ResultsString.AppendFormat("RESULT=%.1f (add half Tracker period) [b->w %d|%.1f|%d] [w->b %d|%.1f|%d] [usb rndtrp %.1f|%.1f|%.1f] [cnt %d] [tmouts %d]",  
 39.1099 +                finalResult, 
 39.1100 +                minTime1To2, averageTime1To2, maxTime1To2, 
 39.1101 +                minTime2To1, averageTime2To1, maxTime2To1,
 39.1102 +                minUSBTripMilliS, averageUSBTripMilliS, maxUSBTripMilliS,
 39.1103 +                DEFAULT_NUMBER_OF_SAMPLES*2, count - measurementsCount);
 39.1104 +    
 39.1105 +    // Display result on latency tester display.
 39.1106 +    LatencyTestDisplay ltd(1, (int)finalResult);
 39.1107 +    Device->SetDisplay(ltd);
 39.1108 +}
 39.1109 +
 39.1110 +void LatencyTest::updateForTimeouts()
 39.1111 +{
 39.1112 +    if (!HaveOldTime)
 39.1113 +    {
 39.1114 +        HaveOldTime = true;
 39.1115 +        OldTime = Timer::GetTicksMs();
 39.1116 +        return;
 39.1117 +    }
 39.1118 +
 39.1119 +    UInt32 newTime = Timer::GetTicksMs();
 39.1120 +    UInt32 elapsedMilliS = newTime - OldTime;
 39.1121 +    if (newTime < OldTime)
 39.1122 +    {
 39.1123 +        elapsedMilliS = OldTime - newTime;
 39.1124 +        elapsedMilliS = UINT_MAX - elapsedMilliS;
 39.1125 +    }
 39.1126 +    OldTime = newTime;
 39.1127 +
 39.1128 +    elapsedMilliS = Alg::Min(elapsedMilliS, (UInt32) 100);   // Clamp at 100mS in case we're not being called very often.
 39.1129 +
 39.1130 +
 39.1131 +    if (ActiveTimerMilliS == 0)
 39.1132 +    {
 39.1133 +        return;
 39.1134 +    }
 39.1135 +
 39.1136 +    if (elapsedMilliS >= ActiveTimerMilliS)
 39.1137 +    {
 39.1138 +        ActiveTimerMilliS = 0;
 39.1139 +        handleMessage(Message(), LatencyTest_Timer);
 39.1140 +        return;
 39.1141 +    }
 39.1142 +
 39.1143 +    ActiveTimerMilliS -= elapsedMilliS;
 39.1144 +}
 39.1145 +
 39.1146 +}} // namespace OVR::Util
    40.1 --- a/libovr/Src/Util/Util_LatencyTest.h	Sat Sep 14 17:51:03 2013 +0300
    40.2 +++ b/libovr/Src/Util/Util_LatencyTest.h	Sun Sep 15 04:10:05 2013 +0300
    40.3 @@ -1,1 +1,160 @@
    40.4 -/************************************************************************************
    40.5 
    40.6 PublicHeader:   OVR.h
    40.7 Filename    :   Util_LatencyTest.h
    40.8 Content     :   Wraps the lower level LatencyTesterDevice and adds functionality.
    40.9 Created     :   February 14, 2013
   40.10 Authors     :   Lee Cooper
   40.11 
   40.12 Copyright   :   Copyright 2013 Oculus VR, Inc. All Rights reserved.
   40.13 
   40.14 Use of this software is subject to the terms of the Oculus license
   40.15 agreement provided at the time of installation or download, or which
   40.16 otherwise accompanies this software in either electronic or hard copy form.
   40.17 
   40.18 *************************************************************************************/
   40.19 
   40.20 #ifndef OVR_Util_LatencyTest_h
   40.21 #define OVR_Util_LatencyTest_h
   40.22 
   40.23 #include "../OVR_Device.h"
   40.24 
   40.25 #include "../Kernel/OVR_String.h"
   40.26 #include "../Kernel/OVR_List.h"
   40.27 
   40.28 namespace OVR { namespace Util {
   40.29 
   40.30 
   40.31 //-------------------------------------------------------------------------------------
   40.32 // ***** LatencyTest
   40.33 //
   40.34 // LatencyTest utility class wraps the low level LatencyTestDevice and manages the scheduling
   40.35 // of a latency test. A single test is composed of a series of individual latency measurements
   40.36 // which are used to derive min, max, and an average latency value.
   40.37 //
   40.38 // Developers are required to call the following methods:
   40.39 //      SetDevice - Sets the LatencyTestDevice to be used for the tests.
   40.40 //      ProcessInputs - This should be called at the same place in the code where the game engine
   40.41 //                      reads the headset orientation from LibOVR (typically done by calling
   40.42 //                      'GetOrientation' on the SensorFusion object). Calling this at the right time
   40.43 //                      enables us to measure the same latency that occurs for headset orientation
   40.44 //                      changes.
   40.45 //      DisplayScreenColor -    The latency tester works by sensing the color of the pixels directly
   40.46 //                              beneath it. The color of these pixels can be set by drawing a small
   40.47 //                              quad at the end of the rendering stage. The quad should be small
   40.48 //                              such that it doesn't significantly impact the rendering of the scene,
   40.49 //                              but large enough to be 'seen' by the sensor. See the SDK
   40.50 //                              documentation for more information.
   40.51 //		GetResultsString -	Call this to get a string containing the most recent results.
   40.52 //							If the string has already been gotten then NULL will be returned.
   40.53 //							The string pointer will remain valid until the next time this 
   40.54 //							method is called.
   40.55 //
   40.56 
   40.57 class LatencyTest : public NewOverrideBase
   40.58 {
   40.59 public:
   40.60     LatencyTest(LatencyTestDevice* device = NULL);
   40.61     ~LatencyTest();
   40.62     
   40.63     // Set the Latency Tester device that we'll use to send commands to and receive
   40.64     // notification messages from.
   40.65     bool        SetDevice(LatencyTestDevice* device);
   40.66 
   40.67     // Returns true if this LatencyTestUtil has a Latency Tester device.
   40.68     bool        HasDevice() const
   40.69     { return Handler.IsHandlerInstalled(); }
   40.70 
   40.71     void        ProcessInputs();
   40.72     bool        DisplayScreenColor(Color& colorToDisplay);
   40.73 	const char*	GetResultsString();
   40.74 
   40.75     // Begin test. Equivalent to pressing the button on the latency tester.
   40.76     void BeginTest();
   40.77 
   40.78 private:
   40.79     LatencyTest* getThis()  { return this; }
   40.80 
   40.81     enum LatencyTestMessageType
   40.82     {
   40.83         LatencyTest_None,
   40.84         LatencyTest_Timer,
   40.85         LatencyTest_ProcessInputs,
   40.86     };
   40.87     
   40.88     UInt32 getRandomComponent(UInt32 range);
   40.89     void handleMessage(const Message& msg, LatencyTestMessageType latencyTestMessage = LatencyTest_None);
   40.90     void reset();
   40.91     void setTimer(UInt32 timeMilliS);
   40.92     void clearTimer();
   40.93 
   40.94     class LatencyTestHandler : public MessageHandler
   40.95     {
   40.96         LatencyTest*    pLatencyTestUtil;
   40.97     public:
   40.98         LatencyTestHandler(LatencyTest* latencyTester) : pLatencyTestUtil(latencyTester) { }
   40.99         ~LatencyTestHandler();
  40.100 
  40.101         virtual void OnMessage(const Message& msg);
  40.102     };
  40.103 
  40.104     bool areResultsComplete();
  40.105     void processResults();
  40.106     void updateForTimeouts();
  40.107 
  40.108     Ptr<LatencyTestDevice>      Device;
  40.109     LatencyTestHandler          Handler;
  40.110 
  40.111     enum TesterState
  40.112     {
  40.113         State_WaitingForButton,
  40.114         State_WaitingForSettlePreCalibrationColorBlack,
  40.115         State_WaitingForSettlePostCalibrationColorBlack,
  40.116         State_WaitingForSettlePreCalibrationColorWhite,
  40.117         State_WaitingForSettlePostCalibrationColorWhite,
  40.118         State_WaitingToTakeMeasurement,
  40.119         State_WaitingForTestStarted,
  40.120         State_WaitingForColorDetected,
  40.121         State_WaitingForSettlePostMeasurement
  40.122     };
  40.123     TesterState                 State;
  40.124 
  40.125     bool                        HaveOldTime;
  40.126     UInt32                      OldTime;
  40.127     UInt32                      ActiveTimerMilliS;
  40.128 
  40.129     Color                       RenderColor;
  40.130 
  40.131     struct MeasurementResult : public ListNode<MeasurementResult>, public NewOverrideBase
  40.132     {
  40.133         MeasurementResult()
  40.134          :  DeviceMeasuredElapsedMilliS(0),
  40.135             TimedOutWaitingForTestStarted(false),
  40.136             TimedOutWaitingForColorDetected(false),
  40.137             StartTestTicksMicroS(0),
  40.138             TestStartedTicksMicroS(0)
  40.139         {}
  40.140 
  40.141         Color                   TargetColor;
  40.142 
  40.143         UInt32                  DeviceMeasuredElapsedMilliS;
  40.144 
  40.145         bool                    TimedOutWaitingForTestStarted;
  40.146         bool                    TimedOutWaitingForColorDetected;
  40.147 
  40.148         UInt64                  StartTestTicksMicroS;
  40.149         UInt64                  TestStartedTicksMicroS;
  40.150     };
  40.151 
  40.152     List<MeasurementResult>     Results;
  40.153     void clearMeasurementResults();
  40.154 
  40.155     MeasurementResult*          getActiveResult();
  40.156 
  40.157     StringBuffer			    ResultsString;
  40.158 	String					    ReturnedResultString;
  40.159 };
  40.160 
  40.161 }} // namespace OVR::Util
  40.162 
  40.163 #endif // OVR_Util_LatencyTest_h
  40.164 \ No newline at end of file
  40.165 +/************************************************************************************
  40.166 +
  40.167 +PublicHeader:   OVR.h
  40.168 +Filename    :   Util_LatencyTest.h
  40.169 +Content     :   Wraps the lower level LatencyTesterDevice and adds functionality.
  40.170 +Created     :   February 14, 2013
  40.171 +Authors     :   Lee Cooper
  40.172 +
  40.173 +Copyright   :   Copyright 2013 Oculus VR, Inc. All Rights reserved.
  40.174 +
  40.175 +Use of this software is subject to the terms of the Oculus license
  40.176 +agreement provided at the time of installation or download, or which
  40.177 +otherwise accompanies this software in either electronic or hard copy form.
  40.178 +
  40.179 +*************************************************************************************/
  40.180 +
  40.181 +#ifndef OVR_Util_LatencyTest_h
  40.182 +#define OVR_Util_LatencyTest_h
  40.183 +
  40.184 +#include "../OVR_Device.h"
  40.185 +
  40.186 +#include "../Kernel/OVR_String.h"
  40.187 +#include "../Kernel/OVR_List.h"
  40.188 +
  40.189 +namespace OVR { namespace Util {
  40.190 +
  40.191 +
  40.192 +//-------------------------------------------------------------------------------------
  40.193 +// ***** LatencyTest
  40.194 +//
  40.195 +// LatencyTest utility class wraps the low level LatencyTestDevice and manages the scheduling
  40.196 +// of a latency test. A single test is composed of a series of individual latency measurements
  40.197 +// which are used to derive min, max, and an average latency value.
  40.198 +//
  40.199 +// Developers are required to call the following methods:
  40.200 +//      SetDevice - Sets the LatencyTestDevice to be used for the tests.
  40.201 +//      ProcessInputs - This should be called at the same place in the code where the game engine
  40.202 +//                      reads the headset orientation from LibOVR (typically done by calling
  40.203 +//                      'GetOrientation' on the SensorFusion object). Calling this at the right time
  40.204 +//                      enables us to measure the same latency that occurs for headset orientation
  40.205 +//                      changes.
  40.206 +//      DisplayScreenColor -    The latency tester works by sensing the color of the pixels directly
  40.207 +//                              beneath it. The color of these pixels can be set by drawing a small
  40.208 +//                              quad at the end of the rendering stage. The quad should be small
  40.209 +//                              such that it doesn't significantly impact the rendering of the scene,
  40.210 +//                              but large enough to be 'seen' by the sensor. See the SDK
  40.211 +//                              documentation for more information.
  40.212 +//		GetResultsString -	Call this to get a string containing the most recent results.
  40.213 +//							If the string has already been gotten then NULL will be returned.
  40.214 +//							The string pointer will remain valid until the next time this 
  40.215 +//							method is called.
  40.216 +//
  40.217 +
  40.218 +class LatencyTest : public NewOverrideBase
  40.219 +{
  40.220 +public:
  40.221 +    LatencyTest(LatencyTestDevice* device = NULL);
  40.222 +    ~LatencyTest();
  40.223 +    
  40.224 +    // Set the Latency Tester device that we'll use to send commands to and receive
  40.225 +    // notification messages from.
  40.226 +    bool        SetDevice(LatencyTestDevice* device);
  40.227 +
  40.228 +    // Returns true if this LatencyTestUtil has a Latency Tester device.
  40.229 +    bool        HasDevice() const
  40.230 +    { return Handler.IsHandlerInstalled(); }
  40.231 +
  40.232 +    void        ProcessInputs();
  40.233 +    bool        DisplayScreenColor(Color& colorToDisplay);
  40.234 +	const char*	GetResultsString();
  40.235 +
  40.236 +    // Begin test. Equivalent to pressing the button on the latency tester.
  40.237 +    void BeginTest();
  40.238 +
  40.239 +private:
  40.240 +    LatencyTest* getThis()  { return this; }
  40.241 +
  40.242 +    enum LatencyTestMessageType
  40.243 +    {
  40.244 +        LatencyTest_None,
  40.245 +        LatencyTest_Timer,
  40.246 +        LatencyTest_ProcessInputs,
  40.247 +    };
  40.248 +    
  40.249 +    UInt32 getRandomComponent(UInt32 range);
  40.250 +    void handleMessage(const Message& msg, LatencyTestMessageType latencyTestMessage = LatencyTest_None);
  40.251 +    void reset();
  40.252 +    void setTimer(UInt32 timeMilliS);
  40.253 +    void clearTimer();
  40.254 +
  40.255 +    class LatencyTestHandler : public MessageHandler
  40.256 +    {
  40.257 +        LatencyTest*    pLatencyTestUtil;
  40.258 +    public:
  40.259 +        LatencyTestHandler(LatencyTest* latencyTester) : pLatencyTestUtil(latencyTester) { }
  40.260 +        ~LatencyTestHandler();
  40.261 +
  40.262 +        virtual void OnMessage(const Message& msg);
  40.263 +    };
  40.264 +
  40.265 +    bool areResultsComplete();
  40.266 +    void processResults();
  40.267 +    void updateForTimeouts();
  40.268 +
  40.269 +    Ptr<LatencyTestDevice>      Device;
  40.270 +    LatencyTestHandler          Handler;
  40.271 +
  40.272 +    enum TesterState
  40.273 +    {
  40.274 +        State_WaitingForButton,
  40.275 +        State_WaitingForSettlePreCalibrationColorBlack,
  40.276 +        State_WaitingForSettlePostCalibrationColorBlack,
  40.277 +        State_WaitingForSettlePreCalibrationColorWhite,
  40.278 +        State_WaitingForSettlePostCalibrationColorWhite,
  40.279 +        State_WaitingToTakeMeasurement,
  40.280 +        State_WaitingForTestStarted,
  40.281 +        State_WaitingForColorDetected,
  40.282 +        State_WaitingForSettlePostMeasurement
  40.283 +    };
  40.284 +    TesterState                 State;
  40.285 +
  40.286 +    bool                        HaveOldTime;
  40.287 +    UInt32                      OldTime;
  40.288 +    UInt32                      ActiveTimerMilliS;
  40.289 +
  40.290 +    Color                       RenderColor;
  40.291 +
  40.292 +    struct MeasurementResult : public ListNode<MeasurementResult>, public NewOverrideBase
  40.293 +    {
  40.294 +        MeasurementResult()
  40.295 +         :  DeviceMeasuredElapsedMilliS(0),
  40.296 +            TimedOutWaitingForTestStarted(false),
  40.297 +            TimedOutWaitingForColorDetected(false),
  40.298 +            StartTestTicksMicroS(0),
  40.299 +            TestStartedTicksMicroS(0)
  40.300 +        {}
  40.301 +
  40.302 +        Color                   TargetColor;
  40.303 +
  40.304 +        UInt32                  DeviceMeasuredElapsedMilliS;
  40.305 +
  40.306 +        bool                    TimedOutWaitingForTestStarted;
  40.307 +        bool                    TimedOutWaitingForColorDetected;
  40.308 +
  40.309 +        UInt64                  StartTestTicksMicroS;
  40.310 +        UInt64                  TestStartedTicksMicroS;
  40.311 +    };
  40.312 +
  40.313 +    List<MeasurementResult>     Results;
  40.314 +    void clearMeasurementResults();
  40.315 +
  40.316 +    MeasurementResult*          getActiveResult();
  40.317 +
  40.318 +    StringBuffer			    ResultsString;
  40.319 +	String					    ReturnedResultString;
  40.320 +};
  40.321 +
  40.322 +}} // namespace OVR::Util
  40.323 +
  40.324 +#endif // OVR_Util_LatencyTest_h
    41.1 --- a/libovr/Src/Util/Util_MagCalibration.cpp	Sat Sep 14 17:51:03 2013 +0300
    41.2 +++ b/libovr/Src/Util/Util_MagCalibration.cpp	Sun Sep 15 04:10:05 2013 +0300
    41.3 @@ -1,1 +1,227 @@
    41.4 -/************************************************************************************
    41.5 
    41.6 Filename    :   Util_MagCalibration.cpp
    41.7 Content     :   Procedures for calibrating the magnetometer
    41.8 Created     :   April 16, 2013
    41.9 Authors     :   Steve LaValle, Andrew Reisse
   41.10 
   41.11 Copyright   :   Copyright 2013 Oculus VR, Inc. All Rights reserved.
   41.12 
   41.13 Use of this software is subject to the terms of the Oculus license
   41.14 agreement provided at the time of installation or download, or which
   41.15 otherwise accompanies this software in either electronic or hard copy form.
   41.16 
   41.17 *************************************************************************************/
   41.18 
   41.19 #include "Util_MagCalibration.h"
   41.20 
   41.21 namespace OVR { namespace Util {
   41.22 
   41.23 void MagCalibration::BeginAutoCalibration(SensorFusion& sf)
   41.24 {
   41.25     Stat = Mag_AutoCalibrating;
   41.26     // This is a "hard" reset of the mag, so need to clear stored values
   41.27     sf.ClearMagCalibration();
   41.28     SampleCount = 0;
   41.29 
   41.30     // reset the statistics
   41.31     MinMagValues = Vector3f(10000.0f,10000.0f,10000.0f);
   41.32     MaxMagValues = Vector3f(-10000.0f,-10000.0f,-10000.0f);
   41.33 	MinQuatValues = Quatf(1.0f,1.0f,1.0f,1.0f);
   41.34 	MaxQuatValues = Quatf(0.0f,0.0f,0.0f,0.0f);
   41.35 }
   41.36 
   41.37 unsigned MagCalibration::UpdateAutoCalibration(SensorFusion& sf)
   41.38 {
   41.39     if (Stat != Mag_AutoCalibrating)
   41.40         return Stat;
   41.41 
   41.42     Quatf q = sf.GetOrientation();
   41.43     Vector3f m = sf.GetMagnetometer();
   41.44 
   41.45     InsertIfAcceptable(q, m);
   41.46 
   41.47     if ((SampleCount == 4) && (Stat == Mag_AutoCalibrating))
   41.48 	{
   41.49 		//LogText("Magnetometer Output Spread: %f %f %f\n",MagSpread.x,MagSpread.y,MagSpread.z);
   41.50 		//LogText("Quaternion Spread: %f %f %f %f\n",QuatSpread.x,QuatSpread.y,QuatSpread.z,QuatSpread.w);
   41.51         SetCalibration(sf);
   41.52 	}
   41.53 
   41.54     return Stat;
   41.55 
   41.56 }
   41.57 
   41.58 void MagCalibration::BeginManualCalibration(SensorFusion& sf)
   41.59 {
   41.60     Stat = Mag_ManuallyCalibrating;
   41.61     sf.ClearMagCalibration();
   41.62     SampleCount = 0;
   41.63 }
   41.64 
   41.65 bool MagCalibration::IsAcceptableSample(const Quatf& q, const Vector3f& m)
   41.66 {
   41.67     switch (SampleCount)
   41.68     {
   41.69         // Initial sample is always acceptable
   41.70     case 0:
   41.71         return true;
   41.72         break;
   41.73     case 1:
   41.74         return (q.DistanceSq(QuatSamples[0]) > MinQuatDistanceSq)&&
   41.75                ((m - MagSamples[0]).LengthSq() > MinMagDistanceSq);
   41.76         break;
   41.77     case 2:
   41.78         return (q.DistanceSq(QuatSamples[0]) > MinQuatDistanceSq)&&
   41.79                (q.DistanceSq(QuatSamples[1]) > MinQuatDistanceSq)&&
   41.80                ((m - MagSamples[0]).LengthSq() > MinMagDistanceSq)&&
   41.81                ((m - MagSamples[1]).LengthSq() > MinMagDistanceSq);
   41.82         break;
   41.83     case 3:
   41.84         return (q.DistanceSq(QuatSamples[0]) > MinQuatDistanceSq)&&
   41.85                (q.DistanceSq(QuatSamples[1]) > MinQuatDistanceSq)&&
   41.86                (q.DistanceSq(QuatSamples[2]) > MinQuatDistanceSq)&&
   41.87                ((PointToPlaneDistance(MagSamples[0],MagSamples[1],MagSamples[2],m) > MinMagDistance)||
   41.88                 (PointToPlaneDistance(MagSamples[1],MagSamples[2],m,MagSamples[0]) > MinMagDistance)||
   41.89                 (PointToPlaneDistance(MagSamples[2],m,MagSamples[0],MagSamples[1]) > MinMagDistance)||
   41.90                 (PointToPlaneDistance(m,MagSamples[0],MagSamples[1],MagSamples[2]) > MinMagDistance));
   41.91     }
   41.92 
   41.93     return false;
   41.94 }
   41.95 
   41.96 
   41.97 bool MagCalibration::InsertIfAcceptable(const Quatf& q, const Vector3f& m)
   41.98 {
   41.99 	// Update some statistics
  41.100 	if (m.x < MinMagValues.x)
  41.101 		MinMagValues.x = m.x;
  41.102 	if (m.y < MinMagValues.y)
  41.103 		MinMagValues.y = m.y;
  41.104 	if (m.z < MinMagValues.z)
  41.105 		MinMagValues.z = m.z;
  41.106 	if (m.x > MaxMagValues.x)
  41.107 		MaxMagValues.x = m.x;
  41.108 	if (m.y > MaxMagValues.y)
  41.109 		MaxMagValues.y = m.y;
  41.110 	if (m.z > MaxMagValues.z)
  41.111 		MaxMagValues.z = m.z;
  41.112 	if (q.x < MinQuatValues.x)
  41.113 		MinQuatValues.x = q.x;
  41.114 	if (q.y < MinQuatValues.y)
  41.115 		MinQuatValues.y = q.y;
  41.116 	if (q.z < MinQuatValues.z)
  41.117 		MinQuatValues.z = q.z;
  41.118 	if (q.w < MinQuatValues.w)
  41.119 		MinQuatValues.w = q.w;
  41.120 	if (q.x > MaxQuatValues.x)
  41.121 		MaxQuatValues.x = q.x;
  41.122 	if (q.y > MaxQuatValues.y)
  41.123 		MaxQuatValues.y = q.y;
  41.124 	if (q.z > MaxQuatValues.z)
  41.125 		MaxQuatValues.z = q.z;
  41.126 	if (q.w > MaxQuatValues.w)
  41.127 		MaxQuatValues.w = q.w;
  41.128 	MagSpread = MaxMagValues - MinMagValues;
  41.129 	QuatSpread = MaxQuatValues - MinQuatValues;
  41.130 
  41.131 	if (IsAcceptableSample(q, m))
  41.132     {
  41.133         MagSamples[SampleCount] = m;
  41.134         QuatSamples[SampleCount] = q;
  41.135         SampleCount++;
  41.136         return true;
  41.137     }
  41.138 
  41.139     return false;
  41.140 }
  41.141 
  41.142 Matrix4f MagCalibration::GetMagCalibration() const
  41.143 {
  41.144     Matrix4f calMat = Matrix4f();
  41.145     calMat.M[0][3] = -MagCenter.x;
  41.146     calMat.M[1][3] = -MagCenter.y;
  41.147     calMat.M[2][3] = -MagCenter.z;
  41.148     return calMat;
  41.149 }
  41.150 
  41.151 bool MagCalibration::SetCalibration(SensorFusion& sf)
  41.152 {
  41.153     if (SampleCount < 4)
  41.154         return false;
  41.155 
  41.156     MagCenter = CalculateSphereCenter(MagSamples[0],MagSamples[1],MagSamples[2],MagSamples[3]);
  41.157     Matrix4f calMat = GetMagCalibration();
  41.158     sf.SetMagCalibration(calMat);
  41.159     Stat = Mag_Calibrated;
  41.160     //LogText("MagCenter: %f %f %f\n",MagCenter.x,MagCenter.y,MagCenter.z);
  41.161 
  41.162     return true;
  41.163 }
  41.164 
  41.165 
  41.166 // Calculate the center of a sphere that passes through p1, p2, p3, p4
  41.167 Vector3f MagCalibration::CalculateSphereCenter(const Vector3f& p1, const Vector3f& p2,
  41.168                                                const Vector3f& p3, const Vector3f& p4) 
  41.169 {
  41.170     Matrix4f A;
  41.171     int i;
  41.172     Vector3f p[4];
  41.173     p[0] = p1;
  41.174     p[1] = p2;
  41.175     p[2] = p3;
  41.176     p[3] = p4;
  41.177 
  41.178     for (i = 0; i < 4; i++) 
  41.179     {
  41.180         A.M[i][0] = p[i].x;
  41.181         A.M[i][1] = p[i].y;
  41.182         A.M[i][2] = p[i].z;
  41.183         A.M[i][3] = 1.0f;
  41.184     }
  41.185     float m11 = A.Determinant();
  41.186     OVR_ASSERT(m11 != 0.0f);
  41.187 
  41.188     for (i = 0; i < 4; i++) 
  41.189     {
  41.190         A.M[i][0] = p[i].x*p[i].x + p[i].y*p[i].y + p[i].z*p[i].z;
  41.191         A.M[i][1] = p[i].y;
  41.192         A.M[i][2] = p[i].z;
  41.193         A.M[i][3] = 1.0f;
  41.194     }
  41.195     float m12 = A.Determinant();
  41.196 
  41.197     for (i = 0; i < 4; i++) 
  41.198     {
  41.199         A.M[i][0] = p[i].x*p[i].x + p[i].y*p[i].y + p[i].z*p[i].z;
  41.200         A.M[i][1] = p[i].x;
  41.201         A.M[i][2] = p[i].z;
  41.202         A.M[i][3] = 1.0f;
  41.203     }
  41.204     float m13 = A.Determinant();
  41.205 
  41.206     for (i = 0; i < 4; i++) 
  41.207     {
  41.208         A.M[i][0] = p[i].x*p[i].x + p[i].y*p[i].y + p[i].z*p[i].z;
  41.209         A.M[i][1] = p[i].x;
  41.210         A.M[i][2] = p[i].y;
  41.211         A.M[i][3] = 1.0f;
  41.212     }
  41.213     float m14 = A.Determinant();
  41.214 
  41.215     float c = 0.5f / m11;
  41.216     return Vector3f(c*m12, -c*m13, c*m14);
  41.217 }
  41.218 
  41.219 // Distance from p4 to the nearest point on a plane through p1, p2, p3
  41.220 float MagCalibration::PointToPlaneDistance(const Vector3f& p1, const Vector3f& p2,
  41.221                                            const Vector3f& p3, const Vector3f& p4) 
  41.222 {
  41.223     Vector3f v1 = p1 - p2;
  41.224     Vector3f v2 = p1 - p3;
  41.225     Vector3f planeNormal = v1.Cross(v2);
  41.226     planeNormal.Normalize();
  41.227     return (fabs((planeNormal * p4) - planeNormal * p1));
  41.228 }
  41.229 
  41.230 }}
  41.231 \ No newline at end of file
  41.232 +/************************************************************************************
  41.233 +
  41.234 +Filename    :   Util_MagCalibration.cpp
  41.235 +Content     :   Procedures for calibrating the magnetometer
  41.236 +Created     :   April 16, 2013
  41.237 +Authors     :   Steve LaValle, Andrew Reisse
  41.238 +
  41.239 +Copyright   :   Copyright 2013 Oculus VR, Inc. All Rights reserved.
  41.240 +
  41.241 +Use of this software is subject to the terms of the Oculus license
  41.242 +agreement provided at the time of installation or download, or which
  41.243 +otherwise accompanies this software in either electronic or hard copy form.
  41.244 +
  41.245 +*************************************************************************************/
  41.246 +
  41.247 +#include "Util_MagCalibration.h"
  41.248 +
  41.249 +namespace OVR { namespace Util {
  41.250 +
  41.251 +void MagCalibration::BeginAutoCalibration(SensorFusion& sf)
  41.252 +{
  41.253 +    Stat = Mag_AutoCalibrating;
  41.254 +    // This is a "hard" reset of the mag, so need to clear stored values
  41.255 +    sf.ClearMagCalibration();
  41.256 +    SampleCount = 0;
  41.257 +
  41.258 +    // reset the statistics
  41.259 +    MinMagValues = Vector3f(10000.0f,10000.0f,10000.0f);
  41.260 +    MaxMagValues = Vector3f(-10000.0f,-10000.0f,-10000.0f);
  41.261 +	MinQuatValues = Quatf(1.0f,1.0f,1.0f,1.0f);
  41.262 +	MaxQuatValues = Quatf(0.0f,0.0f,0.0f,0.0f);
  41.263 +}
  41.264 +
  41.265 +unsigned MagCalibration::UpdateAutoCalibration(SensorFusion& sf)
  41.266 +{
  41.267 +    if (Stat != Mag_AutoCalibrating)
  41.268 +        return Stat;
  41.269 +
  41.270 +    Quatf q = sf.GetOrientation();
  41.271 +    Vector3f m = sf.GetMagnetometer();
  41.272 +
  41.273 +    InsertIfAcceptable(q, m);
  41.274 +
  41.275 +    if ((SampleCount == 4) && (Stat == Mag_AutoCalibrating))
  41.276 +	{
  41.277 +		//LogText("Magnetometer Output Spread: %f %f %f\n",MagSpread.x,MagSpread.y,MagSpread.z);
  41.278 +		//LogText("Quaternion Spread: %f %f %f %f\n",QuatSpread.x,QuatSpread.y,QuatSpread.z,QuatSpread.w);
  41.279 +        SetCalibration(sf);
  41.280 +	}
  41.281 +
  41.282 +    return Stat;
  41.283 +
  41.284 +}
  41.285 +
  41.286 +void MagCalibration::BeginManualCalibration(SensorFusion& sf)
  41.287 +{
  41.288 +    Stat = Mag_ManuallyCalibrating;
  41.289 +    sf.ClearMagCalibration();
  41.290 +    SampleCount = 0;
  41.291 +}
  41.292 +
  41.293 +bool MagCalibration::IsAcceptableSample(const Quatf& q, const Vector3f& m)
  41.294 +{
  41.295 +    switch (SampleCount)
  41.296 +    {
  41.297 +        // Initial sample is always acceptable
  41.298 +    case 0:
  41.299 +        return true;
  41.300 +        break;
  41.301 +    case 1:
  41.302 +        return (q.DistanceSq(QuatSamples[0]) > MinQuatDistanceSq)&&
  41.303 +               ((m - MagSamples[0]).LengthSq() > MinMagDistanceSq);
  41.304 +        break;
  41.305 +    case 2:
  41.306 +        return (q.DistanceSq(QuatSamples[0]) > MinQuatDistanceSq)&&
  41.307 +               (q.DistanceSq(QuatSamples[1]) > MinQuatDistanceSq)&&
  41.308 +               ((m - MagSamples[0]).LengthSq() > MinMagDistanceSq)&&
  41.309 +               ((m - MagSamples[1]).LengthSq() > MinMagDistanceSq);
  41.310 +        break;
  41.311 +    case 3:
  41.312 +        return (q.DistanceSq(QuatSamples[0]) > MinQuatDistanceSq)&&
  41.313 +               (q.DistanceSq(QuatSamples[1]) > MinQuatDistanceSq)&&
  41.314 +               (q.DistanceSq(QuatSamples[2]) > MinQuatDistanceSq)&&
  41.315 +               ((PointToPlaneDistance(MagSamples[0],MagSamples[1],MagSamples[2],m) > MinMagDistance)||
  41.316 +                (PointToPlaneDistance(MagSamples[1],MagSamples[2],m,MagSamples[0]) > MinMagDistance)||
  41.317 +                (PointToPlaneDistance(MagSamples[2],m,MagSamples[0],MagSamples[1]) > MinMagDistance)||
  41.318 +                (PointToPlaneDistance(m,MagSamples[0],MagSamples[1],MagSamples[2]) > MinMagDistance));
  41.319 +    }
  41.320 +
  41.321 +    return false;
  41.322 +}
  41.323 +
  41.324 +
  41.325 +bool MagCalibration::InsertIfAcceptable(const Quatf& q, const Vector3f& m)
  41.326 +{
  41.327 +	// Update some statistics
  41.328 +	if (m.x < MinMagValues.x)
  41.329 +		MinMagValues.x = m.x;
  41.330 +	if (m.y < MinMagValues.y)
  41.331 +		MinMagValues.y = m.y;
  41.332 +	if (m.z < MinMagValues.z)
  41.333 +		MinMagValues.z = m.z;
  41.334 +	if (m.x > MaxMagValues.x)
  41.335 +		MaxMagValues.x = m.x;
  41.336 +	if (m.y > MaxMagValues.y)
  41.337 +		MaxMagValues.y = m.y;
  41.338 +	if (m.z > MaxMagValues.z)
  41.339 +		MaxMagValues.z = m.z;
  41.340 +	if (q.x < MinQuatValues.x)
  41.341 +		MinQuatValues.x = q.x;
  41.342 +	if (q.y < MinQuatValues.y)
  41.343 +		MinQuatValues.y = q.y;
  41.344 +	if (q.z < MinQuatValues.z)
  41.345 +		MinQuatValues.z = q.z;
  41.346 +	if (q.w < MinQuatValues.w)
  41.347 +		MinQuatValues.w = q.w;
  41.348 +	if (q.x > MaxQuatValues.x)
  41.349 +		MaxQuatValues.x = q.x;
  41.350 +	if (q.y > MaxQuatValues.y)
  41.351 +		MaxQuatValues.y = q.y;
  41.352 +	if (q.z > MaxQuatValues.z)
  41.353 +		MaxQuatValues.z = q.z;
  41.354 +	if (q.w > MaxQuatValues.w)
  41.355 +		MaxQuatValues.w = q.w;
  41.356 +	MagSpread = MaxMagValues - MinMagValues;
  41.357 +	QuatSpread = MaxQuatValues - MinQuatValues;
  41.358 +
  41.359 +	if (IsAcceptableSample(q, m))
  41.360 +    {
  41.361 +        MagSamples[SampleCount] = m;
  41.362 +        QuatSamples[SampleCount] = q;
  41.363 +        SampleCount++;
  41.364 +        return true;
  41.365 +    }
  41.366 +
  41.367 +    return false;
  41.368 +}
  41.369 +
  41.370 +Matrix4f MagCalibration::GetMagCalibration() const
  41.371 +{
  41.372 +    Matrix4f calMat = Matrix4f();
  41.373 +    calMat.M[0][3] = -MagCenter.x;
  41.374 +    calMat.M[1][3] = -MagCenter.y;
  41.375 +    calMat.M[2][3] = -MagCenter.z;
  41.376 +    return calMat;
  41.377 +}
  41.378 +
  41.379 +bool MagCalibration::SetCalibration(SensorFusion& sf)
  41.380 +{
  41.381 +    if (SampleCount < 4)
  41.382 +        return false;
  41.383 +
  41.384 +    MagCenter = CalculateSphereCenter(MagSamples[0],MagSamples[1],MagSamples[2],MagSamples[3]);
  41.385 +    Matrix4f calMat = GetMagCalibration();
  41.386 +    sf.SetMagCalibration(calMat);
  41.387 +    Stat = Mag_Calibrated;
  41.388 +    //LogText("MagCenter: %f %f %f\n",MagCenter.x,MagCenter.y,MagCenter.z);
  41.389 +
  41.390 +    return true;
  41.391 +}
  41.392 +
  41.393 +
  41.394 +// Calculate the center of a sphere that passes through p1, p2, p3, p4
  41.395 +Vector3f MagCalibration::CalculateSphereCenter(const Vector3f& p1, const Vector3f& p2,
  41.396 +                                               const Vector3f& p3, const Vector3f& p4) 
  41.397 +{
  41.398 +    Matrix4f A;
  41.399 +    int i;
  41.400 +    Vector3f p[4];
  41.401 +    p[0] = p1;
  41.402 +    p[1] = p2;
  41.403 +    p[2] = p3;
  41.404 +    p[3] = p4;
  41.405 +
  41.406 +    for (i = 0; i < 4; i++) 
  41.407 +    {
  41.408 +        A.M[i][0] = p[i].x;
  41.409 +        A.M[i][1] = p[i].y;
  41.410 +        A.M[i][2] = p[i].z;
  41.411 +        A.M[i][3] = 1.0f;
  41.412 +    }
  41.413 +    float m11 = A.Determinant();
  41.414 +    OVR_ASSERT(m11 != 0.0f);
  41.415 +
  41.416 +    for (i = 0; i < 4; i++) 
  41.417 +    {
  41.418 +        A.M[i][0] = p[i].x*p[i].x + p[i].y*p[i].y + p[i].z*p[i].z;
  41.419 +        A.M[i][1] = p[i].y;
  41.420 +        A.M[i][2] = p[i].z;
  41.421 +        A.M[i][3] = 1.0f;
  41.422 +    }
  41.423 +    float m12 = A.Determinant();
  41.424 +
  41.425 +    for (i = 0; i < 4; i++) 
  41.426 +    {
  41.427 +        A.M[i][0] = p[i].x*p[i].x + p[i].y*p[i].y + p[i].z*p[i].z;
  41.428 +        A.M[i][1] = p[i].x;
  41.429 +        A.M[i][2] = p[i].z;
  41.430 +        A.M[i][3] = 1.0f;
  41.431 +    }
  41.432 +    float m13 = A.Determinant();
  41.433 +
  41.434 +    for (i = 0; i < 4; i++) 
  41.435 +    {
  41.436 +        A.M[i][0] = p[i].x*p[i].x + p[i].y*p[i].y + p[i].z*p[i].z;
  41.437 +        A.M[i][1] = p[i].x;
  41.438 +        A.M[i][2] = p[i].y;
  41.439 +        A.M[i][3] = 1.0f;
  41.440 +    }
  41.441 +    float m14 = A.Determinant();
  41.442 +
  41.443 +    float c = 0.5f / m11;
  41.444 +    return Vector3f(c*m12, -c*m13, c*m14);
  41.445 +}
  41.446 +
  41.447 +// Distance from p4 to the nearest point on a plane through p1, p2, p3
  41.448 +float MagCalibration::PointToPlaneDistance(const Vector3f& p1, const Vector3f& p2,
  41.449 +                                           const Vector3f& p3, const Vector3f& p4) 
  41.450 +{
  41.451 +    Vector3f v1 = p1 - p2;
  41.452 +    Vector3f v2 = p1 - p3;
  41.453 +    Vector3f planeNormal = v1.Cross(v2);
  41.454 +    planeNormal.Normalize();
  41.455 +    return (fabs((planeNormal * p4) - planeNormal * p1));
  41.456 +}
  41.457 +
  41.458 +}}
    42.1 --- a/libovr/Src/Util/Util_MagCalibration.h	Sat Sep 14 17:51:03 2013 +0300
    42.2 +++ b/libovr/Src/Util/Util_MagCalibration.h	Sun Sep 15 04:10:05 2013 +0300
    42.3 @@ -1,1 +1,138 @@
    42.4 -/************************************************************************************
    42.5 
    42.6 PublicHeader:   OVR.h
    42.7 Filename    :   Util_MagCalibration.h
    42.8 Content     :   Procedures for calibrating the magnetometer
    42.9 Created     :   April 16, 2013
   42.10 Authors     :   Steve LaValle, Andrew Reisse
   42.11 
   42.12 Copyright   :   Copyright 2013 Oculus VR, Inc. All Rights reserved.
   42.13 
   42.14 Use of this software is subject to the terms of the Oculus license
   42.15 agreement provided at the time of installation or download, or which
   42.16 otherwise accompanies this software in either electronic or hard copy form.
   42.17 
   42.18 *************************************************************************************/
   42.19 
   42.20 #ifndef OVR_Util_MagCalibration_h
   42.21 #define OVR_Util_MagCalibration_h
   42.22 
   42.23 #include "../OVR_SensorFusion.h"
   42.24 #include "../Kernel/OVR_String.h"
   42.25 #include "../Kernel/OVR_Log.h"
   42.26 
   42.27 namespace OVR { namespace Util {
   42.28 
   42.29 class MagCalibration
   42.30 {
   42.31 public:
   42.32     enum MagStatus
   42.33     {
   42.34         Mag_Uninitialized = 0,
   42.35         Mag_AutoCalibrating = 1,
   42.36         Mag_ManuallyCalibrating = 2,
   42.37         Mag_Calibrated  = 3
   42.38     };
   42.39 
   42.40     MagCalibration() :
   42.41         Stat(Mag_Uninitialized),
   42.42         MinMagDistance(0.2f), MinQuatDistance(0.5f),
   42.43         SampleCount(0)
   42.44     {
   42.45         MinMagDistanceSq = MinMagDistance * MinMagDistance;
   42.46         MinQuatDistanceSq = MinQuatDistance * MinQuatDistance;
   42.47         MinMagValues = Vector3f(10000.0f,10000.0f,10000.0f);
   42.48         MaxMagValues = Vector3f(-10000.0f,-10000.0f,-10000.0f);
   42.49 		MinQuatValues = Quatf(1.0f,1.0f,1.0f,1.0f);
   42.50 		MaxQuatValues = Quatf(0.0f,0.0f,0.0f,0.0f);
   42.51 		}
   42.52 
   42.53     // Methods that are useful for either auto or manual calibration
   42.54     bool     IsUnitialized() const       { return Stat == Mag_Uninitialized; }
   42.55     bool     IsCalibrated() const        { return Stat == Mag_Calibrated; }
   42.56     int      NumberOfSamples() const     { return SampleCount; }
   42.57     int      RequiredSampleCount() const { return 4; }
   42.58 	void     AbortCalibration()
   42.59 	{
   42.60         Stat = Mag_Uninitialized;
   42.61         SampleCount = 0;
   42.62 	}
   42.63 
   42.64     void     ClearCalibration(SensorFusion& sf) 
   42.65     {
   42.66         Stat = Mag_Uninitialized;
   42.67         SampleCount = 0;
   42.68         sf.ClearMagCalibration();
   42.69 	};
   42.70   
   42.71     // Methods for automatic magnetometer calibration
   42.72     void     BeginAutoCalibration(SensorFusion& sf);
   42.73     unsigned UpdateAutoCalibration(SensorFusion& sf);
   42.74     bool     IsAutoCalibrating() const { return Stat == Mag_AutoCalibrating; }
   42.75 
   42.76     // Methods for building a manual (user-guided) calibraton procedure
   42.77     void     BeginManualCalibration(SensorFusion& sf);
   42.78     bool     IsAcceptableSample(const Quatf& q, const Vector3f& m);
   42.79     bool     InsertIfAcceptable(const Quatf& q, const Vector3f& m);
   42.80     // Returns true if successful, requiring that SampleCount = 4
   42.81     bool     SetCalibration(SensorFusion& sf);
   42.82     bool     IsManuallyCalibrating() const { return Stat == Mag_ManuallyCalibrating; }
   42.83 
   42.84     // This is the minimum acceptable distance (Euclidean) between raw
   42.85     // magnetometer values to be acceptable for usage in calibration.
   42.86     void SetMinMagDistance(float dist) 
   42.87     { 
   42.88         MinMagDistance = dist; 
   42.89         MinMagDistanceSq = MinMagDistance * MinMagDistance;
   42.90     }
   42.91 
   42.92     // The minimum acceptable distance (4D Euclidean) between orientations
   42.93     // to be acceptable for calibration usage.
   42.94     void SetMinQuatDistance(float dist) 
   42.95     { 
   42.96         MinQuatDistance = dist; 
   42.97         MinQuatDistanceSq = MinQuatDistance * MinQuatDistance;
   42.98     }
   42.99 
  42.100     // A result of the calibration, which is the center of a sphere that 
  42.101     // roughly approximates the magnetometer data.
  42.102     Vector3f GetMagCenter() const { return MagCenter; }
  42.103     // Retrieves the full magnetometer calibration matrix
  42.104     Matrix4f GetMagCalibration() const;
  42.105     // Retrieves the range of each quaternion term during calibration
  42.106     Quatf GetCalibrationQuatSpread() const { return QuatSpread; }
  42.107     // Retrieves the range of each magnetometer term during calibration
  42.108     Vector3f GetCalibrationMagSpread() const { return MagSpread; }
  42.109 
  42.110 private:
  42.111     // Determine the unique sphere through 4 non-coplanar points
  42.112     Vector3f CalculateSphereCenter(const Vector3f& p1, const Vector3f& p2,
  42.113                                    const Vector3f& p3, const Vector3f& p4);
  42.114 
  42.115     // Distance from p4 to the nearest point on a plane through p1, p2, p3
  42.116     float PointToPlaneDistance(const Vector3f& p1, const Vector3f& p2,
  42.117                                const Vector3f& p3, const Vector3f& p4);
  42.118 
  42.119     Vector3f MagCenter;
  42.120     unsigned Stat;
  42.121     float    MinMagDistance;
  42.122     float    MinQuatDistance;
  42.123     float    MinMagDistanceSq;
  42.124     float    MinQuatDistanceSq;
  42.125 	// For gathering statistics during calibration
  42.126 	Vector3f    MinMagValues;
  42.127 	Vector3f    MaxMagValues;
  42.128 	Vector3f    MagSpread;
  42.129 	Quatf		MinQuatValues;
  42.130 	Quatf		MaxQuatValues;
  42.131 	Quatf       QuatSpread;
  42.132 
  42.133     unsigned SampleCount;
  42.134     Vector3f MagSamples[4];
  42.135     Quatf    QuatSamples[4];
  42.136 
  42.137 };
  42.138 
  42.139 }}
  42.140 
  42.141 #endif
  42.142 \ No newline at end of file
  42.143 +/************************************************************************************
  42.144 +
  42.145 +PublicHeader:   OVR.h
  42.146 +Filename    :   Util_MagCalibration.h
  42.147 +Content     :   Procedures for calibrating the magnetometer
  42.148 +Created     :   April 16, 2013
  42.149 +Authors     :   Steve LaValle, Andrew Reisse
  42.150 +
  42.151 +Copyright   :   Copyright 2013 Oculus VR, Inc. All Rights reserved.
  42.152 +
  42.153 +Use of this software is subject to the terms of the Oculus license
  42.154 +agreement provided at the time of installation or download, or which
  42.155 +otherwise accompanies this software in either electronic or hard copy form.
  42.156 +
  42.157 +*************************************************************************************/
  42.158 +
  42.159 +#ifndef OVR_Util_MagCalibration_h
  42.160 +#define OVR_Util_MagCalibration_h
  42.161 +
  42.162 +#include "../OVR_SensorFusion.h"
  42.163 +#include "../Kernel/OVR_String.h"
  42.164 +#include "../Kernel/OVR_Log.h"
  42.165 +
  42.166 +namespace OVR { namespace Util {
  42.167 +
  42.168 +class MagCalibration
  42.169 +{
  42.170 +public:
  42.171 +    enum MagStatus
  42.172 +    {
  42.173 +        Mag_Uninitialized = 0,
  42.174 +        Mag_AutoCalibrating = 1,
  42.175 +        Mag_ManuallyCalibrating = 2,
  42.176 +        Mag_Calibrated  = 3
  42.177 +    };
  42.178 +
  42.179 +    MagCalibration() :
  42.180 +        Stat(Mag_Uninitialized),
  42.181 +        MinMagDistance(0.2f), MinQuatDistance(0.5f),
  42.182 +        SampleCount(0)
  42.183 +    {
  42.184 +        MinMagDistanceSq = MinMagDistance * MinMagDistance;
  42.185 +        MinQuatDistanceSq = MinQuatDistance * MinQuatDistance;
  42.186 +        MinMagValues = Vector3f(10000.0f,10000.0f,10000.0f);
  42.187 +        MaxMagValues = Vector3f(-10000.0f,-10000.0f,-10000.0f);
  42.188 +		MinQuatValues = Quatf(1.0f,1.0f,1.0f,1.0f);
  42.189 +		MaxQuatValues = Quatf(0.0f,0.0f,0.0f,0.0f);
  42.190 +		}
  42.191 +
  42.192 +    // Methods that are useful for either auto or manual calibration
  42.193 +    bool     IsUnitialized() const       { return Stat == Mag_Uninitialized; }
  42.194 +    bool     IsCalibrated() const        { return Stat == Mag_Calibrated; }
  42.195 +    int      NumberOfSamples() const     { return SampleCount; }
  42.196 +    int      RequiredSampleCount() const { return 4; }
  42.197 +	void     AbortCalibration()
  42.198 +	{
  42.199 +        Stat = Mag_Uninitialized;
  42.200 +        SampleCount = 0;
  42.201 +	}
  42.202 +
  42.203 +    void     ClearCalibration(SensorFusion& sf) 
  42.204 +    {
  42.205 +        Stat = Mag_Uninitialized;
  42.206 +        SampleCount = 0;
  42.207 +        sf.ClearMagCalibration();
  42.208 +	};
  42.209 +  
  42.210 +    // Methods for automatic magnetometer calibration
  42.211 +    void     BeginAutoCalibration(SensorFusion& sf);
  42.212 +    unsigned UpdateAutoCalibration(SensorFusion& sf);
  42.213 +    bool     IsAutoCalibrating() const { return Stat == Mag_AutoCalibrating; }
  42.214 +
  42.215 +    // Methods for building a manual (user-guided) calibraton procedure
  42.216 +    void     BeginManualCalibration(SensorFusion& sf);
  42.217 +    bool     IsAcceptableSample(const Quatf& q, const Vector3f& m);
  42.218 +    bool     InsertIfAcceptable(const Quatf& q, const Vector3f& m);
  42.219 +    // Returns true if successful, requiring that SampleCount = 4
  42.220 +    bool     SetCalibration(SensorFusion& sf);
  42.221 +    bool     IsManuallyCalibrating() const { return Stat == Mag_ManuallyCalibrating; }
  42.222 +
  42.223 +    // This is the minimum acceptable distance (Euclidean) between raw
  42.224 +    // magnetometer values to be acceptable for usage in calibration.
  42.225 +    void SetMinMagDistance(float dist) 
  42.226 +    { 
  42.227 +        MinMagDistance = dist; 
  42.228 +        MinMagDistanceSq = MinMagDistance * MinMagDistance;
  42.229 +    }
  42.230 +
  42.231 +    // The minimum acceptable distance (4D Euclidean) between orientations
  42.232 +    // to be acceptable for calibration usage.
  42.233 +    void SetMinQuatDistance(float dist) 
  42.234 +    { 
  42.235 +        MinQuatDistance = dist; 
  42.236 +        MinQuatDistanceSq = MinQuatDistance * MinQuatDistance;
  42.237 +    }
  42.238 +
  42.239 +    // A result of the calibration, which is the center of a sphere that 
  42.240 +    // roughly approximates the magnetometer data.
  42.241 +    Vector3f GetMagCenter() const { return MagCenter; }
  42.242 +    // Retrieves the full magnetometer calibration matrix
  42.243 +    Matrix4f GetMagCalibration() const;
  42.244 +    // Retrieves the range of each quaternion term during calibration
  42.245 +    Quatf GetCalibrationQuatSpread() const { return QuatSpread; }
  42.246 +    // Retrieves the range of each magnetometer term during calibration
  42.247 +    Vector3f GetCalibrationMagSpread() const { return MagSpread; }
  42.248 +
  42.249 +private:
  42.250 +    // Determine the unique sphere through 4 non-coplanar points
  42.251 +    Vector3f CalculateSphereCenter(const Vector3f& p1, const Vector3f& p2,
  42.252 +                                   const Vector3f& p3, const Vector3f& p4);
  42.253 +
  42.254 +    // Distance from p4 to the nearest point on a plane through p1, p2, p3
  42.255 +    float PointToPlaneDistance(const Vector3f& p1, const Vector3f& p2,
  42.256 +                               const Vector3f& p3, const Vector3f& p4);
  42.257 +
  42.258 +    Vector3f MagCenter;
  42.259 +    unsigned Stat;
  42.260 +    float    MinMagDistance;
  42.261 +    float    MinQuatDistance;
  42.262 +    float    MinMagDistanceSq;
  42.263 +    float    MinQuatDistanceSq;
  42.264 +	// For gathering statistics during calibration
  42.265 +	Vector3f    MinMagValues;
  42.266 +	Vector3f    MaxMagValues;
  42.267 +	Vector3f    MagSpread;
  42.268 +	Quatf		MinQuatValues;
  42.269 +	Quatf		MaxQuatValues;
  42.270 +	Quatf       QuatSpread;
  42.271 +
  42.272 +    unsigned SampleCount;
  42.273 +    Vector3f MagSamples[4];
  42.274 +    Quatf    QuatSamples[4];
  42.275 +
  42.276 +};
  42.277 +
  42.278 +}}
  42.279 +
  42.280 +#endif
    43.1 --- a/libovr/Src/Util/Util_Render_Stereo.cpp	Sat Sep 14 17:51:03 2013 +0300
    43.2 +++ b/libovr/Src/Util/Util_Render_Stereo.cpp	Sun Sep 15 04:10:05 2013 +0300
    43.3 @@ -1,1 +1,314 @@
    43.4 -/************************************************************************************
    43.5 
    43.6 Filename    :   Util_Render_Stereo.cpp
    43.7 Content     :   Stereo rendering configuration implementation
    43.8 Created     :   October 22, 2012
    43.9 Authors     :   Michael Antonov, Andrew Reisse
   43.10 
   43.11 Copyright   :   Copyright 2012 Oculus, Inc. All Rights reserved.
   43.12 
   43.13 Use of this software is subject to the terms of the Oculus Inc license
   43.14 agreement provided at the time of installation or download, or which
   43.15 otherwise accompanies this software in either electronic or hard copy form.
   43.16 
   43.17 *************************************************************************************/
   43.18 
   43.19 #include "Util_Render_Stereo.h"
   43.20 
   43.21 namespace OVR { namespace Util { namespace Render {
   43.22 
   43.23 
   43.24 //-----------------------------------------------------------------------------------
   43.25 
   43.26 // DistortionFnInverse computes the inverse of the distortion function on an argument.
   43.27 float DistortionConfig::DistortionFnInverse(float r)
   43.28 {    
   43.29     OVR_ASSERT((r <= 10.0f));
   43.30 
   43.31     float s, d;
   43.32     float delta = r * 0.25f;
   43.33 
   43.34     s = r * 0.5f;
   43.35     d = fabs(r - DistortionFn(s));
   43.36 
   43.37     for (int i = 0; i < 20; i++)
   43.38     {
   43.39         float sUp   = s + delta;
   43.40         float sDown = s - delta;
   43.41         float dUp   = fabs(r - DistortionFn(sUp));
   43.42         float dDown = fabs(r - DistortionFn(sDown));
   43.43 
   43.44         if (dUp < d)
   43.45         {
   43.46             s = sUp;
   43.47             d = dUp;
   43.48         }
   43.49         else if (dDown < d)
   43.50         {
   43.51             s = sDown;
   43.52             d = dDown;
   43.53         }
   43.54         else
   43.55         {
   43.56             delta *= 0.5f;
   43.57         }
   43.58     }
   43.59 
   43.60     return s;
   43.61 }
   43.62 
   43.63 
   43.64 //-----------------------------------------------------------------------------------
   43.65 // **** StereoConfig Implementation
   43.66 
   43.67 StereoConfig::StereoConfig(StereoMode mode, const Viewport& vp)
   43.68     : Mode(mode),
   43.69       InterpupillaryDistance(0.064f), AspectMultiplier(1.0f),
   43.70       FullView(vp), DirtyFlag(true), IPDOverride(false),
   43.71       YFov(0), Aspect(vp.w / float(vp.h)), ProjectionCenterOffset(0),
   43.72       OrthoPixelOffset(0)
   43.73 {
   43.74     // And default distortion for it.
   43.75     Distortion.SetCoefficients(1.0f, 0.22f, 0.24f);
   43.76     Distortion.Scale = 1.0f; // Will be computed later.
   43.77 
   43.78     // Fit left of the image.
   43.79     DistortionFitX = -1.0f;
   43.80     DistortionFitY = 0.0f;
   43.81 
   43.82     // Initialize "fake" default HMD values for testing without HMD plugged in.
   43.83     // These default values match those returned by the HMD.
   43.84     HMD.HResolution            = 1280;
   43.85     HMD.VResolution            = 800;
   43.86     HMD.HScreenSize            = 0.14976f;
   43.87     HMD.VScreenSize            = HMD.HScreenSize / (1280.0f / 800.0f);
   43.88     HMD.InterpupillaryDistance = InterpupillaryDistance;
   43.89     HMD.LensSeparationDistance = 0.0635f;
   43.90     HMD.EyeToScreenDistance    = 0.041f;
   43.91     HMD.DistortionK[0]         = Distortion.K[0];
   43.92     HMD.DistortionK[1]         = Distortion.K[1];
   43.93     HMD.DistortionK[2]         = Distortion.K[2];
   43.94     HMD.DistortionK[3]         = 0;
   43.95 
   43.96     Set2DAreaFov(DegreeToRad(85.0f));
   43.97 }
   43.98 
   43.99 void StereoConfig::SetFullViewport(const Viewport& vp)
  43.100 {
  43.101     if (vp != FullView)
  43.102     { 
  43.103         FullView = vp;
  43.104         DirtyFlag = true;
  43.105     }
  43.106 }
  43.107 
  43.108 void StereoConfig::SetHMDInfo(const HMDInfo& hmd)
  43.109 {
  43.110     HMD = hmd;
  43.111     Distortion.K[0] = hmd.DistortionK[0];
  43.112     Distortion.K[1] = hmd.DistortionK[1];
  43.113     Distortion.K[2] = hmd.DistortionK[2];
  43.114     Distortion.K[3] = hmd.DistortionK[3];
  43.115 
  43.116     Distortion.SetChromaticAberration(hmd.ChromaAbCorrection[0], hmd.ChromaAbCorrection[1],
  43.117                                       hmd.ChromaAbCorrection[2], hmd.ChromaAbCorrection[3]);
  43.118 
  43.119     if (!IPDOverride)
  43.120         InterpupillaryDistance = HMD.InterpupillaryDistance;
  43.121 
  43.122     DirtyFlag = true;
  43.123 }
  43.124 
  43.125 void StereoConfig::SetDistortionFitPointVP(float x, float y)
  43.126 {
  43.127     DistortionFitX = x;
  43.128     DistortionFitY = y;
  43.129     DirtyFlag = true;
  43.130 }
  43.131 
  43.132 void StereoConfig::SetDistortionFitPointPixels(float x, float y)
  43.133 {
  43.134     DistortionFitX = (4 * x / float(FullView.w)) - 1.0f;
  43.135     DistortionFitY = (2 * y / float(FullView.h)) - 1.0f;
  43.136     DirtyFlag = true;
  43.137 }
  43.138 
  43.139 void StereoConfig::Set2DAreaFov(float fovRadians)
  43.140 {
  43.141     Area2DFov = fovRadians;
  43.142     DirtyFlag = true;
  43.143 }
  43.144 
  43.145 
  43.146 const StereoEyeParams& StereoConfig::GetEyeRenderParams(StereoEye eye)
  43.147 {
  43.148     static const UByte eyeParamIndices[3] = { 0, 0, 1 };
  43.149 
  43.150     updateIfDirty();
  43.151     OVR_ASSERT(eye < sizeof(eyeParamIndices));
  43.152     return EyeRenderParams[eyeParamIndices[eye]];
  43.153 }
  43.154 
  43.155 
  43.156 void StereoConfig::updateComputedState()
  43.157 {
  43.158     // Need to compute all of the following:
  43.159     //   - Aspect Ratio
  43.160     //   - FOV
  43.161     //   - Projection offsets for 3D
  43.162     //   - Distortion XCenterOffset
  43.163     //   - Update 2D
  43.164     //   - Initialize EyeRenderParams
  43.165 
  43.166     // Compute aspect ratio. Stereo mode cuts width in half.
  43.167     Aspect = float(FullView.w) / float(FullView.h);
  43.168     Aspect *= (Mode == Stereo_None) ? 1.0f : 0.5f;
  43.169     Aspect *= AspectMultiplier; 
  43.170 
  43.171     updateDistortionOffsetAndScale();
  43.172 
  43.173     // Compute Vertical FOV based on distance, distortion, etc.
  43.174     // Distance from vertical center to render vertical edge perceived through the lens.
  43.175     // This will be larger then normal screen size due to magnification & distortion.
  43.176     //
  43.177     // This percievedHalfRTDistance equation should hold as long as the render target
  43.178     // and display have the same aspect ratios. What we'd like to know is where the edge
  43.179     // of the render target will on the perceived screen surface. With NO LENS,
  43.180     // the answer would be:
  43.181     //
  43.182     //  halfRTDistance = (VScreenSize / 2) * aspect *
  43.183     //                   DistortionFn_Inverse( DistortionScale / aspect )
  43.184     //
  43.185     // To model the optical lens we eliminates DistortionFn_Inverse. Aspect ratios
  43.186     // cancel out, so we get:
  43.187     //
  43.188     //  halfRTDistance = (VScreenSize / 2) * DistortionScale
  43.189     //
  43.190     if (Mode == Stereo_None)
  43.191     {
  43.192         YFov = DegreeToRad(80.0f);
  43.193     }
  43.194     else
  43.195     {
  43.196         float percievedHalfRTDistance = (HMD.VScreenSize / 2) * Distortion.Scale;    
  43.197         YFov = 2.0f * atan(percievedHalfRTDistance/HMD.EyeToScreenDistance);
  43.198     }
  43.199     
  43.200     updateProjectionOffset();
  43.201     update2D();
  43.202     updateEyeParams();
  43.203 
  43.204     DirtyFlag = false;
  43.205 }
  43.206 
  43.207 void StereoConfig::updateDistortionOffsetAndScale()
  43.208 {
  43.209     // Distortion center shift is stored separately, since it isn't affected
  43.210     // by the eye distance.
  43.211     float lensOffset        = HMD.LensSeparationDistance * 0.5f;
  43.212     float lensShift         = HMD.HScreenSize * 0.25f - lensOffset;
  43.213     float lensViewportShift = 4.0f * lensShift / HMD.HScreenSize;
  43.214     Distortion.XCenterOffset= lensViewportShift;
  43.215 
  43.216     // Compute distortion scale from DistortionFitX & DistortionFitY.
  43.217     // Fit value of 0.0 means "no fit".
  43.218     if ((fabs(DistortionFitX) < 0.0001f) &&  (fabs(DistortionFitY) < 0.0001f))
  43.219     {
  43.220         Distortion.Scale = 1.0f;
  43.221     }
  43.222     else
  43.223     {
  43.224         // Convert fit value to distortion-centered coordinates before fit radius
  43.225         // calculation.
  43.226         float stereoAspect = 0.5f * float(FullView.w) / float(FullView.h);
  43.227         float dx           = DistortionFitX - Distortion.XCenterOffset;
  43.228         float dy           = DistortionFitY / stereoAspect;
  43.229         float fitRadius    = sqrt(dx * dx + dy * dy);
  43.230         Distortion.Scale   = Distortion.DistortionFn(fitRadius)/fitRadius;
  43.231     }
  43.232 }
  43.233 
  43.234 void StereoConfig::updateProjectionOffset()
  43.235 {
  43.236     // Post-projection viewport coordinates range from (-1.0, 1.0), with the
  43.237     // center of the left viewport falling at (1/4) of horizontal screen size.
  43.238     // We need to shift this projection center to match with the lens center;
  43.239     // note that we don't use the IPD here due to collimated light property of the lens.
  43.240     // We compute this shift in physical units (meters) to
  43.241     // correct for different screen sizes and then rescale to viewport coordinates.    
  43.242     float viewCenter         = HMD.HScreenSize * 0.25f;
  43.243     float eyeProjectionShift = viewCenter - HMD.LensSeparationDistance*0.5f;
  43.244     ProjectionCenterOffset   = 4.0f * eyeProjectionShift / HMD.HScreenSize;
  43.245 }
  43.246 
  43.247 void StereoConfig::update2D()
  43.248 {
  43.249     // Orthographic projection fakes a screen at a distance of 0.8m from the
  43.250     // eye, where hmd screen projection surface is at 0.05m distance.
  43.251     // This introduces an extra off-center pixel projection shift based on eye distance.
  43.252     // This offCenterShift is the pixel offset of the other camera's center
  43.253     // in your reference camera based on surface distance.    
  43.254     float metersToPixels          = (HMD.HResolution / HMD.HScreenSize);
  43.255     float lensDistanceScreenPixels= metersToPixels * HMD.LensSeparationDistance;
  43.256     float eyeDistanceScreenPixels = metersToPixels * InterpupillaryDistance;
  43.257     float offCenterShiftPixels    = (HMD.EyeToScreenDistance / 0.8f) * eyeDistanceScreenPixels;
  43.258     float leftPixelCenter         = (HMD.HResolution / 2) - lensDistanceScreenPixels * 0.5f;
  43.259     float rightPixelCenter        = lensDistanceScreenPixels * 0.5f;
  43.260     float pixelDifference         = leftPixelCenter - rightPixelCenter;
  43.261     
  43.262     // This computes the number of pixels that fit within specified 2D FOV (assuming
  43.263     // distortion scaling will be done).
  43.264     float percievedHalfScreenDistance = tan(Area2DFov * 0.5f) * HMD.EyeToScreenDistance;
  43.265     float vfovSize = 2.0f * percievedHalfScreenDistance / Distortion.Scale;
  43.266     FovPixels = HMD.VResolution * vfovSize / HMD.VScreenSize;
  43.267     
  43.268     // Create orthographic matrix.   
  43.269     Matrix4f& m      = OrthoCenter;
  43.270     m.SetIdentity();
  43.271     m.M[0][0] = FovPixels / (FullView.w * 0.5f);
  43.272     m.M[1][1] = -FovPixels / FullView.h;
  43.273     m.M[0][3] = 0;
  43.274     m.M[1][3] = 0;
  43.275     m.M[2][2] = 0;
  43.276 
  43.277     float orthoPixelOffset = (pixelDifference + offCenterShiftPixels/Distortion.Scale) * 0.5f;
  43.278     OrthoPixelOffset = orthoPixelOffset * 2.0f / FovPixels;
  43.279 }
  43.280 
  43.281 void StereoConfig::updateEyeParams()
  43.282 {
  43.283     // Projection matrix for the center eye, which the left/right matrices are based on.
  43.284     Matrix4f projCenter = Matrix4f::PerspectiveRH(YFov, Aspect, 0.01f, 2000.0f);
  43.285    
  43.286     switch(Mode)
  43.287     {
  43.288     case Stereo_None:
  43.289         {
  43.290             EyeRenderParams[0].Init(StereoEye_Center, FullView, 0, projCenter, OrthoCenter);
  43.291         }
  43.292         break;
  43.293 
  43.294     case Stereo_LeftRight_Multipass:
  43.295         {
  43.296             Matrix4f projLeft  = Matrix4f::Translation(ProjectionCenterOffset, 0, 0) * projCenter,
  43.297                      projRight = Matrix4f::Translation(-ProjectionCenterOffset, 0, 0) * projCenter;
  43.298 
  43.299             EyeRenderParams[0].Init(StereoEye_Left,
  43.300                 Viewport(FullView.x, FullView.y, FullView.w/2, FullView.h),
  43.301                          +InterpupillaryDistance * 0.5f,  // World view shift.                       
  43.302                          projLeft, OrthoCenter * Matrix4f::Translation(OrthoPixelOffset, 0, 0),
  43.303                          &Distortion);
  43.304             EyeRenderParams[1].Init(StereoEye_Right,
  43.305                 Viewport(FullView.x + FullView.w/2, FullView.y, FullView.w/2, FullView.h),
  43.306                          -InterpupillaryDistance * 0.5f,                         
  43.307                          projRight, OrthoCenter * Matrix4f::Translation(-OrthoPixelOffset, 0, 0),
  43.308                          &Distortion);
  43.309         }
  43.310         break;
  43.311     }
  43.312 
  43.313 }
  43.314 
  43.315 
  43.316 }}}  // OVR::Util::Render
  43.317 
  43.318 \ No newline at end of file
  43.319 +/************************************************************************************
  43.320 +
  43.321 +Filename    :   Util_Render_Stereo.cpp
  43.322 +Content     :   Stereo rendering configuration implementation
  43.323 +Created     :   October 22, 2012
  43.324 +Authors     :   Michael Antonov, Andrew Reisse
  43.325 +
  43.326 +Copyright   :   Copyright 2012 Oculus, Inc. All Rights reserved.
  43.327 +
  43.328 +Use of this software is subject to the terms of the Oculus Inc license
  43.329 +agreement provided at the time of installation or download, or which
  43.330 +otherwise accompanies this software in either electronic or hard copy form.
  43.331 +
  43.332 +*************************************************************************************/
  43.333 +
  43.334 +#include "Util_Render_Stereo.h"
  43.335 +
  43.336 +namespace OVR { namespace Util { namespace Render {
  43.337 +
  43.338 +
  43.339 +//-----------------------------------------------------------------------------------
  43.340 +
  43.341 +// DistortionFnInverse computes the inverse of the distortion function on an argument.
  43.342 +float DistortionConfig::DistortionFnInverse(float r)
  43.343 +{    
  43.344 +    OVR_ASSERT((r <= 10.0f));
  43.345 +
  43.346 +    float s, d;
  43.347 +    float delta = r * 0.25f;
  43.348 +
  43.349 +    s = r * 0.5f;
  43.350 +    d = fabs(r - DistortionFn(s));
  43.351 +
  43.352 +    for (int i = 0; i < 20; i++)
  43.353 +    {
  43.354 +        float sUp   = s + delta;
  43.355 +        float sDown = s - delta;
  43.356 +        float dUp   = fabs(r - DistortionFn(sUp));
  43.357 +        float dDown = fabs(r - DistortionFn(sDown));
  43.358 +
  43.359 +        if (dUp < d)
  43.360 +        {
  43.361 +            s = sUp;
  43.362 +            d = dUp;
  43.363 +        }
  43.364 +        else if (dDown < d)
  43.365 +        {
  43.366 +            s = sDown;
  43.367 +            d = dDown;
  43.368 +        }
  43.369 +        else
  43.370 +        {
  43.371 +            delta *= 0.5f;
  43.372 +        }
  43.373 +    }
  43.374 +
  43.375 +    return s;
  43.376 +}
  43.377 +
  43.378 +
  43.379 +//-----------------------------------------------------------------------------------
  43.380 +// **** StereoConfig Implementation
  43.381 +
  43.382 +StereoConfig::StereoConfig(StereoMode mode, const Viewport& vp)
  43.383 +    : Mode(mode),
  43.384 +      InterpupillaryDistance(0.064f), AspectMultiplier(1.0f),
  43.385 +      FullView(vp), DirtyFlag(true), IPDOverride(false),
  43.386 +      YFov(0), Aspect(vp.w / float(vp.h)), ProjectionCenterOffset(0),
  43.387 +      OrthoPixelOffset(0)
  43.388 +{
  43.389 +    // And default distortion for it.
  43.390 +    Distortion.SetCoefficients(1.0f, 0.22f, 0.24f);
  43.391 +    Distortion.Scale = 1.0f; // Will be computed later.
  43.392 +
  43.393 +    // Fit left of the image.
  43.394 +    DistortionFitX = -1.0f;
  43.395 +    DistortionFitY = 0.0f;
  43.396 +
  43.397 +    // Initialize "fake" default HMD values for testing without HMD plugged in.
  43.398 +    // These default values match those returned by the HMD.
  43.399 +    HMD.HResolution            = 1280;
  43.400 +    HMD.VResolution            = 800;
  43.401 +    HMD.HScreenSize            = 0.14976f;
  43.402 +    HMD.VScreenSize            = HMD.HScreenSize / (1280.0f / 800.0f);
  43.403 +    HMD.InterpupillaryDistance = InterpupillaryDistance;
  43.404 +    HMD.LensSeparationDistance = 0.0635f;
  43.405 +    HMD.EyeToScreenDistance    = 0.041f;
  43.406 +    HMD.DistortionK[0]         = Distortion.K[0];
  43.407 +    HMD.DistortionK[1]         = Distortion.K[1];
  43.408 +    HMD.DistortionK[2]         = Distortion.K[2];
  43.409 +    HMD.DistortionK[3]         = 0;
  43.410 +
  43.411 +    Set2DAreaFov(DegreeToRad(85.0f));
  43.412 +}
  43.413 +
  43.414 +void StereoConfig::SetFullViewport(const Viewport& vp)
  43.415 +{
  43.416 +    if (vp != FullView)
  43.417 +    { 
  43.418 +        FullView = vp;
  43.419 +        DirtyFlag = true;
  43.420 +    }
  43.421 +}
  43.422 +
  43.423 +void StereoConfig::SetHMDInfo(const HMDInfo& hmd)
  43.424 +{
  43.425 +    HMD = hmd;
  43.426 +    Distortion.K[0] = hmd.DistortionK[0];
  43.427 +    Distortion.K[1] = hmd.DistortionK[1];
  43.428 +    Distortion.K[2] = hmd.DistortionK[2];
  43.429 +    Distortion.K[3] = hmd.DistortionK[3];
  43.430 +
  43.431 +    Distortion.SetChromaticAberration(hmd.ChromaAbCorrection[0], hmd.ChromaAbCorrection[1],
  43.432 +                                      hmd.ChromaAbCorrection[2], hmd.ChromaAbCorrection[3]);
  43.433 +
  43.434 +    if (!IPDOverride)
  43.435 +        InterpupillaryDistance = HMD.InterpupillaryDistance;
  43.436 +
  43.437 +    DirtyFlag = true;
  43.438 +}
  43.439 +
  43.440 +void StereoConfig::SetDistortionFitPointVP(float x, float y)
  43.441 +{
  43.442 +    DistortionFitX = x;
  43.443 +    DistortionFitY = y;
  43.444 +    DirtyFlag = true;
  43.445 +}
  43.446 +
  43.447 +void StereoConfig::SetDistortionFitPointPixels(float x, float y)
  43.448 +{
  43.449 +    DistortionFitX = (4 * x / float(FullView.w)) - 1.0f;
  43.450 +    DistortionFitY = (2 * y / float(FullView.h)) - 1.0f;
  43.451 +    DirtyFlag = true;
  43.452 +}
  43.453 +
  43.454 +void StereoConfig::Set2DAreaFov(float fovRadians)
  43.455 +{
  43.456 +    Area2DFov = fovRadians;
  43.457 +    DirtyFlag = true;
  43.458 +}
  43.459 +
  43.460 +
  43.461 +const StereoEyeParams& StereoConfig::GetEyeRenderParams(StereoEye eye)
  43.462 +{
  43.463 +    static const UByte eyeParamIndices[3] = { 0, 0, 1 };
  43.464 +
  43.465 +    updateIfDirty();
  43.466 +    OVR_ASSERT(eye < sizeof(eyeParamIndices));
  43.467 +    return EyeRenderParams[eyeParamIndices[eye]];
  43.468 +}
  43.469 +
  43.470 +
  43.471 +void StereoConfig::updateComputedState()
  43.472 +{
  43.473 +    // Need to compute all of the following:
  43.474 +    //   - Aspect Ratio
  43.475 +    //   - FOV
  43.476 +    //   - Projection offsets for 3D
  43.477 +    //   - Distortion XCenterOffset
  43.478 +    //   - Update 2D
  43.479 +    //   - Initialize EyeRenderParams
  43.480 +
  43.481 +    // Compute aspect ratio. Stereo mode cuts width in half.
  43.482 +    Aspect = float(FullView.w) / float(FullView.h);
  43.483 +    Aspect *= (Mode == Stereo_None) ? 1.0f : 0.5f;
  43.484 +    Aspect *= AspectMultiplier; 
  43.485 +
  43.486 +    updateDistortionOffsetAndScale();
  43.487 +
  43.488 +    // Compute Vertical FOV based on distance, distortion, etc.
  43.489 +    // Distance from vertical center to render vertical edge perceived through the lens.
  43.490 +    // This will be larger then normal screen size due to magnification & distortion.
  43.491 +    //
  43.492 +    // This percievedHalfRTDistance equation should hold as long as the render target
  43.493 +    // and display have the same aspect ratios. What we'd like to know is where the edge
  43.494 +    // of the render target will on the perceived screen surface. With NO LENS,
  43.495 +    // the answer would be:
  43.496 +    //
  43.497 +    //  halfRTDistance = (VScreenSize / 2) * aspect *
  43.498 +    //                   DistortionFn_Inverse( DistortionScale / aspect )
  43.499 +    //
  43.500 +    // To model the optical lens we eliminates DistortionFn_Inverse. Aspect ratios
  43.501 +    // cancel out, so we get:
  43.502 +    //
  43.503 +    //  halfRTDistance = (VScreenSize / 2) * DistortionScale
  43.504 +    //
  43.505 +    if (Mode == Stereo_None)
  43.506 +    {
  43.507 +        YFov = DegreeToRad(80.0f);
  43.508 +    }
  43.509 +    else
  43.510 +    {
  43.511 +        float percievedHalfRTDistance = (HMD.VScreenSize / 2) * Distortion.Scale;    
  43.512 +        YFov = 2.0f * atan(percievedHalfRTDistance/HMD.EyeToScreenDistance);
  43.513 +    }
  43.514 +    
  43.515 +    updateProjectionOffset();
  43.516 +    update2D();
  43.517 +    updateEyeParams();
  43.518 +
  43.519 +    DirtyFlag = false;
  43.520 +}
  43.521 +
  43.522 +void StereoConfig::updateDistortionOffsetAndScale()
  43.523 +{
  43.524 +    // Distortion center shift is stored separately, since it isn't affected
  43.525 +    // by the eye distance.
  43.526 +    float lensOffset        = HMD.LensSeparationDistance * 0.5f;
  43.527 +    float lensShift         = HMD.HScreenSize * 0.25f - lensOffset;
  43.528 +    float lensViewportShift = 4.0f * lensShift / HMD.HScreenSize;
  43.529 +    Distortion.XCenterOffset= lensViewportShift;
  43.530 +
  43.531 +    // Compute distortion scale from DistortionFitX & DistortionFitY.
  43.532 +    // Fit value of 0.0 means "no fit".
  43.533 +    if ((fabs(DistortionFitX) < 0.0001f) &&  (fabs(DistortionFitY) < 0.0001f))
  43.534 +    {
  43.535 +        Distortion.Scale = 1.0f;
  43.536 +    }
  43.537 +    else
  43.538 +    {
  43.539 +        // Convert fit value to distortion-centered coordinates before fit radius
  43.540 +        // calculation.
  43.541 +        float stereoAspect = 0.5f * float(FullView.w) / float(FullView.h);
  43.542 +        float dx           = DistortionFitX - Distortion.XCenterOffset;
  43.543 +        float dy           = DistortionFitY / stereoAspect;
  43.544 +        float fitRadius    = sqrt(dx * dx + dy * dy);
  43.545 +        Distortion.Scale   = Distortion.DistortionFn(fitRadius)/fitRadius;
  43.546 +    }
  43.547 +}
  43.548 +
  43.549 +void StereoConfig::updateProjectionOffset()
  43.550 +{
  43.551 +    // Post-projection viewport coordinates range from (-1.0, 1.0), with the
  43.552 +    // center of the left viewport falling at (1/4) of horizontal screen size.
  43.553 +    // We need to shift this projection center to match with the lens center;
  43.554 +    // note that we don't use the IPD here due to collimated light property of the lens.
  43.555 +    // We compute this shift in physical units (meters) to
  43.556 +    // correct for different screen sizes and then rescale to viewport coordinates.    
  43.557 +    float viewCenter         = HMD.HScreenSize * 0.25f;
  43.558 +    float eyeProjectionShift = viewCenter - HMD.LensSeparationDistance*0.5f;
  43.559 +    ProjectionCenterOffset   = 4.0f * eyeProjectionShift / HMD.HScreenSize;
  43.560 +}
  43.561 +
  43.562 +void StereoConfig::update2D()
  43.563 +{
  43.564 +    // Orthographic projection fakes a screen at a distance of 0.8m from the
  43.565 +    // eye, where hmd screen projection surface is at 0.05m distance.
  43.566 +    // This introduces an extra off-center pixel projection shift based on eye distance.
  43.567 +    // This offCenterShift is the pixel offset of the other camera's center
  43.568 +    // in your reference camera based on surface distance.    
  43.569 +    float metersToPixels          = (HMD.HResolution / HMD.HScreenSize);
  43.570 +    float lensDistanceScreenPixels= metersToPixels * HMD.LensSeparationDistance;
  43.571 +    float eyeDistanceScreenPixels = metersToPixels * InterpupillaryDistance;
  43.572 +    float offCenterShiftPixels    = (HMD.EyeToScreenDistance / 0.8f) * eyeDistanceScreenPixels;
  43.573 +    float leftPixelCenter         = (HMD.HResolution / 2) - lensDistanceScreenPixels * 0.5f;
  43.574 +    float rightPixelCenter        = lensDistanceScreenPixels * 0.5f;
  43.575 +    float pixelDifference         = leftPixelCenter - rightPixelCenter;
  43.576 +    
  43.577 +    // This computes the number of pixels that fit within specified 2D FOV (assuming
  43.578 +    // distortion scaling will be done).
  43.579 +    float percievedHalfScreenDistance = tan(Area2DFov * 0.5f) * HMD.EyeToScreenDistance;
  43.580 +    float vfovSize = 2.0f * percievedHalfScreenDistance / Distortion.Scale;
  43.581 +    FovPixels = HMD.VResolution * vfovSize / HMD.VScreenSize;
  43.582 +    
  43.583 +    // Create orthographic matrix.   
  43.584 +    Matrix4f& m      = OrthoCenter;
  43.585 +    m.SetIdentity();
  43.586 +    m.M[0][0] = FovPixels / (FullView.w * 0.5f);
  43.587 +    m.M[1][1] = -FovPixels / FullView.h;
  43.588 +    m.M[0][3] = 0;
  43.589 +    m.M[1][3] = 0;
  43.590 +    m.M[2][2] = 0;
  43.591 +
  43.592 +    float orthoPixelOffset = (pixelDifference + offCenterShiftPixels/Distortion.Scale) * 0.5f;
  43.593 +    OrthoPixelOffset = orthoPixelOffset * 2.0f / FovPixels;
  43.594 +}
  43.595 +
  43.596 +void StereoConfig::updateEyeParams()
  43.597 +{
  43.598 +    // Projection matrix for the center eye, which the left/right matrices are based on.
  43.599 +    Matrix4f projCenter = Matrix4f::PerspectiveRH(YFov, Aspect, 0.01f, 2000.0f);
  43.600 +   
  43.601 +    switch(Mode)
  43.602 +    {
  43.603 +    case Stereo_None:
  43.604 +        {
  43.605 +            EyeRenderParams[0].Init(StereoEye_Center, FullView, 0, projCenter, OrthoCenter);
  43.606 +        }
  43.607 +        break;
  43.608 +
  43.609 +    case Stereo_LeftRight_Multipass:
  43.610 +        {
  43.611 +            Matrix4f projLeft  = Matrix4f::Translation(ProjectionCenterOffset, 0, 0) * projCenter,
  43.612 +                     projRight = Matrix4f::Translation(-ProjectionCenterOffset, 0, 0) * projCenter;
  43.613 +
  43.614 +            EyeRenderParams[0].Init(StereoEye_Left,
  43.615 +                Viewport(FullView.x, FullView.y, FullView.w/2, FullView.h),
  43.616 +                         +InterpupillaryDistance * 0.5f,  // World view shift.                       
  43.617 +                         projLeft, OrthoCenter * Matrix4f::Translation(OrthoPixelOffset, 0, 0),
  43.618 +                         &Distortion);
  43.619 +            EyeRenderParams[1].Init(StereoEye_Right,
  43.620 +                Viewport(FullView.x + FullView.w/2, FullView.y, FullView.w/2, FullView.h),
  43.621 +                         -InterpupillaryDistance * 0.5f,                         
  43.622 +                         projRight, OrthoCenter * Matrix4f::Translation(-OrthoPixelOffset, 0, 0),
  43.623 +                         &Distortion);
  43.624 +        }
  43.625 +        break;
  43.626 +    }
  43.627 +
  43.628 +}
  43.629 +
  43.630 +
  43.631 +}}}  // OVR::Util::Render
  43.632 +
    44.1 --- a/libovr/Src/Util/Util_Render_Stereo.h	Sat Sep 14 17:51:03 2013 +0300
    44.2 +++ b/libovr/Src/Util/Util_Render_Stereo.h	Sun Sep 15 04:10:05 2013 +0300
    44.3 @@ -1,1 +1,300 @@
    44.4 -/************************************************************************************
    44.5 
    44.6 PublicHeader:   OVR.h
    44.7 Filename    :   Util_Render_Stereo.h
    44.8 Content     :   Sample stereo rendering configuration classes.
    44.9 Created     :   October 22, 2012
   44.10 Authors     :   Michael Antonov
   44.11 
   44.12 Copyright   :   Copyright 2012 Oculus, Inc. All Rights reserved.
   44.13 
   44.14 Use of this software is subject to the terms of the Oculus Inc license
   44.15 agreement provided at the time of installation or download, or which
   44.16 otherwise accompanies this software in either electronic or hard copy form.
   44.17 
   44.18 *************************************************************************************/
   44.19 
   44.20 #ifndef OVR_Util_Render_Stereo_h
   44.21 #define OVR_Util_Render_Stereo_h
   44.22 
   44.23 #include "../OVR_Device.h"
   44.24 
   44.25 namespace OVR { namespace Util { namespace Render {
   44.26 
   44.27 
   44.28 //-----------------------------------------------------------------------------------
   44.29 // ***** Stereo Enumerations
   44.30 
   44.31 // StereoMode describes rendering modes that can be used by StereoConfig.
   44.32 // These modes control whether stereo rendering is used or not (Stereo_None),
   44.33 // and how it is implemented.
   44.34 enum StereoMode
   44.35 {
   44.36     Stereo_None                 = 0,
   44.37     Stereo_LeftRight_Multipass  = 1
   44.38 };
   44.39 
   44.40 
   44.41 // StereoEye specifies which eye we are rendering for; it is used to
   44.42 // retrieve StereoEyeParams.
   44.43 enum StereoEye
   44.44 {
   44.45     StereoEye_Center,
   44.46     StereoEye_Left,
   44.47     StereoEye_Right    
   44.48 };
   44.49 
   44.50 
   44.51 //-----------------------------------------------------------------------------------
   44.52 // ***** Viewport
   44.53 
   44.54 // Viewport describes a rectangular area used for rendering, in pixels.
   44.55 struct Viewport
   44.56 {
   44.57     int x, y;
   44.58     int w, h;
   44.59 
   44.60     Viewport() {}
   44.61     Viewport(int x1, int y1, int w1, int h1) : x(x1), y(y1), w(w1), h(h1) { }
   44.62 
   44.63     bool operator == (const Viewport& vp) const
   44.64     { return (x == vp.x) && (y == vp.y) && (w == vp.w) && (h == vp.h); }
   44.65     bool operator != (const Viewport& vp) const
   44.66     { return !operator == (vp); }
   44.67 };
   44.68 
   44.69 
   44.70 //-----------------------------------------------------------------------------------
   44.71 // ***** DistortionConfig
   44.72 
   44.73 // DistortionConfig Provides controls for the distortion shader.
   44.74 //  - K[0] - K[3] are coefficients for the distortion function.
   44.75 //  - XCenterOffset is the offset of lens distortion center from the 
   44.76 //    center of one-eye screen half. [-1, 1] Range.
   44.77 //  - Scale is a factor of how much larger will the input image be,
   44.78 //    with a factor of 1.0f being no scaling. An inverse of this 
   44.79 //    value is applied to sampled UV coordinates (1/Scale).
   44.80 //  - ChromaticAberration is an array of parameters for controlling
   44.81 //    additional Red and Blue scaling in order to reduce chromatic aberration
   44.82 //    caused by the Rift lenses.
   44.83 class DistortionConfig
   44.84 {
   44.85 public:
   44.86     DistortionConfig(float k0 = 1.0f, float k1 = 0.0f, float k2 = 0.0f, float k3 = 0.0f)
   44.87         : XCenterOffset(0), YCenterOffset(0), Scale(1.0f)
   44.88     { 
   44.89         SetCoefficients(k0, k1, k2, k3);
   44.90         SetChromaticAberration();
   44.91     }
   44.92 
   44.93     void SetCoefficients(float k0, float k1 = 0.0f, float k2 = 0.0f, float k3 = 0.0f)
   44.94     { K[0] = k0; K[1] = k1;  K[2] = k2; K[3] = k3; }
   44.95 
   44.96     void SetChromaticAberration(float red1 = 1.0f, float red2 = 0.0f, float blue1 = 1.0f, float blue2 = 0.0f)
   44.97     { ChromaticAberration[0] = red1; ChromaticAberration[1] = red2; ChromaticAberration[2] = blue1; ChromaticAberration[3] = blue2; }
   44.98 
   44.99 
  44.100     // DistortionFn applies distortion equation to the argument. The returned
  44.101     // value should match distortion equation used in shader.
  44.102     float  DistortionFn(float r) const
  44.103     {        
  44.104         float rsq   = r * r;
  44.105         float scale = r * (K[0] + K[1] * rsq + K[2] * rsq * rsq + K[3] * rsq * rsq * rsq);
  44.106         return scale;
  44.107     }
  44.108 
  44.109     // DistortionFnInverse computes the inverse of the distortion function on an argument.
  44.110     float DistortionFnInverse(float r);
  44.111 
  44.112     float   K[4];
  44.113     float   XCenterOffset, YCenterOffset;
  44.114     float   Scale;
  44.115 
  44.116     float   ChromaticAberration[4]; // Additional per-channel scaling is applied after distortion:
  44.117                                     // Index [0] - Red channel constant coefficient.
  44.118                                     // Index [1] - Red channel r^2 coefficient.
  44.119                                     // Index [2] - Blue channel constant coefficient.
  44.120                                     // Index [3] - Blue channel r^2 coefficient.
  44.121 };
  44.122 
  44.123 
  44.124 //-----------------------------------------------------------------------------------
  44.125 // ***** StereoEyeParams
  44.126 
  44.127 // StereoEyeParams describes RenderDevice configuration needed to render
  44.128 // the scene for one eye. 
  44.129 class StereoEyeParams
  44.130 {
  44.131 public:
  44.132     StereoEye                Eye;
  44.133     Viewport                 VP;               // Viewport that we are rendering to        
  44.134     const DistortionConfig*  pDistortion;
  44.135 
  44.136     Matrix4f                 ViewAdjust;       // Translation to be applied to view matrix.
  44.137     Matrix4f                 Projection;       // Projection matrix used with this eye.
  44.138     Matrix4f                 OrthoProjection;  // Orthographic projection used with this eye.
  44.139 
  44.140     void Init(StereoEye eye, const Viewport &vp, float vofs,
  44.141               const Matrix4f& proj, const Matrix4f& orthoProj,
  44.142               const DistortionConfig* distortion = 0)
  44.143     {
  44.144         Eye                    = eye;
  44.145         VP                     = vp;
  44.146         ViewAdjust             = Matrix4f::Translation(Vector3f(vofs,0,0));
  44.147         Projection             = proj;
  44.148         OrthoProjection        = orthoProj;
  44.149         pDistortion            = distortion;        
  44.150     }
  44.151 };
  44.152 
  44.153 
  44.154 //-----------------------------------------------------------------------------------
  44.155 // *****  StereoConfig
  44.156 
  44.157 // StereoConfig maintains a scene stereo state and allow switching between different
  44.158 // stereo rendering modes. To support rendering, StereoConfig keeps track of HMD
  44.159 // variables such as screen size, eye-to-screen distance and distortion, and computes
  44.160 // extra data such as FOV and distortion center offsets based on it. Rendering
  44.161 // parameters are returned though StereoEyeParams for each eye.
  44.162 //
  44.163 // Beyond regular 3D projection, this class supports rendering a 2D orthographic
  44.164 // surface for UI and text. The 2D surface will be defined as fitting within a 2D
  44.165 // field of view (85 degrees by default) and used [-1,1] coordinate system with
  44.166 // square pixels. The (0,0) coordinate corresponds to eye center location
  44.167 // that is properly adjusted during rendering through SterepRenderParams::Adjust2D.
  44.168 // Genreally speaking, text outside [-1,1] coordinate range will not be readable.
  44.169 
  44.170 class StereoConfig
  44.171 {
  44.172 public:
  44.173 
  44.174     StereoConfig(StereoMode mode = Stereo_LeftRight_Multipass,
  44.175                  const Viewport& fullViewport = Viewport(0,0, 1280,800));
  44.176  
  44.177 
  44.178     // *** Modifiable State Access
  44.179 
  44.180     // Sets a stereo rendering mode and updates internal cached
  44.181     // state (matrices, per-eye view) based on it.
  44.182     void        SetStereoMode(StereoMode mode)  { Mode = mode; DirtyFlag = true; }
  44.183     StereoMode  GetStereoMode() const           { return Mode; }
  44.184 
  44.185     // Sets HMD parameters; also initializes distortion coefficients.
  44.186     void        SetHMDInfo(const HMDInfo& hmd);
  44.187     const HMDInfo& GetHMDInfo() const           { return HMD; }
  44.188 
  44.189     // Query physical eye-to-screen distance in meters, which combines screen-to-lens and
  44.190     // and lens-to-eye pupil distances. Modifying this value adjusts FOV.
  44.191     float       GetEyeToScreenDistance() const  { return HMD.EyeToScreenDistance; }
  44.192     void        SetEyeToScreenDistance(float esd) { HMD.EyeToScreenDistance = esd; DirtyFlag = true; }
  44.193 
  44.194     // Interpupillary distance used for stereo, in meters. Default is 0.064m (64 mm).
  44.195     void        SetIPD(float ipd)               { InterpupillaryDistance = ipd; IPDOverride = DirtyFlag = true; }
  44.196     float       GetIPD() const                  { return InterpupillaryDistance; }
  44.197 
  44.198     // Set full render target viewport; for HMD this includes both eyes. 
  44.199     void        SetFullViewport(const Viewport& vp);
  44.200     const Viewport& GetFullViewport() const     { return FullView; }
  44.201 
  44.202     // Aspect ratio defaults to ((w/h)*multiplier) computed per eye.
  44.203     // Aspect multiplier allows adjusting aspect ratio consistently for Stereo/NoStereo.
  44.204     void        SetAspectMultiplier(float m)    { AspectMultiplier = m; DirtyFlag = true; }
  44.205     float       GetAspectMultiplier() const     { return AspectMultiplier; }
  44.206 
  44.207     
  44.208     // For the distorted image to fill rendered viewport, input texture render target needs to be
  44.209     // scaled by DistortionScale before sampling. The scale factor is computed by fitting a point
  44.210     // on of specified radius from a distortion center, more easily specified as a coordinate.
  44.211     // SetDistortionFitPointVP sets the (x,y) coordinate of the point that scale will be "fit" to,
  44.212     // assuming [-1,1] coordinate range for full left-eye viewport. A fit point is a location
  44.213     // where source (pre-distortion) and target (post-distortion) image match each other.
  44.214     // For the right eye, the interpretation of 'u' will be inverted.  
  44.215     void       SetDistortionFitPointVP(float x, float y);
  44.216     // SetDistortionFitPointPixels sets the (x,y) coordinate of the point that scale will be "fit" to,
  44.217     // specified in pixeld for full left-eye texture.
  44.218     void       SetDistortionFitPointPixels(float x, float y);
  44.219 
  44.220     // Changes all distortion settings.
  44.221     // Note that setting HMDInfo also changes Distortion coefficients.
  44.222     void        SetDistortionConfig(const DistortionConfig& d) { Distortion = d; DirtyFlag = true; }
  44.223     
  44.224     // Modify distortion coefficients; useful for adjustment tweaking.
  44.225     void        SetDistortionK(int i, float k)  { Distortion.K[i] = k; DirtyFlag = true; }
  44.226     float       GetDistortionK(int i) const     { return Distortion.K[i]; }
  44.227 
  44.228     // Sets the fieldOfView that the 2D coordinate area stretches to.
  44.229     void        Set2DAreaFov(float fovRadians);
  44.230 
  44.231 
  44.232     // *** Computed State
  44.233 
  44.234     // Return current aspect ratio.
  44.235     float      GetAspect()                      { updateIfDirty(); return Aspect; }
  44.236     
  44.237     // Return computed vertical FOV in radians/degrees.
  44.238     float      GetYFOVRadians()                 { updateIfDirty(); return YFov; }
  44.239     float      GetYFOVDegrees()                 { return RadToDegree(GetYFOVRadians()); }
  44.240 
  44.241     // Query horizontal projection center offset as a distance away from the
  44.242     // one-eye [-1,1] unit viewport.
  44.243     // Positive return value should be used for left eye, negative for right eye. 
  44.244     float      GetProjectionCenterOffset()      { updateIfDirty(); return ProjectionCenterOffset; }
  44.245 
  44.246     // GetDistortionConfig isn't const because XCenterOffset bay need to be recomputed.  
  44.247     const DistortionConfig& GetDistortionConfig() { updateIfDirty(); return Distortion; }
  44.248 
  44.249     // Returns DistortionScale factor by which input texture size is increased to make
  44.250     // post-distortion result distortion fit the viewport.
  44.251     float      GetDistortionScale()             { updateIfDirty(); return Distortion.Scale; }
  44.252 
  44.253     // Returns the size of a pixel within 2D coordinate system.
  44.254     float      Get2DUnitPixel()                 { updateIfDirty();  return (2.0f / (FovPixels * Distortion.Scale)); }
  44.255 
  44.256     // Returns full set of Stereo rendering parameters for the specified eye.
  44.257     const StereoEyeParams& GetEyeRenderParams(StereoEye eye);
  44.258    
  44.259 private:    
  44.260 
  44.261     void updateIfDirty()   { if (DirtyFlag) updateComputedState(); }
  44.262     void updateComputedState();
  44.263 
  44.264     void updateDistortionOffsetAndScale();
  44.265     void updateProjectionOffset();
  44.266     void update2D();
  44.267     void updateEyeParams();
  44.268 
  44.269 
  44.270     // *** Modifiable State
  44.271 
  44.272     StereoMode         Mode;
  44.273     float              InterpupillaryDistance;
  44.274     float              AspectMultiplier;               // Multiplied into aspect ratio to change it.
  44.275     HMDInfo            HMD;
  44.276     DistortionConfig   Distortion;
  44.277     float              DistortionFitX, DistortionFitY; // In [-1,1] half-screen viewport units.
  44.278     Viewport           FullView;                       // Entire window viewport.
  44.279 
  44.280     float              Area2DFov;                      // FOV range mapping to [-1, 1] 2D area.
  44.281  
  44.282     // *** Computed State
  44.283  
  44.284     bool               DirtyFlag;   // Set when any if the modifiable state changed.
  44.285     bool               IPDOverride; // True after SetIPD was called.    
  44.286     float              YFov;        // Vertical FOV.
  44.287     float              Aspect;      // Aspect ratio: (w/h)*AspectMultiplier.
  44.288     float              ProjectionCenterOffset;
  44.289     StereoEyeParams    EyeRenderParams[2];
  44.290 
  44.291   
  44.292     // ** 2D Rendering
  44.293 
  44.294     // Number of 2D pixels in the FOV. This defines [-1,1] coordinate range for 2D.  
  44.295     float              FovPixels;
  44.296     Matrix4f           OrthoCenter;
  44.297     float              OrthoPixelOffset;
  44.298 };
  44.299 
  44.300 
  44.301 }}}  // OVR::Util::Render
  44.302 
  44.303 #endif
  44.304 \ No newline at end of file
  44.305 +/************************************************************************************
  44.306 +
  44.307 +PublicHeader:   OVR.h
  44.308 +Filename    :   Util_Render_Stereo.h
  44.309 +Content     :   Sample stereo rendering configuration classes.
  44.310 +Created     :   October 22, 2012
  44.311 +Authors     :   Michael Antonov
  44.312 +
  44.313 +Copyright   :   Copyright 2012 Oculus, Inc. All Rights reserved.
  44.314 +
  44.315 +Use of this software is subject to the terms of the Oculus Inc license
  44.316 +agreement provided at the time of installation or download, or which
  44.317 +otherwise accompanies this software in either electronic or hard copy form.
  44.318 +
  44.319 +*************************************************************************************/
  44.320 +
  44.321 +#ifndef OVR_Util_Render_Stereo_h
  44.322 +#define OVR_Util_Render_Stereo_h
  44.323 +
  44.324 +#include "../OVR_Device.h"
  44.325 +
  44.326 +namespace OVR { namespace Util { namespace Render {
  44.327 +
  44.328 +
  44.329 +//-----------------------------------------------------------------------------------
  44.330 +// ***** Stereo Enumerations
  44.331 +
  44.332 +// StereoMode describes rendering modes that can be used by StereoConfig.
  44.333 +// These modes control whether stereo rendering is used or not (Stereo_None),
  44.334 +// and how it is implemented.
  44.335 +enum StereoMode
  44.336 +{
  44.337 +    Stereo_None                 = 0,
  44.338 +    Stereo_LeftRight_Multipass  = 1
  44.339 +};
  44.340 +
  44.341 +
  44.342 +// StereoEye specifies which eye we are rendering for; it is used to
  44.343 +// retrieve StereoEyeParams.
  44.344 +enum StereoEye
  44.345 +{
  44.346 +    StereoEye_Center,
  44.347 +    StereoEye_Left,
  44.348 +    StereoEye_Right    
  44.349 +};
  44.350 +
  44.351 +
  44.352 +//-----------------------------------------------------------------------------------
  44.353 +// ***** Viewport
  44.354 +
  44.355 +// Viewport describes a rectangular area used for rendering, in pixels.
  44.356 +struct Viewport
  44.357 +{
  44.358 +    int x, y;
  44.359 +    int w, h;
  44.360 +
  44.361 +    Viewport() {}
  44.362 +    Viewport(int x1, int y1, int w1, int h1) : x(x1), y(y1), w(w1), h(h1) { }
  44.363 +
  44.364 +    bool operator == (const Viewport& vp) const
  44.365 +    { return (x == vp.x) && (y == vp.y) && (w == vp.w) && (h == vp.h); }
  44.366 +    bool operator != (const Viewport& vp) const
  44.367 +    { return !operator == (vp); }
  44.368 +};
  44.369 +
  44.370 +
  44.371 +//-----------------------------------------------------------------------------------
  44.372 +// ***** DistortionConfig
  44.373 +
  44.374 +// DistortionConfig Provides controls for the distortion shader.
  44.375 +//  - K[0] - K[3] are coefficients for the distortion function.
  44.376 +//  - XCenterOffset is the offset of lens distortion center from the 
  44.377 +//    center of one-eye screen half. [-1, 1] Range.
  44.378 +//  - Scale is a factor of how much larger will the input image be,
  44.379 +//    with a factor of 1.0f being no scaling. An inverse of this 
  44.380 +//    value is applied to sampled UV coordinates (1/Scale).
  44.381 +//  - ChromaticAberration is an array of parameters for controlling
  44.382 +//    additional Red and Blue scaling in order to reduce chromatic aberration
  44.383 +//    caused by the Rift lenses.
  44.384 +class DistortionConfig
  44.385 +{
  44.386 +public:
  44.387 +    DistortionConfig(float k0 = 1.0f, float k1 = 0.0f, float k2 = 0.0f, float k3 = 0.0f)
  44.388 +        : XCenterOffset(0), YCenterOffset(0), Scale(1.0f)
  44.389 +    { 
  44.390 +        SetCoefficients(k0, k1, k2, k3);
  44.391 +        SetChromaticAberration();
  44.392 +    }
  44.393 +
  44.394 +    void SetCoefficients(float k0, float k1 = 0.0f, float k2 = 0.0f, float k3 = 0.0f)
  44.395 +    { K[0] = k0; K[1] = k1;  K[2] = k2; K[3] = k3; }
  44.396 +
  44.397 +    void SetChromaticAberration(float red1 = 1.0f, float red2 = 0.0f, float blue1 = 1.0f, float blue2 = 0.0f)
  44.398 +    { ChromaticAberration[0] = red1; ChromaticAberration[1] = red2; ChromaticAberration[2] = blue1; ChromaticAberration[3] = blue2; }
  44.399 +
  44.400 +
  44.401 +    // DistortionFn applies distortion equation to the argument. The returned
  44.402 +    // value should match distortion equation used in shader.
  44.403 +    float  DistortionFn(float r) const
  44.404 +    {        
  44.405 +        float rsq   = r * r;
  44.406 +        float scale = r * (K[0] + K[1] * rsq + K[2] * rsq * rsq + K[3] * rsq * rsq * rsq);
  44.407 +        return scale;
  44.408 +    }
  44.409 +
  44.410 +    // DistortionFnInverse computes the inverse of the distortion function on an argument.
  44.411 +    float DistortionFnInverse(float r);
  44.412 +
  44.413 +    float   K[4];
  44.414 +    float   XCenterOffset, YCenterOffset;
  44.415 +    float   Scale;
  44.416 +
  44.417 +    float   ChromaticAberration[4]; // Additional per-channel scaling is applied after distortion:
  44.418 +                                    // Index [0] - Red channel constant coefficient.
  44.419 +                                    // Index [1] - Red channel r^2 coefficient.
  44.420 +                                    // Index [2] - Blue channel constant coefficient.
  44.421 +                                    // Index [3] - Blue channel r^2 coefficient.
  44.422 +};
  44.423 +
  44.424 +
  44.425 +//-----------------------------------------------------------------------------------
  44.426 +// ***** StereoEyeParams
  44.427 +
  44.428 +// StereoEyeParams describes RenderDevice configuration needed to render
  44.429 +// the scene for one eye. 
  44.430 +class StereoEyeParams
  44.431 +{
  44.432 +public:
  44.433 +    StereoEye                Eye;
  44.434 +    Viewport                 VP;               // Viewport that we are rendering to        
  44.435 +    const DistortionConfig*  pDistortion;
  44.436 +
  44.437 +    Matrix4f                 ViewAdjust;       // Translation to be applied to view matrix.
  44.438 +    Matrix4f                 Projection;       // Projection matrix used with this eye.
  44.439 +    Matrix4f                 OrthoProjection;  // Orthographic projection used with this eye.
  44.440 +
  44.441 +    void Init(StereoEye eye, const Viewport &vp, float vofs,
  44.442 +              const Matrix4f& proj, const Matrix4f& orthoProj,
  44.443 +              const DistortionConfig* distortion = 0)
  44.444 +    {
  44.445 +        Eye                    = eye;
  44.446 +        VP                     = vp;
  44.447 +        ViewAdjust             = Matrix4f::Translation(Vector3f(vofs,0,0));
  44.448 +        Projection             = proj;
  44.449 +        OrthoProjection        = orthoProj;
  44.450 +        pDistortion            = distortion;        
  44.451 +    }
  44.452 +};
  44.453 +
  44.454 +
  44.455 +//-----------------------------------------------------------------------------------
  44.456 +// *****  StereoConfig
  44.457 +
  44.458 +// StereoConfig maintains a scene stereo state and allow switching between different
  44.459 +// stereo rendering modes. To support rendering, StereoConfig keeps track of HMD
  44.460 +// variables such as screen size, eye-to-screen distance and distortion, and computes
  44.461 +// extra data such as FOV and distortion center offsets based on it. Rendering
  44.462 +// parameters are returned though StereoEyeParams for each eye.
  44.463 +//
  44.464 +// Beyond regular 3D projection, this class supports rendering a 2D orthographic
  44.465 +// surface for UI and text. The 2D surface will be defined as fitting within a 2D
  44.466 +// field of view (85 degrees by default) and used [-1,1] coordinate system with
  44.467 +// square pixels. The (0,0) coordinate corresponds to eye center location
  44.468 +// that is properly adjusted during rendering through SterepRenderParams::Adjust2D.
  44.469 +// Genreally speaking, text outside [-1,1] coordinate range will not be readable.
  44.470 +
  44.471 +class StereoConfig
  44.472 +{
  44.473 +public:
  44.474 +
  44.475 +    StereoConfig(StereoMode mode = Stereo_LeftRight_Multipass,
  44.476 +                 const Viewport& fullViewport = Viewport(0,0, 1280,800));
  44.477 + 
  44.478 +
  44.479 +    // *** Modifiable State Access
  44.480 +
  44.481 +    // Sets a stereo rendering mode and updates internal cached
  44.482 +    // state (matrices, per-eye view) based on it.
  44.483 +    void        SetStereoMode(StereoMode mode)  { Mode = mode; DirtyFlag = true; }
  44.484 +    StereoMode  GetStereoMode() const           { return Mode; }
  44.485 +
  44.486 +    // Sets HMD parameters; also initializes distortion coefficients.
  44.487 +    void        SetHMDInfo(const HMDInfo& hmd);
  44.488 +    const HMDInfo& GetHMDInfo() const           { return HMD; }
  44.489 +
  44.490 +    // Query physical eye-to-screen distance in meters, which combines screen-to-lens and
  44.491 +    // and lens-to-eye pupil distances. Modifying this value adjusts FOV.
  44.492 +    float       GetEyeToScreenDistance() const  { return HMD.EyeToScreenDistance; }
  44.493 +    void        SetEyeToScreenDistance(float esd) { HMD.EyeToScreenDistance = esd; DirtyFlag = true; }
  44.494 +
  44.495 +    // Interpupillary distance used for stereo, in meters. Default is 0.064m (64 mm).
  44.496 +    void        SetIPD(float ipd)               { InterpupillaryDistance = ipd; IPDOverride = DirtyFlag = true; }
  44.497 +    float       GetIPD() const                  { return InterpupillaryDistance; }
  44.498 +
  44.499 +    // Set full render target viewport; for HMD this includes both eyes. 
  44.500 +    void        SetFullViewport(const Viewport& vp);
  44.501 +    const Viewport& GetFullViewport() const     { return FullView; }
  44.502 +
  44.503 +    // Aspect ratio defaults to ((w/h)*multiplier) computed per eye.
  44.504 +    // Aspect multiplier allows adjusting aspect ratio consistently for Stereo/NoStereo.
  44.505 +    void        SetAspectMultiplier(float m)    { AspectMultiplier = m; DirtyFlag = true; }
  44.506 +    float       GetAspectMultiplier() const     { return AspectMultiplier; }
  44.507 +
  44.508 +    
  44.509 +    // For the distorted image to fill rendered viewport, input texture render target needs to be
  44.510 +    // scaled by DistortionScale before sampling. The scale factor is computed by fitting a point
  44.511 +    // on of specified radius from a distortion center, more easily specified as a coordinate.
  44.512 +    // SetDistortionFitPointVP sets the (x,y) coordinate of the point that scale will be "fit" to,
  44.513 +    // assuming [-1,1] coordinate range for full left-eye viewport. A fit point is a location
  44.514 +    // where source (pre-distortion) and target (post-distortion) image match each other.
  44.515 +    // For the right eye, the interpretation of 'u' will be inverted.  
  44.516 +    void       SetDistortionFitPointVP(float x, float y);
  44.517 +    // SetDistortionFitPointPixels sets the (x,y) coordinate of the point that scale will be "fit" to,
  44.518 +    // specified in pixeld for full left-eye texture.
  44.519 +    void       SetDistortionFitPointPixels(float x, float y);
  44.520 +
  44.521 +    // Changes all distortion settings.
  44.522 +    // Note that setting HMDInfo also changes Distortion coefficients.
  44.523 +    void        SetDistortionConfig(const DistortionConfig& d) { Distortion = d; DirtyFlag = true; }
  44.524 +    
  44.525 +    // Modify distortion coefficients; useful for adjustment tweaking.
  44.526 +    void        SetDistortionK(int i, float k)  { Distortion.K[i] = k; DirtyFlag = true; }
  44.527 +    float       GetDistortionK(int i) const     { return Distortion.K[i]; }
  44.528 +
  44.529 +    // Sets the fieldOfView that the 2D coordinate area stretches to.
  44.530 +    void        Set2DAreaFov(float fovRadians);
  44.531 +
  44.532 +
  44.533 +    // *** Computed State
  44.534 +
  44.535 +    // Return current aspect ratio.
  44.536 +    float      GetAspect()                      { updateIfDirty(); return Aspect; }
  44.537 +    
  44.538 +    // Return computed vertical FOV in radians/degrees.
  44.539 +    float      GetYFOVRadians()                 { updateIfDirty(); return YFov; }
  44.540 +    float      GetYFOVDegrees()                 { return RadToDegree(GetYFOVRadians()); }
  44.541 +
  44.542 +    // Query horizontal projection center offset as a distance away from the
  44.543 +    // one-eye [-1,1] unit viewport.
  44.544 +    // Positive return value should be used for left eye, negative for right eye. 
  44.545 +    float      GetProjectionCenterOffset()      { updateIfDirty(); return ProjectionCenterOffset; }
  44.546 +
  44.547 +    // GetDistortionConfig isn't const because XCenterOffset bay need to be recomputed.  
  44.548 +    const DistortionConfig& GetDistortionConfig() { updateIfDirty(); return Distortion; }
  44.549 +
  44.550 +    // Returns DistortionScale factor by which input texture size is increased to make
  44.551 +    // post-distortion result distortion fit the viewport.
  44.552 +    float      GetDistortionScale()             { updateIfDirty(); return Distortion.Scale; }
  44.553 +
  44.554 +    // Returns the size of a pixel within 2D coordinate system.
  44.555 +    float      Get2DUnitPixel()                 { updateIfDirty();  return (2.0f / (FovPixels * Distortion.Scale)); }
  44.556 +
  44.557 +    // Returns full set of Stereo rendering parameters for the specified eye.
  44.558 +    const StereoEyeParams& GetEyeRenderParams(StereoEye eye);
  44.559 +   
  44.560 +private:    
  44.561 +
  44.562 +    void updateIfDirty()   { if (DirtyFlag) updateComputedState(); }
  44.563 +    void updateComputedState();
  44.564 +
  44.565 +    void updateDistortionOffsetAndScale();
  44.566 +    void updateProjectionOffset();
  44.567 +    void update2D();
  44.568 +    void updateEyeParams();
  44.569 +
  44.570 +
  44.571 +    // *** Modifiable State
  44.572 +
  44.573 +    StereoMode         Mode;
  44.574 +    float              InterpupillaryDistance;
  44.575 +    float              AspectMultiplier;               // Multiplied into aspect ratio to change it.
  44.576 +    HMDInfo            HMD;
  44.577 +    DistortionConfig   Distortion;
  44.578 +    float              DistortionFitX, DistortionFitY; // In [-1,1] half-screen viewport units.
  44.579 +    Viewport           FullView;                       // Entire window viewport.
  44.580 +
  44.581 +    float              Area2DFov;                      // FOV range mapping to [-1, 1] 2D area.
  44.582 + 
  44.583 +    // *** Computed State
  44.584 + 
  44.585 +    bool               DirtyFlag;   // Set when any if the modifiable state changed.
  44.586 +    bool               IPDOverride; // True after SetIPD was called.    
  44.587 +    float              YFov;        // Vertical FOV.
  44.588 +    float              Aspect;      // Aspect ratio: (w/h)*AspectMultiplier.
  44.589 +    float              ProjectionCenterOffset;
  44.590 +    StereoEyeParams    EyeRenderParams[2];
  44.591 +
  44.592 +  
  44.593 +    // ** 2D Rendering
  44.594 +
  44.595 +    // Number of 2D pixels in the FOV. This defines [-1,1] coordinate range for 2D.  
  44.596 +    float              FovPixels;
  44.597 +    Matrix4f           OrthoCenter;
  44.598 +    float              OrthoPixelOffset;
  44.599 +};
  44.600 +
  44.601 +
  44.602 +}}}  // OVR::Util::Render
  44.603 +
  44.604 +#endif
    45.1 --- a/libovr/Src/linux/OVR_ThreadsPthread.cpp	Sat Sep 14 17:51:03 2013 +0300
    45.2 +++ b/libovr/Src/linux/OVR_ThreadsPthread.cpp	Sun Sep 15 04:10:05 2013 +0300
    45.3 @@ -1,1 +1,795 @@
    45.4 -
    45.5 #include "OVR_Threads.h"
    45.6 #include "OVR_Hash.h"
    45.7 
    45.8 #ifdef OVR_ENABLE_THREADS
    45.9 
   45.10 #include "OVR_Timer.h"
   45.11 #include "OVR_Log.h"
   45.12 
   45.13 #include <pthread.h>
   45.14 #include <time.h>
   45.15 
   45.16 #ifdef OVR_OS_PS3
   45.17 #include <sys/sys_time.h>
   45.18 #include <sys/timer.h>
   45.19 #include <sys/synchronization.h>
   45.20 #define sleep(x) sys_timer_sleep(x)
   45.21 #define usleep(x) sys_timer_usleep(x)
   45.22 using std::timespec;
   45.23 #else
   45.24 #include <unistd.h>
   45.25 #include <sys/time.h>
   45.26 #include <errno.h>
   45.27 #endif
   45.28 
   45.29 namespace OVR {
   45.30 
   45.31 // ***** Mutex implementation
   45.32 
   45.33 
   45.34 // *** Internal Mutex implementation structure
   45.35 
   45.36 class MutexImpl : public NewOverrideBase
   45.37 {
   45.38     // System mutex or semaphore
   45.39     pthread_mutex_t   SMutex;
   45.40     bool          Recursive;
   45.41     unsigned      LockCount;
   45.42     pthread_t     LockedBy;
   45.43 
   45.44     friend class WaitConditionImpl;
   45.45 
   45.46 public:
   45.47     // Constructor/destructor
   45.48     MutexImpl(Mutex* pmutex, bool recursive = 1);
   45.49     ~MutexImpl();
   45.50 
   45.51     // Locking functions
   45.52     void                DoLock();
   45.53     bool                TryLock();
   45.54     void                Unlock(Mutex* pmutex);
   45.55     // Returns 1 if the mutes is currently locked
   45.56     bool                IsLockedByAnotherThread(Mutex* pmutex);        
   45.57     bool                IsSignaled() const;
   45.58 };
   45.59 
   45.60 pthread_mutexattr_t Lock::RecursiveAttr;
   45.61 bool Lock::RecursiveAttrInit = 0;
   45.62 
   45.63 // *** Constructor/destructor
   45.64 MutexImpl::MutexImpl(Mutex* pmutex, bool recursive)
   45.65 {   
   45.66     Recursive           = recursive;
   45.67     LockCount           = 0;
   45.68 
   45.69     if (Recursive)
   45.70     {
   45.71         if (!Lock::RecursiveAttrInit)
   45.72         {
   45.73             pthread_mutexattr_init(&Lock::RecursiveAttr);
   45.74             pthread_mutexattr_settype(&Lock::RecursiveAttr, PTHREAD_MUTEX_RECURSIVE);
   45.75             Lock::RecursiveAttrInit = 1;
   45.76         }
   45.77 
   45.78         pthread_mutex_init(&SMutex, &Lock::RecursiveAttr);
   45.79     }
   45.80     else
   45.81         pthread_mutex_init(&SMutex, 0);
   45.82 }
   45.83 
   45.84 MutexImpl::~MutexImpl()
   45.85 {
   45.86     pthread_mutex_destroy(&SMutex);
   45.87 }
   45.88 
   45.89 
   45.90 // Lock and try lock
   45.91 void MutexImpl::DoLock()
   45.92 {
   45.93     while (pthread_mutex_lock(&SMutex));
   45.94     LockCount++;
   45.95     LockedBy = pthread_self();
   45.96 }
   45.97 
   45.98 bool MutexImpl::TryLock()
   45.99 {
  45.100     if (!pthread_mutex_trylock(&SMutex))
  45.101     {
  45.102         LockCount++;
  45.103         LockedBy = pthread_self();
  45.104         return 1;
  45.105     }
  45.106     
  45.107     return 0;
  45.108 }
  45.109 
  45.110 void MutexImpl::Unlock(Mutex* pmutex)
  45.111 {
  45.112     OVR_ASSERT(pthread_self() == LockedBy && LockCount > 0);
  45.113 
  45.114     unsigned lockCount;
  45.115     LockCount--;
  45.116     lockCount = LockCount;
  45.117 
  45.118     pthread_mutex_unlock(&SMutex);
  45.119 }
  45.120 
  45.121 bool    MutexImpl::IsLockedByAnotherThread(Mutex* pmutex)
  45.122 {
  45.123     // There could be multiple interpretations of IsLocked with respect to current thread
  45.124     if (LockCount == 0)
  45.125         return 0;
  45.126     if (pthread_self() != LockedBy)
  45.127         return 1;
  45.128     return 0;
  45.129 }
  45.130 
  45.131 bool    MutexImpl::IsSignaled() const
  45.132 {
  45.133     // An mutex is signaled if it is not locked ANYWHERE
  45.134     // Note that this is different from IsLockedByAnotherThread function,
  45.135     // that takes current thread into account
  45.136     return LockCount == 0;
  45.137 }
  45.138 
  45.139 
  45.140 // *** Actual Mutex class implementation
  45.141 
  45.142 Mutex::Mutex(bool recursive)
  45.143 {
  45.144     // NOTE: RefCount mode already thread-safe for all waitables.
  45.145     pImpl = new MutexImpl(this, recursive);
  45.146 }
  45.147 
  45.148 Mutex::~Mutex()
  45.149 {
  45.150     delete pImpl;
  45.151 }
  45.152 
  45.153 // Lock and try lock
  45.154 void Mutex::DoLock()
  45.155 {
  45.156     pImpl->DoLock();
  45.157 }
  45.158 bool Mutex::TryLock()
  45.159 {
  45.160     return pImpl->TryLock();
  45.161 }
  45.162 void Mutex::Unlock()
  45.163 {
  45.164     pImpl->Unlock(this);
  45.165 }
  45.166 bool    Mutex::IsLockedByAnotherThread()
  45.167 {
  45.168     return pImpl->IsLockedByAnotherThread(this);
  45.169 }
  45.170 
  45.171 
  45.172 
  45.173 //-----------------------------------------------------------------------------------
  45.174 // ***** Event
  45.175 
  45.176 bool Event::Wait(unsigned delay)
  45.177 {
  45.178     Mutex::Locker lock(&StateMutex);
  45.179 
  45.180     // Do the correct amount of waiting
  45.181     if (delay == OVR_WAIT_INFINITE)
  45.182     {
  45.183         while(!State)
  45.184             StateWaitCondition.Wait(&StateMutex);
  45.185     }
  45.186     else if (delay)
  45.187     {
  45.188         if (!State)
  45.189             StateWaitCondition.Wait(&StateMutex, delay);
  45.190     }
  45.191 
  45.192     bool state = State;
  45.193     // Take care of temporary 'pulsing' of a state
  45.194     if (Temporary)
  45.195     {
  45.196         Temporary   = false;
  45.197         State       = false;
  45.198     }
  45.199     return state;
  45.200 }
  45.201 
  45.202 void Event::updateState(bool newState, bool newTemp, bool mustNotify)
  45.203 {
  45.204     Mutex::Locker lock(&StateMutex);
  45.205     State       = newState;
  45.206     Temporary   = newTemp;
  45.207     if (mustNotify)
  45.208         StateWaitCondition.NotifyAll();    
  45.209 }
  45.210 
  45.211 
  45.212 
  45.213 // ***** Wait Condition Implementation
  45.214 
  45.215 // Internal implementation class
  45.216 class WaitConditionImpl : public NewOverrideBase
  45.217 {
  45.218     pthread_mutex_t     SMutex;
  45.219     pthread_cond_t      Condv;
  45.220 
  45.221 public:
  45.222 
  45.223     // Constructor/destructor
  45.224     WaitConditionImpl();
  45.225     ~WaitConditionImpl();
  45.226 
  45.227     // Release mutex and wait for condition. The mutex is re-aqured after the wait.
  45.228     bool    Wait(Mutex *pmutex, unsigned delay = OVR_WAIT_INFINITE);
  45.229 
  45.230     // Notify a condition, releasing at one object waiting
  45.231     void    Notify();
  45.232     // Notify a condition, releasing all objects waiting
  45.233     void    NotifyAll();
  45.234 };
  45.235 
  45.236 
  45.237 WaitConditionImpl::WaitConditionImpl()
  45.238 {
  45.239     pthread_mutex_init(&SMutex, 0);
  45.240     pthread_cond_init(&Condv, 0);
  45.241 }
  45.242 
  45.243 WaitConditionImpl::~WaitConditionImpl()
  45.244 {
  45.245     pthread_mutex_destroy(&SMutex);
  45.246     pthread_cond_destroy(&Condv);
  45.247 }    
  45.248 
  45.249 bool    WaitConditionImpl::Wait(Mutex *pmutex, unsigned delay)
  45.250 {
  45.251     bool            result = 1;
  45.252     unsigned            lockCount = pmutex->pImpl->LockCount;
  45.253 
  45.254     // Mutex must have been locked
  45.255     if (lockCount == 0)
  45.256         return 0;
  45.257 
  45.258     pthread_mutex_lock(&SMutex);
  45.259 
  45.260     // Finally, release a mutex or semaphore
  45.261     if (pmutex->pImpl->Recursive)
  45.262     {
  45.263         // Release the recursive mutex N times
  45.264         pmutex->pImpl->LockCount = 0;
  45.265         for(unsigned i=0; i<lockCount; i++)
  45.266             pthread_mutex_unlock(&pmutex->pImpl->SMutex);
  45.267     }
  45.268     else
  45.269     {
  45.270         pmutex->pImpl->LockCount = 0;
  45.271         pthread_mutex_unlock(&pmutex->pImpl->SMutex);
  45.272     }
  45.273 
  45.274     // Note that there is a gap here between mutex.Unlock() and Wait().
  45.275     // The other mutex protects this gap.
  45.276 
  45.277     if (delay == OVR_WAIT_INFINITE)
  45.278         pthread_cond_wait(&Condv,&SMutex);
  45.279     else
  45.280     {
  45.281         timespec ts;
  45.282 #ifdef OVR_OS_PS3
  45.283         sys_time_sec_t s;
  45.284         sys_time_nsec_t ns;
  45.285         sys_time_get_current_time(&s, &ns);
  45.286 
  45.287         ts.tv_sec = s + (delay / 1000);
  45.288         ts.tv_nsec = ns + (delay % 1000) * 1000000;
  45.289 
  45.290 #else
  45.291         struct timeval tv;
  45.292         gettimeofday(&tv, 0);
  45.293 
  45.294         ts.tv_sec = tv.tv_sec + (delay / 1000);
  45.295         ts.tv_nsec = (tv.tv_usec + (delay % 1000) * 1000) * 1000;
  45.296 #endif
  45.297         if (ts.tv_nsec > 999999999)
  45.298         {
  45.299             ts.tv_sec++;
  45.300             ts.tv_nsec -= 1000000000;
  45.301         }
  45.302         int r = pthread_cond_timedwait(&Condv,&SMutex, &ts);
  45.303         OVR_ASSERT(r == 0 || r == ETIMEDOUT);
  45.304         if (r)
  45.305             result = 0;
  45.306     }
  45.307 
  45.308     pthread_mutex_unlock(&SMutex);
  45.309 
  45.310     // Re-aquire the mutex
  45.311     for(unsigned i=0; i<lockCount; i++)
  45.312         pmutex->DoLock(); 
  45.313 
  45.314     // Return the result
  45.315     return result;
  45.316 }
  45.317 
  45.318 // Notify a condition, releasing the least object in a queue
  45.319 void    WaitConditionImpl::Notify()
  45.320 {
  45.321     pthread_mutex_lock(&SMutex);
  45.322     pthread_cond_signal(&Condv);
  45.323     pthread_mutex_unlock(&SMutex);
  45.324 }
  45.325 
  45.326 // Notify a condition, releasing all objects waiting
  45.327 void    WaitConditionImpl::NotifyAll()
  45.328 {
  45.329     pthread_mutex_lock(&SMutex);
  45.330     pthread_cond_broadcast(&Condv);
  45.331     pthread_mutex_unlock(&SMutex);
  45.332 }
  45.333 
  45.334 
  45.335 
  45.336 // *** Actual implementation of WaitCondition
  45.337 
  45.338 WaitCondition::WaitCondition()
  45.339 {
  45.340     pImpl = new WaitConditionImpl;
  45.341 }
  45.342 WaitCondition::~WaitCondition()
  45.343 {
  45.344     delete pImpl;
  45.345 }
  45.346     
  45.347 bool    WaitCondition::Wait(Mutex *pmutex, unsigned delay)
  45.348 {
  45.349     return pImpl->Wait(pmutex, delay);
  45.350 }
  45.351 // Notification
  45.352 void    WaitCondition::Notify()
  45.353 {
  45.354     pImpl->Notify();
  45.355 }
  45.356 void    WaitCondition::NotifyAll()
  45.357 {
  45.358     pImpl->NotifyAll();
  45.359 }
  45.360 
  45.361 
  45.362 // ***** Current thread
  45.363 
  45.364 // Per-thread variable
  45.365 /*
  45.366 static __thread Thread* pCurrentThread = 0;
  45.367 
  45.368 // Static function to return a pointer to the current thread
  45.369 void    Thread::InitCurrentThread(Thread *pthread)
  45.370 {
  45.371     pCurrentThread = pthread;
  45.372 }
  45.373 
  45.374 // Static function to return a pointer to the current thread
  45.375 Thread*    Thread::GetThread()
  45.376 {
  45.377     return pCurrentThread;
  45.378 }
  45.379 */
  45.380 
  45.381 
  45.382 // *** Thread constructors.
  45.383 
  45.384 Thread::Thread(UPInt stackSize, int processor)
  45.385 {
  45.386     // NOTE: RefCount mode already thread-safe for all Waitable objects.
  45.387     CreateParams params;
  45.388     params.stackSize = stackSize;
  45.389     params.processor = processor;
  45.390     Init(params);
  45.391 }
  45.392 
  45.393 Thread::Thread(Thread::ThreadFn threadFunction, void*  userHandle, UPInt stackSize,
  45.394                  int processor, Thread::ThreadState initialState)
  45.395 {
  45.396     CreateParams params(threadFunction, userHandle, stackSize, processor, initialState);
  45.397     Init(params);
  45.398 }
  45.399 
  45.400 Thread::Thread(const CreateParams& params)
  45.401 {
  45.402     Init(params);
  45.403 }
  45.404 
  45.405 void Thread::Init(const CreateParams& params)
  45.406 {
  45.407     // Clear the variables    
  45.408     ThreadFlags     = 0;
  45.409     ThreadHandle    = 0;
  45.410     ExitCode        = 0;
  45.411     SuspendCount    = 0;
  45.412     StackSize       = params.stackSize;
  45.413     Processor       = params.processor;
  45.414     Priority        = params.priority;
  45.415 
  45.416     // Clear Function pointers
  45.417     ThreadFunction  = params.threadFunction;
  45.418     UserHandle      = params.userHandle;
  45.419     if (params.initialState != NotRunning)
  45.420         Start(params.initialState);
  45.421 }
  45.422 
  45.423 Thread::~Thread()
  45.424 {
  45.425     // Thread should not running while object is being destroyed,
  45.426     // this would indicate ref-counting issue.
  45.427     //OVR_ASSERT(IsRunning() == 0);
  45.428 
  45.429     // Clean up thread.    
  45.430     ThreadHandle = 0;
  45.431 }
  45.432 
  45.433 
  45.434 
  45.435 // *** Overridable User functions.
  45.436 
  45.437 // Default Run implementation
  45.438 int    Thread::Run()
  45.439 {
  45.440     // Call pointer to function, if available.    
  45.441     return (ThreadFunction) ? ThreadFunction(this, UserHandle) : 0;
  45.442 }
  45.443 void    Thread::OnExit()
  45.444 {   
  45.445 }
  45.446 
  45.447 
  45.448 // Finishes the thread and releases internal reference to it.
  45.449 void    Thread::FinishAndRelease()
  45.450 {
  45.451     // Note: thread must be US.
  45.452     ThreadFlags &= (UInt32)~(OVR_THREAD_STARTED);
  45.453     ThreadFlags |= OVR_THREAD_FINISHED;
  45.454 
  45.455     // Release our reference; this is equivalent to 'delete this'
  45.456     // from the point of view of our thread.
  45.457     Release();
  45.458 }
  45.459 
  45.460 
  45.461 
  45.462 // *** ThreadList - used to track all created threads
  45.463 
  45.464 class ThreadList : public NewOverrideBase
  45.465 {
  45.466     //------------------------------------------------------------------------
  45.467     struct ThreadHashOp
  45.468     {
  45.469         size_t operator()(const Thread* ptr)
  45.470         {
  45.471             return (((size_t)ptr) >> 6) ^ (size_t)ptr;
  45.472         }
  45.473     };
  45.474 
  45.475     HashSet<Thread*, ThreadHashOp>        ThreadSet;
  45.476     Mutex                                 ThreadMutex;
  45.477     WaitCondition                         ThreadsEmpty;
  45.478     // Track the root thread that created us.
  45.479     pthread_t                             RootThreadId;
  45.480 
  45.481     static ThreadList* volatile pRunningThreads;
  45.482 
  45.483     void addThread(Thread *pthread)
  45.484     {
  45.485         Mutex::Locker lock(&ThreadMutex);
  45.486         ThreadSet.Add(pthread);
  45.487     }
  45.488 
  45.489     void removeThread(Thread *pthread)
  45.490     {
  45.491         Mutex::Locker lock(&ThreadMutex);
  45.492         ThreadSet.Remove(pthread);
  45.493         if (ThreadSet.GetSize() == 0)
  45.494             ThreadsEmpty.Notify();
  45.495     }
  45.496 
  45.497     void finishAllThreads()
  45.498     {
  45.499         // Only original root thread can call this.
  45.500         OVR_ASSERT(pthread_self() == RootThreadId);
  45.501 
  45.502         Mutex::Locker lock(&ThreadMutex);
  45.503         while (ThreadSet.GetSize() != 0)
  45.504             ThreadsEmpty.Wait(&ThreadMutex);
  45.505     }
  45.506 
  45.507 public:
  45.508 
  45.509     ThreadList()
  45.510     {
  45.511         RootThreadId = pthread_self();
  45.512     }
  45.513     ~ThreadList() { }
  45.514 
  45.515 
  45.516     static void AddRunningThread(Thread *pthread)
  45.517     {
  45.518         // Non-atomic creation ok since only the root thread
  45.519         if (!pRunningThreads)
  45.520         {
  45.521             pRunningThreads = new ThreadList;
  45.522             OVR_ASSERT(pRunningThreads);
  45.523         }
  45.524         pRunningThreads->addThread(pthread);
  45.525     }
  45.526 
  45.527     // NOTE: 'pthread' might be a dead pointer when this is
  45.528     // called so it should not be accessed; it is only used
  45.529     // for removal.
  45.530     static void RemoveRunningThread(Thread *pthread)
  45.531     {
  45.532         OVR_ASSERT(pRunningThreads);        
  45.533         pRunningThreads->removeThread(pthread);
  45.534     }
  45.535 
  45.536     static void FinishAllThreads()
  45.537     {
  45.538         // This is ok because only root thread can wait for other thread finish.
  45.539         if (pRunningThreads)
  45.540         {           
  45.541             pRunningThreads->finishAllThreads();
  45.542             delete pRunningThreads;
  45.543             pRunningThreads = 0;
  45.544         }        
  45.545     }
  45.546 };
  45.547 
  45.548 // By default, we have no thread list.
  45.549 ThreadList* volatile ThreadList::pRunningThreads = 0;
  45.550 
  45.551 
  45.552 // FinishAllThreads - exposed publicly in Thread.
  45.553 void Thread::FinishAllThreads()
  45.554 {
  45.555     ThreadList::FinishAllThreads();
  45.556 }
  45.557 
  45.558 // *** Run override
  45.559 
  45.560 int    Thread::PRun()
  45.561 {
  45.562     // Suspend us on start, if requested
  45.563     if (ThreadFlags & OVR_THREAD_START_SUSPENDED)
  45.564     {
  45.565         Suspend();
  45.566         ThreadFlags &= (UInt32)~OVR_THREAD_START_SUSPENDED;
  45.567     }
  45.568 
  45.569     // Call the virtual run function
  45.570     ExitCode = Run();    
  45.571     return ExitCode;
  45.572 }
  45.573 
  45.574 
  45.575 
  45.576 
  45.577 // *** User overridables
  45.578 
  45.579 bool    Thread::GetExitFlag() const
  45.580 {
  45.581     return (ThreadFlags & OVR_THREAD_EXIT) != 0;
  45.582 }       
  45.583 
  45.584 void    Thread::SetExitFlag(bool exitFlag)
  45.585 {
  45.586     // The below is atomic since ThreadFlags is AtomicInt.
  45.587     if (exitFlag)
  45.588         ThreadFlags |= OVR_THREAD_EXIT;
  45.589     else
  45.590         ThreadFlags &= (UInt32) ~OVR_THREAD_EXIT;
  45.591 }
  45.592 
  45.593 
  45.594 // Determines whether the thread was running and is now finished
  45.595 bool    Thread::IsFinished() const
  45.596 {
  45.597     return (ThreadFlags & OVR_THREAD_FINISHED) != 0;
  45.598 }
  45.599 // Determines whether the thread is suspended
  45.600 bool    Thread::IsSuspended() const
  45.601 {   
  45.602     return SuspendCount > 0;
  45.603 }
  45.604 // Returns current thread state
  45.605 Thread::ThreadState Thread::GetThreadState() const
  45.606 {
  45.607     if (IsSuspended())
  45.608         return Suspended;    
  45.609     if (ThreadFlags & OVR_THREAD_STARTED)
  45.610         return Running;    
  45.611     return NotRunning;
  45.612 }
  45.613 /*
  45.614 static const char* mapsched_policy(int policy)
  45.615 {
  45.616     switch(policy)
  45.617     {
  45.618     case SCHED_OTHER:
  45.619         return "SCHED_OTHER";
  45.620     case SCHED_RR:
  45.621         return "SCHED_RR";
  45.622     case SCHED_FIFO:
  45.623         return "SCHED_FIFO";
  45.624 
  45.625     }
  45.626     return "UNKNOWN";
  45.627 }
  45.628     int policy;
  45.629     sched_param sparam;
  45.630     pthread_getschedparam(pthread_self(), &policy, &sparam);
  45.631     int max_prior = sched_get_priority_max(policy);
  45.632     int min_prior = sched_get_priority_min(policy);
  45.633     printf(" !!!! policy: %s, priority: %d, max priority: %d, min priority: %d\n", mapsched_policy(policy), sparam.sched_priority, max_prior, min_prior);
  45.634 #include <stdio.h>
  45.635 */
  45.636 // ***** Thread management
  45.637 
  45.638 // The actual first function called on thread start
  45.639 void* Thread_PthreadStartFn(void* phandle)
  45.640 {
  45.641     Thread* pthread = (Thread*)phandle;
  45.642     int     result = pthread->PRun();
  45.643     // Signal the thread as done and release it atomically.
  45.644     pthread->FinishAndRelease();
  45.645     // At this point Thread object might be dead; however we can still pass
  45.646     // it to RemoveRunningThread since it is only used as a key there.   
  45.647     ThreadList::RemoveRunningThread(pthread);
  45.648     return (void*) result;
  45.649 }
  45.650 
  45.651 int Thread::InitAttr = 0;
  45.652 pthread_attr_t Thread::Attr; 
  45.653 
  45.654 /* static */
  45.655 int Thread::GetOSPriority(ThreadPriority p)
  45.656 //static inline int MapToSystemPrority(Thread::ThreadPriority p)
  45.657 {
  45.658 #ifdef OVR_OS_PS3 
  45.659     switch(p)
  45.660     {
  45.661     case Thread::CriticalPriority:     return 0;
  45.662     case Thread::HighestPriority:      return 300;
  45.663     case Thread::AboveNormalPriority:  return 600;
  45.664     case Thread::NormalPriority:       return 1000;
  45.665     case Thread::BelowNormalPriority:  return 1500;
  45.666     case Thread::LowestPriority:       return 2500;
  45.667     case Thread::IdlePriority:         return 3071;
  45.668     }                                  return 1000;
  45.669 #else
  45.670     OVR_UNUSED(p);
  45.671     return -1;
  45.672 #endif
  45.673 }
  45.674 
  45.675 bool    Thread::Start(ThreadState initialState)
  45.676 {
  45.677     if (initialState == NotRunning)
  45.678         return 0;
  45.679     if (GetThreadState() != NotRunning)
  45.680     {
  45.681         OVR_DEBUG_LOG(("Thread::Start failed - thread %p already running", this));
  45.682         return 0;
  45.683     }
  45.684 
  45.685     if (!InitAttr)
  45.686     {
  45.687         pthread_attr_init(&Attr);
  45.688         pthread_attr_setdetachstate(&Attr, PTHREAD_CREATE_DETACHED);
  45.689         pthread_attr_setstacksize(&Attr, 128 * 1024);
  45.690         sched_param sparam;
  45.691         sparam.sched_priority = Thread::GetOSPriority(NormalPriority);
  45.692         pthread_attr_setschedparam(&Attr, &sparam);
  45.693         InitAttr = 1;
  45.694     }
  45.695 
  45.696     ExitCode        = 0;
  45.697     SuspendCount    = 0;
  45.698     ThreadFlags     = (initialState == Running) ? 0 : OVR_THREAD_START_SUSPENDED;
  45.699 
  45.700     // AddRef to us until the thread is finished
  45.701     AddRef();
  45.702     ThreadList::AddRunningThread(this);
  45.703 
  45.704     int result;
  45.705     if (StackSize != 128 * 1024 || Priority != NormalPriority)
  45.706     {
  45.707         pthread_attr_t attr;
  45.708 
  45.709         pthread_attr_init(&attr);
  45.710         pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
  45.711         pthread_attr_setstacksize(&attr, StackSize);
  45.712         sched_param sparam;
  45.713         sparam.sched_priority = Thread::GetOSPriority(Priority);
  45.714         pthread_attr_setschedparam(&attr, &sparam);
  45.715         result = pthread_create(&ThreadHandle, &attr, Thread_PthreadStartFn, this);
  45.716         pthread_attr_destroy(&attr);
  45.717     }
  45.718     else
  45.719         result = pthread_create(&ThreadHandle, &Attr, Thread_PthreadStartFn, this);
  45.720 
  45.721     if (result)
  45.722     {
  45.723         ThreadFlags = 0;
  45.724         Release();
  45.725         ThreadList::RemoveRunningThread(this);
  45.726         return 0;
  45.727     }
  45.728     return 1;
  45.729 }
  45.730 
  45.731 
  45.732 // Suspend the thread until resumed
  45.733 bool    Thread::Suspend()
  45.734 {
  45.735     OVR_DEBUG_LOG(("Thread::Suspend - cannot suspend threads on this system"));
  45.736     return 0;
  45.737 }
  45.738 
  45.739 // Resumes currently suspended thread
  45.740 bool    Thread::Resume()
  45.741 {
  45.742     return 0;
  45.743 }
  45.744 
  45.745 
  45.746 // Quits with an exit code  
  45.747 void    Thread::Exit(int exitCode)
  45.748 {
  45.749     // Can only exist the current thread
  45.750    // if (GetThread() != this)
  45.751    //     return;
  45.752 
  45.753     // Call the virtual OnExit function
  45.754     OnExit();   
  45.755 
  45.756     // Signal this thread object as done and release it's references.
  45.757     FinishAndRelease();
  45.758     ThreadList::RemoveRunningThread(this);
  45.759 
  45.760     pthread_exit((void *) exitCode);
  45.761 }
  45.762 
  45.763 ThreadId GetCurrentThreadId()
  45.764 {
  45.765     return (void*)pthread_self();
  45.766 }
  45.767 
  45.768 // *** Sleep functions
  45.769 
  45.770 /* static */
  45.771 bool    Thread::Sleep(unsigned secs)
  45.772 {
  45.773     sleep(secs);
  45.774     return 1;
  45.775 }
  45.776 /* static */
  45.777 bool    Thread::MSleep(unsigned msecs)
  45.778 {
  45.779     usleep(msecs*1000);
  45.780     return 1;
  45.781 }
  45.782 
  45.783 /* static */
  45.784 int     Thread::GetCPUCount()
  45.785 {
  45.786     return 1;
  45.787 }
  45.788 
  45.789 
  45.790 #ifdef OVR_OS_PS3
  45.791 
  45.792 sys_lwmutex_attribute_t Lock::LockAttr = { SYS_SYNC_PRIORITY, SYS_SYNC_RECURSIVE };
  45.793 
  45.794 #endif
  45.795 
  45.796 }
  45.797 
  45.798 #endif  // OVR_ENABLE_THREADS
  45.799 \ No newline at end of file
  45.800 +
  45.801 +#include "OVR_Threads.h"
  45.802 +#include "OVR_Hash.h"
  45.803 +
  45.804 +#ifdef OVR_ENABLE_THREADS
  45.805 +
  45.806 +#include "OVR_Timer.h"
  45.807 +#include "OVR_Log.h"
  45.808 +
  45.809 +#include <pthread.h>
  45.810 +#include <time.h>
  45.811 +
  45.812 +#ifdef OVR_OS_PS3
  45.813 +#include <sys/sys_time.h>
  45.814 +#include <sys/timer.h>
  45.815 +#include <sys/synchronization.h>
  45.816 +#define sleep(x) sys_timer_sleep(x)
  45.817 +#define usleep(x) sys_timer_usleep(x)
  45.818 +using std::timespec;
  45.819 +#else
  45.820 +#include <unistd.h>
  45.821 +#include <sys/time.h>
  45.822 +#include <errno.h>
  45.823 +#endif
  45.824 +
  45.825 +namespace OVR {
  45.826 +
  45.827 +// ***** Mutex implementation
  45.828 +
  45.829 +
  45.830 +// *** Internal Mutex implementation structure
  45.831 +
  45.832 +class MutexImpl : public NewOverrideBase
  45.833 +{
  45.834 +    // System mutex or semaphore
  45.835 +    pthread_mutex_t   SMutex;
  45.836 +    bool          Recursive;
  45.837 +    unsigned      LockCount;
  45.838 +    pthread_t     LockedBy;
  45.839 +
  45.840 +    friend class WaitConditionImpl;
  45.841 +
  45.842 +public:
  45.843 +    // Constructor/destructor
  45.844 +    MutexImpl(Mutex* pmutex, bool recursive = 1);
  45.845 +    ~MutexImpl();
  45.846 +
  45.847 +    // Locking functions
  45.848 +    void                DoLock();
  45.849 +    bool                TryLock();
  45.850 +    void                Unlock(Mutex* pmutex);
  45.851 +    // Returns 1 if the mutes is currently locked
  45.852 +    bool                IsLockedByAnotherThread(Mutex* pmutex);        
  45.853 +    bool                IsSignaled() const;
  45.854 +};
  45.855 +
  45.856 +pthread_mutexattr_t Lock::RecursiveAttr;
  45.857 +bool Lock::RecursiveAttrInit = 0;
  45.858 +
  45.859 +// *** Constructor/destructor
  45.860 +MutexImpl::MutexImpl(Mutex* pmutex, bool recursive)
  45.861 +{   
  45.862 +    Recursive           = recursive;
  45.863 +    LockCount           = 0;
  45.864 +
  45.865 +    if (Recursive)
  45.866 +    {
  45.867 +        if (!Lock::RecursiveAttrInit)
  45.868 +        {
  45.869 +            pthread_mutexattr_init(&Lock::RecursiveAttr);
  45.870 +            pthread_mutexattr_settype(&Lock::RecursiveAttr, PTHREAD_MUTEX_RECURSIVE);
  45.871 +            Lock::RecursiveAttrInit = 1;
  45.872 +        }
  45.873 +
  45.874 +        pthread_mutex_init(&SMutex, &Lock::RecursiveAttr);
  45.875 +    }
  45.876 +    else
  45.877 +        pthread_mutex_init(&SMutex, 0);
  45.878 +}
  45.879 +
  45.880 +MutexImpl::~MutexImpl()
  45.881 +{
  45.882 +    pthread_mutex_destroy(&SMutex);
  45.883 +}
  45.884 +
  45.885 +
  45.886 +// Lock and try lock
  45.887 +void MutexImpl::DoLock()
  45.888 +{
  45.889 +    while (pthread_mutex_lock(&SMutex));
  45.890 +    LockCount++;
  45.891 +    LockedBy = pthread_self();
  45.892 +}
  45.893 +
  45.894 +bool MutexImpl::TryLock()
  45.895 +{
  45.896 +    if (!pthread_mutex_trylock(&SMutex))
  45.897 +    {
  45.898 +        LockCount++;
  45.899 +        LockedBy = pthread_self();
  45.900 +        return 1;
  45.901 +    }
  45.902 +    
  45.903 +    return 0;
  45.904 +}
  45.905 +
  45.906 +void MutexImpl::Unlock(Mutex* pmutex)
  45.907 +{
  45.908 +    OVR_ASSERT(pthread_self() == LockedBy && LockCount > 0);
  45.909 +
  45.910 +    unsigned lockCount;
  45.911 +    LockCount--;
  45.912 +    lockCount = LockCount;
  45.913 +
  45.914 +    pthread_mutex_unlock(&SMutex);
  45.915 +}
  45.916 +
  45.917 +bool    MutexImpl::IsLockedByAnotherThread(Mutex* pmutex)
  45.918 +{
  45.919 +    // There could be multiple interpretations of IsLocked with respect to current thread
  45.920 +    if (LockCount == 0)
  45.921 +        return 0;
  45.922 +    if (pthread_self() != LockedBy)
  45.923 +        return 1;
  45.924 +    return 0;
  45.925 +}
  45.926 +
  45.927 +bool    MutexImpl::IsSignaled() const
  45.928 +{
  45.929 +    // An mutex is signaled if it is not locked ANYWHERE
  45.930 +    // Note that this is different from IsLockedByAnotherThread function,
  45.931 +    // that takes current thread into account
  45.932 +    return LockCount == 0;
  45.933 +}
  45.934 +
  45.935 +
  45.936 +// *** Actual Mutex class implementation
  45.937 +
  45.938 +Mutex::Mutex(bool recursive)
  45.939 +{
  45.940 +    // NOTE: RefCount mode already thread-safe for all waitables.
  45.941 +    pImpl = new MutexImpl(this, recursive);
  45.942 +}
  45.943 +
  45.944 +Mutex::~Mutex()
  45.945 +{
  45.946 +    delete pImpl;
  45.947 +}
  45.948 +
  45.949 +// Lock and try lock
  45.950 +void Mutex::DoLock()
  45.951 +{
  45.952 +    pImpl->DoLock();
  45.953 +}
  45.954 +bool Mutex::TryLock()
  45.955 +{
  45.956 +    return pImpl->TryLock();
  45.957 +}
  45.958 +void Mutex::Unlock()
  45.959 +{
  45.960 +    pImpl->Unlock(this);
  45.961 +}
  45.962 +bool    Mutex::IsLockedByAnotherThread()
  45.963 +{
  45.964 +    return pImpl->IsLockedByAnotherThread(this);
  45.965 +}
  45.966 +
  45.967 +
  45.968 +
  45.969 +//-----------------------------------------------------------------------------------
  45.970 +// ***** Event
  45.971 +
  45.972 +bool Event::Wait(unsigned delay)
  45.973 +{
  45.974 +    Mutex::Locker lock(&StateMutex);
  45.975 +
  45.976 +    // Do the correct amount of waiting
  45.977 +    if (delay == OVR_WAIT_INFINITE)
  45.978 +    {
  45.979 +        while(!State)
  45.980 +            StateWaitCondition.Wait(&StateMutex);
  45.981 +    }
  45.982 +    else if (delay)
  45.983 +    {
  45.984 +        if (!State)
  45.985 +            StateWaitCondition.Wait(&StateMutex, delay);
  45.986 +    }
  45.987 +
  45.988 +    bool state = State;
  45.989 +    // Take care of temporary 'pulsing' of a state
  45.990 +    if (Temporary)
  45.991 +    {
  45.992 +        Temporary   = false;
  45.993 +        State       = false;
  45.994 +    }
  45.995 +    return state;
  45.996 +}
  45.997 +
  45.998 +void Event::updateState(bool newState, bool newTemp, bool mustNotify)
  45.999 +{
 45.1000 +    Mutex::Locker lock(&StateMutex);
 45.1001 +    State       = newState;
 45.1002 +    Temporary   = newTemp;
 45.1003 +    if (mustNotify)
 45.1004 +        StateWaitCondition.NotifyAll();    
 45.1005 +}
 45.1006 +
 45.1007 +
 45.1008 +
 45.1009 +// ***** Wait Condition Implementation
 45.1010 +
 45.1011 +// Internal implementation class
 45.1012 +class WaitConditionImpl : public NewOverrideBase
 45.1013 +{
 45.1014 +    pthread_mutex_t     SMutex;
 45.1015 +    pthread_cond_t      Condv;
 45.1016 +
 45.1017 +public:
 45.1018 +
 45.1019 +    // Constructor/destructor
 45.1020 +    WaitConditionImpl();
 45.1021 +    ~WaitConditionImpl();
 45.1022 +
 45.1023 +    // Release mutex and wait for condition. The mutex is re-aqured after the wait.
 45.1024 +    bool    Wait(Mutex *pmutex, unsigned delay = OVR_WAIT_INFINITE);
 45.1025 +
 45.1026 +    // Notify a condition, releasing at one object waiting
 45.1027 +    void    Notify();
 45.1028 +    // Notify a condition, releasing all objects waiting
 45.1029 +    void    NotifyAll();
 45.1030 +};
 45.1031 +
 45.1032 +
 45.1033 +WaitConditionImpl::WaitConditionImpl()
 45.1034 +{
 45.1035 +    pthread_mutex_init(&SMutex, 0);
 45.1036 +    pthread_cond_init(&Condv, 0);
 45.1037 +}
 45.1038 +
 45.1039 +WaitConditionImpl::~WaitConditionImpl()
 45.1040 +{
 45.1041 +    pthread_mutex_destroy(&SMutex);
 45.1042 +    pthread_cond_destroy(&Condv);
 45.1043 +}    
 45.1044 +
 45.1045 +bool    WaitConditionImpl::Wait(Mutex *pmutex, unsigned delay)
 45.1046 +{
 45.1047 +    bool            result = 1;
 45.1048 +    unsigned            lockCount = pmutex->pImpl->LockCount;
 45.1049 +
 45.1050 +    // Mutex must have been locked
 45.1051 +    if (lockCount == 0)
 45.1052 +        return 0;
 45.1053 +
 45.1054 +    pthread_mutex_lock(&SMutex);
 45.1055 +
 45.1056 +    // Finally, release a mutex or semaphore
 45.1057 +    if (pmutex->pImpl->Recursive)
 45.1058 +    {
 45.1059 +        // Release the recursive mutex N times
 45.1060 +        pmutex->pImpl->LockCount = 0;
 45.1061 +        for(unsigned i=0; i<lockCount; i++)
 45.1062 +            pthread_mutex_unlock(&pmutex->pImpl->SMutex);
 45.1063 +    }
 45.1064 +    else
 45.1065 +    {
 45.1066 +        pmutex->pImpl->LockCount = 0;
 45.1067 +        pthread_mutex_unlock(&pmutex->pImpl->SMutex);
 45.1068 +    }
 45.1069 +
 45.1070 +    // Note that there is a gap here between mutex.Unlock() and Wait().
 45.1071 +    // The other mutex protects this gap.
 45.1072 +
 45.1073 +    if (delay == OVR_WAIT_INFINITE)
 45.1074 +        pthread_cond_wait(&Condv,&SMutex);
 45.1075 +    else
 45.1076 +    {
 45.1077 +        timespec ts;
 45.1078 +#ifdef OVR_OS_PS3
 45.1079 +        sys_time_sec_t s;
 45.1080 +        sys_time_nsec_t ns;
 45.1081 +        sys_time_get_current_time(&s, &ns);
 45.1082 +
 45.1083 +        ts.tv_sec = s + (delay / 1000);
 45.1084 +        ts.tv_nsec = ns + (delay % 1000) * 1000000;
 45.1085 +
 45.1086 +#else
 45.1087 +        struct timeval tv;
 45.1088 +        gettimeofday(&tv, 0);
 45.1089 +
 45.1090 +        ts.tv_sec = tv.tv_sec + (delay / 1000);
 45.1091 +        ts.tv_nsec = (tv.tv_usec + (delay % 1000) * 1000) * 1000;
 45.1092 +#endif
 45.1093 +        if (ts.tv_nsec > 999999999)
 45.1094 +        {
 45.1095 +            ts.tv_sec++;
 45.1096 +            ts.tv_nsec -= 1000000000;
 45.1097 +        }
 45.1098 +        int r = pthread_cond_timedwait(&Condv,&SMutex, &ts);
 45.1099 +        OVR_ASSERT(r == 0 || r == ETIMEDOUT);
 45.1100 +        if (r)
 45.1101 +            result = 0;
 45.1102 +    }
 45.1103 +
 45.1104 +    pthread_mutex_unlock(&SMutex);
 45.1105 +
 45.1106 +    // Re-aquire the mutex
 45.1107 +    for(unsigned i=0; i<lockCount; i++)
 45.1108 +        pmutex->DoLock(); 
 45.1109 +
 45.1110 +    // Return the result
 45.1111 +    return result;
 45.1112 +}
 45.1113 +
 45.1114 +// Notify a condition, releasing the least object in a queue
 45.1115 +void    WaitConditionImpl::Notify()
 45.1116 +{
 45.1117 +    pthread_mutex_lock(&SMutex);
 45.1118 +    pthread_cond_signal(&Condv);
 45.1119 +    pthread_mutex_unlock(&SMutex);
 45.1120 +}
 45.1121 +
 45.1122 +// Notify a condition, releasing all objects waiting
 45.1123 +void    WaitConditionImpl::NotifyAll()
 45.1124 +{
 45.1125 +    pthread_mutex_lock(&SMutex);
 45.1126 +    pthread_cond_broadcast(&Condv);
 45.1127 +    pthread_mutex_unlock(&SMutex);
 45.1128 +}
 45.1129 +
 45.1130 +
 45.1131 +
 45.1132 +// *** Actual implementation of WaitCondition
 45.1133 +
 45.1134 +WaitCondition::WaitCondition()
 45.1135 +{
 45.1136 +    pImpl = new WaitConditionImpl;
 45.1137 +}
 45.1138 +WaitCondition::~WaitCondition()
 45.1139 +{
 45.1140 +    delete pImpl;
 45.1141 +}
 45.1142 +    
 45.1143 +bool    WaitCondition::Wait(Mutex *pmutex, unsigned delay)
 45.1144 +{
 45.1145 +    return pImpl->Wait(pmutex, delay);
 45.1146 +}
 45.1147 +// Notification
 45.1148 +void    WaitCondition::Notify()
 45.1149 +{
 45.1150 +    pImpl->Notify();
 45.1151 +}
 45.1152 +void    WaitCondition::NotifyAll()
 45.1153 +{
 45.1154 +    pImpl->NotifyAll();
 45.1155 +}
 45.1156 +
 45.1157 +
 45.1158 +// ***** Current thread
 45.1159 +
 45.1160 +// Per-thread variable
 45.1161 +/*
 45.1162 +static __thread Thread* pCurrentThread = 0;
 45.1163 +
 45.1164 +// Static function to return a pointer to the current thread
 45.1165 +void    Thread::InitCurrentThread(Thread *pthread)
 45.1166 +{
 45.1167 +    pCurrentThread = pthread;
 45.1168 +}
 45.1169 +
 45.1170 +// Static function to return a pointer to the current thread
 45.1171 +Thread*    Thread::GetThread()
 45.1172 +{
 45.1173 +    return pCurrentThread;
 45.1174 +}
 45.1175 +*/
 45.1176 +
 45.1177 +
 45.1178 +// *** Thread constructors.
 45.1179 +
 45.1180 +Thread::Thread(UPInt stackSize, int processor)
 45.1181 +{
 45.1182 +    // NOTE: RefCount mode already thread-safe for all Waitable objects.
 45.1183 +    CreateParams params;
 45.1184 +    params.stackSize = stackSize;
 45.1185 +    params.processor = processor;
 45.1186 +    Init(params);
 45.1187 +}
 45.1188 +
 45.1189 +Thread::Thread(Thread::ThreadFn threadFunction, void*  userHandle, UPInt stackSize,
 45.1190 +                 int processor, Thread::ThreadState initialState)
 45.1191 +{
 45.1192 +    CreateParams params(threadFunction, userHandle, stackSize, processor, initialState);
 45.1193 +    Init(params);
 45.1194 +}
 45.1195 +
 45.1196 +Thread::Thread(const CreateParams& params)
 45.1197 +{
 45.1198 +    Init(params);
 45.1199 +}
 45.1200 +
 45.1201 +void Thread::Init(const CreateParams& params)
 45.1202 +{
 45.1203 +    // Clear the variables    
 45.1204 +    ThreadFlags     = 0;
 45.1205 +    ThreadHandle    = 0;
 45.1206 +    ExitCode        = 0;
 45.1207 +    SuspendCount    = 0;
 45.1208 +    StackSize       = params.stackSize;
 45.1209 +    Processor       = params.processor;
 45.1210 +    Priority        = params.priority;
 45.1211 +
 45.1212 +    // Clear Function pointers
 45.1213 +    ThreadFunction  = params.threadFunction;
 45.1214 +    UserHandle      = params.userHandle;
 45.1215 +    if (params.initialState != NotRunning)
 45.1216 +        Start(params.initialState);
 45.1217 +}
 45.1218 +
 45.1219 +Thread::~Thread()
 45.1220 +{
 45.1221 +    // Thread should not running while object is being destroyed,
 45.1222 +    // this would indicate ref-counting issue.
 45.1223 +    //OVR_ASSERT(IsRunning() == 0);
 45.1224 +
 45.1225 +    // Clean up thread.    
 45.1226 +    ThreadHandle = 0;
 45.1227 +}
 45.1228 +
 45.1229 +
 45.1230 +
 45.1231 +// *** Overridable User functions.
 45.1232 +
 45.1233 +// Default Run implementation
 45.1234 +int    Thread::Run()
 45.1235 +{
 45.1236 +    // Call pointer to function, if available.    
 45.1237 +    return (ThreadFunction) ? ThreadFunction(this, UserHandle) : 0;
 45.1238 +}
 45.1239 +void    Thread::OnExit()
 45.1240 +{   
 45.1241 +}
 45.1242 +
 45.1243 +
 45.1244 +// Finishes the thread and releases internal reference to it.
 45.1245 +void    Thread::FinishAndRelease()
 45.1246 +{
 45.1247 +    // Note: thread must be US.
 45.1248 +    ThreadFlags &= (UInt32)~(OVR_THREAD_STARTED);
 45.1249 +    ThreadFlags |= OVR_THREAD_FINISHED;
 45.1250 +
 45.1251 +    // Release our reference; this is equivalent to 'delete this'
 45.1252 +    // from the point of view of our thread.
 45.1253 +    Release();
 45.1254 +}
 45.1255 +
 45.1256 +
 45.1257 +
 45.1258 +// *** ThreadList - used to track all created threads
 45.1259 +
 45.1260 +class ThreadList : public NewOverrideBase
 45.1261 +{
 45.1262 +    //------------------------------------------------------------------------
 45.1263 +    struct ThreadHashOp
 45.1264 +    {
 45.1265 +        size_t operator()(const Thread* ptr)
 45.1266 +        {
 45.1267 +            return (((size_t)ptr) >> 6) ^ (size_t)ptr;
 45.1268 +        }
 45.1269 +    };
 45.1270 +
 45.1271 +    HashSet<Thread*, ThreadHashOp>        ThreadSet;
 45.1272 +    Mutex                                 ThreadMutex;
 45.1273 +    WaitCondition                         ThreadsEmpty;
 45.1274 +    // Track the root thread that created us.
 45.1275 +    pthread_t                             RootThreadId;
 45.1276 +
 45.1277 +    static ThreadList* volatile pRunningThreads;
 45.1278 +
 45.1279 +    void addThread(Thread *pthread)
 45.1280 +    {
 45.1281 +        Mutex::Locker lock(&ThreadMutex);
 45.1282 +        ThreadSet.Add(pthread);
 45.1283 +    }
 45.1284 +
 45.1285 +    void removeThread(Thread *pthread)
 45.1286 +    {
 45.1287 +        Mutex::Locker lock(&ThreadMutex);
 45.1288 +        ThreadSet.Remove(pthread);
 45.1289 +        if (ThreadSet.GetSize() == 0)
 45.1290 +            ThreadsEmpty.Notify();
 45.1291 +    }
 45.1292 +
 45.1293 +    void finishAllThreads()
 45.1294 +    {
 45.1295 +        // Only original root thread can call this.
 45.1296 +        OVR_ASSERT(pthread_self() == RootThreadId);
 45.1297 +
 45.1298 +        Mutex::Locker lock(&ThreadMutex);
 45.1299 +        while (ThreadSet.GetSize() != 0)
 45.1300 +            ThreadsEmpty.Wait(&ThreadMutex);
 45.1301 +    }
 45.1302 +
 45.1303 +public:
 45.1304 +
 45.1305 +    ThreadList()
 45.1306 +    {
 45.1307 +        RootThreadId = pthread_self();
 45.1308 +    }
 45.1309 +    ~ThreadList() { }
 45.1310 +
 45.1311 +
 45.1312 +    static void AddRunningThread(Thread *pthread)
 45.1313 +    {
 45.1314 +        // Non-atomic creation ok since only the root thread
 45.1315 +        if (!pRunningThreads)
 45.1316 +        {
 45.1317 +            pRunningThreads = new ThreadList;
 45.1318 +            OVR_ASSERT(pRunningThreads);
 45.1319 +        }
 45.1320 +        pRunningThreads->addThread(pthread);
 45.1321 +    }
 45.1322 +
 45.1323 +    // NOTE: 'pthread' might be a dead pointer when this is
 45.1324 +    // called so it should not be accessed; it is only used
 45.1325 +    // for removal.
 45.1326 +    static void RemoveRunningThread(Thread *pthread)
 45.1327 +    {
 45.1328 +        OVR_ASSERT(pRunningThreads);        
 45.1329 +        pRunningThreads->removeThread(pthread);
 45.1330 +    }
 45.1331 +
 45.1332 +    static void FinishAllThreads()
 45.1333 +    {
 45.1334 +        // This is ok because only root thread can wait for other thread finish.
 45.1335 +        if (pRunningThreads)
 45.1336 +        {           
 45.1337 +            pRunningThreads->finishAllThreads();
 45.1338 +            delete pRunningThreads;
 45.1339 +            pRunningThreads = 0;
 45.1340 +        }        
 45.1341 +    }
 45.1342 +};
 45.1343 +
 45.1344 +// By default, we have no thread list.
 45.1345 +ThreadList* volatile ThreadList::pRunningThreads = 0;
 45.1346 +
 45.1347 +
 45.1348 +// FinishAllThreads - exposed publicly in Thread.
 45.1349 +void Thread::FinishAllThreads()
 45.1350 +{
 45.1351 +    ThreadList::FinishAllThreads();
 45.1352 +}
 45.1353 +
 45.1354 +// *** Run override
 45.1355 +
 45.1356 +int    Thread::PRun()
 45.1357 +{
 45.1358 +    // Suspend us on start, if requested
 45.1359 +    if (ThreadFlags & OVR_THREAD_START_SUSPENDED)
 45.1360 +    {
 45.1361 +        Suspend();
 45.1362 +        ThreadFlags &= (UInt32)~OVR_THREAD_START_SUSPENDED;
 45.1363 +    }
 45.1364 +
 45.1365 +    // Call the virtual run function
 45.1366 +    ExitCode = Run();    
 45.1367 +    return ExitCode;
 45.1368 +}
 45.1369 +
 45.1370 +
 45.1371 +
 45.1372 +
 45.1373 +// *** User overridables
 45.1374 +
 45.1375 +bool    Thread::GetExitFlag() const
 45.1376 +{
 45.1377 +    return (ThreadFlags & OVR_THREAD_EXIT) != 0;
 45.1378 +}       
 45.1379 +
 45.1380 +void    Thread::SetExitFlag(bool exitFlag)
 45.1381 +{
 45.1382 +    // The below is atomic since ThreadFlags is AtomicInt.
 45.1383 +    if (exitFlag)
 45.1384 +        ThreadFlags |= OVR_THREAD_EXIT;
 45.1385 +    else
 45.1386 +        ThreadFlags &= (UInt32) ~OVR_THREAD_EXIT;
 45.1387 +}
 45.1388 +
 45.1389 +
 45.1390 +// Determines whether the thread was running and is now finished
 45.1391 +bool    Thread::IsFinished() const
 45.1392 +{
 45.1393 +    return (ThreadFlags & OVR_THREAD_FINISHED) != 0;
 45.1394 +}
 45.1395 +// Determines whether the thread is suspended
 45.1396 +bool    Thread::IsSuspended() const
 45.1397 +{   
 45.1398 +    return SuspendCount > 0;
 45.1399 +}
 45.1400 +// Returns current thread state
 45.1401 +Thread::ThreadState Thread::GetThreadState() const
 45.1402 +{
 45.1403 +    if (IsSuspended())
 45.1404 +        return Suspended;    
 45.1405 +    if (ThreadFlags & OVR_THREAD_STARTED)
 45.1406 +        return Running;    
 45.1407 +    return NotRunning;
 45.1408 +}
 45.1409 +/*
 45.1410 +static const char* mapsched_policy(int policy)
 45.1411 +{
 45.1412 +    switch(policy)
 45.1413 +    {
 45.1414 +    case SCHED_OTHER:
 45.1415 +        return "SCHED_OTHER";
 45.1416 +    case SCHED_RR:
 45.1417 +        return "SCHED_RR";
 45.1418 +    case SCHED_FIFO:
 45.1419 +        return "SCHED_FIFO";
 45.1420 +
 45.1421 +    }
 45.1422 +    return "UNKNOWN";
 45.1423 +}
 45.1424 +    int policy;
 45.1425 +    sched_param sparam;
 45.1426 +    pthread_getschedparam(pthread_self(), &policy, &sparam);
 45.1427 +    int max_prior = sched_get_priority_max(policy);
 45.1428 +    int min_prior = sched_get_priority_min(policy);
 45.1429 +    printf(" !!!! policy: %s, priority: %d, max priority: %d, min priority: %d\n", mapsched_policy(policy), sparam.sched_priority, max_prior, min_prior);
 45.1430 +#include <stdio.h>
 45.1431 +*/
 45.1432 +// ***** Thread management
 45.1433 +
 45.1434 +// The actual first function called on thread start
 45.1435 +void* Thread_PthreadStartFn(void* phandle)
 45.1436 +{
 45.1437 +    Thread* pthread = (Thread*)phandle;
 45.1438 +    int     result = pthread->PRun();
 45.1439 +    // Signal the thread as done and release it atomically.
 45.1440 +    pthread->FinishAndRelease();
 45.1441 +    // At this point Thread object might be dead; however we can still pass
 45.1442 +    // it to RemoveRunningThread since it is only used as a key there.   
 45.1443 +    ThreadList::RemoveRunningThread(pthread);
 45.1444 +    return (void*) result;
 45.1445 +}
 45.1446 +
 45.1447 +int Thread::InitAttr = 0;
 45.1448 +pthread_attr_t Thread::Attr; 
 45.1449 +
 45.1450 +/* static */
 45.1451 +int Thread::GetOSPriority(ThreadPriority p)
 45.1452 +//static inline int MapToSystemPrority(Thread::ThreadPriority p)
 45.1453 +{
 45.1454 +#ifdef OVR_OS_PS3 
 45.1455 +    switch(p)
 45.1456 +    {
 45.1457 +    case Thread::CriticalPriority:     return 0;
 45.1458 +    case Thread::HighestPriority:      return 300;
 45.1459 +    case Thread::AboveNormalPriority:  return 600;
 45.1460 +    case Thread::NormalPriority:       return 1000;
 45.1461 +    case Thread::BelowNormalPriority:  return 1500;
 45.1462 +    case Thread::LowestPriority:       return 2500;
 45.1463 +    case Thread::IdlePriority:         return 3071;
 45.1464 +    }                                  return 1000;
 45.1465 +#else
 45.1466 +    OVR_UNUSED(p);
 45.1467 +    return -1;
 45.1468 +#endif
 45.1469 +}
 45.1470 +
 45.1471 +bool    Thread::Start(ThreadState initialState)
 45.1472 +{
 45.1473 +    if (initialState == NotRunning)
 45.1474 +        return 0;
 45.1475 +    if (GetThreadState() != NotRunning)
 45.1476 +    {
 45.1477 +        OVR_DEBUG_LOG(("Thread::Start failed - thread %p already running", this));
 45.1478 +        return 0;
 45.1479 +    }
 45.1480 +
 45.1481 +    if (!InitAttr)
 45.1482 +    {
 45.1483 +        pthread_attr_init(&Attr);
 45.1484 +        pthread_attr_setdetachstate(&Attr, PTHREAD_CREATE_DETACHED);
 45.1485 +        pthread_attr_setstacksize(&Attr, 128 * 1024);
 45.1486 +        sched_param sparam;
 45.1487 +        sparam.sched_priority = Thread::GetOSPriority(NormalPriority);
 45.1488 +        pthread_attr_setschedparam(&Attr, &sparam);
 45.1489 +        InitAttr = 1;
 45.1490 +    }
 45.1491 +
 45.1492 +    ExitCode        = 0;
 45.1493 +    SuspendCount    = 0;
 45.1494 +    ThreadFlags     = (initialState == Running) ? 0 : OVR_THREAD_START_SUSPENDED;
 45.1495 +
 45.1496 +    // AddRef to us until the thread is finished
 45.1497 +    AddRef();
 45.1498 +    ThreadList::AddRunningThread(this);
 45.1499 +
 45.1500 +    int result;
 45.1501 +    if (StackSize != 128 * 1024 || Priority != NormalPriority)
 45.1502 +    {
 45.1503 +        pthread_attr_t attr;
 45.1504 +
 45.1505 +        pthread_attr_init(&attr);
 45.1506 +        pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
 45.1507 +        pthread_attr_setstacksize(&attr, StackSize);
 45.1508 +        sched_param sparam;
 45.1509 +        sparam.sched_priority = Thread::GetOSPriority(Priority);
 45.1510 +        pthread_attr_setschedparam(&attr, &sparam);
 45.1511 +        result = pthread_create(&ThreadHandle, &attr, Thread_PthreadStartFn, this);
 45.1512 +        pthread_attr_destroy(&attr);
 45.1513 +    }
 45.1514 +    else
 45.1515 +        result = pthread_create(&ThreadHandle, &Attr, Thread_PthreadStartFn, this);
 45.1516 +
 45.1517 +    if (result)
 45.1518 +    {
 45.1519 +        ThreadFlags = 0;
 45.1520 +        Release();
 45.1521 +        ThreadList::RemoveRunningThread(this);
 45.1522 +        return 0;
 45.1523 +    }
 45.1524 +    return 1;
 45.1525 +}
 45.1526 +
 45.1527 +
 45.1528 +// Suspend the thread until resumed
 45.1529 +bool    Thread::Suspend()
 45.1530 +{
 45.1531 +    OVR_DEBUG_LOG(("Thread::Suspend - cannot suspend threads on this system"));
 45.1532 +    return 0;
 45.1533 +}
 45.1534 +
 45.1535 +// Resumes currently suspended thread
 45.1536 +bool    Thread::Resume()
 45.1537 +{
 45.1538 +    return 0;
 45.1539 +}
 45.1540 +
 45.1541 +
 45.1542 +// Quits with an exit code  
 45.1543 +void    Thread::Exit(int exitCode)
 45.1544 +{
 45.1545 +    // Can only exist the current thread
 45.1546 +   // if (GetThread() != this)
 45.1547 +   //     return;
 45.1548 +
 45.1549 +    // Call the virtual OnExit function
 45.1550 +    OnExit();   
 45.1551 +
 45.1552 +    // Signal this thread object as done and release it's references.
 45.1553 +    FinishAndRelease();
 45.1554 +    ThreadList::RemoveRunningThread(this);
 45.1555 +
 45.1556 +    pthread_exit((void *) exitCode);
 45.1557 +}
 45.1558 +
 45.1559 +ThreadId GetCurrentThreadId()
 45.1560 +{
 45.1561 +    return (void*)pthread_self();
 45.1562 +}
 45.1563 +
 45.1564 +// *** Sleep functions
 45.1565 +
 45.1566 +/* static */
 45.1567 +bool    Thread::Sleep(unsigned secs)
 45.1568 +{
 45.1569 +    sleep(secs);
 45.1570 +    return 1;
 45.1571 +}
 45.1572 +/* static */
 45.1573 +bool    Thread::MSleep(unsigned msecs)
 45.1574 +{
 45.1575 +    usleep(msecs*1000);
 45.1576 +    return 1;
 45.1577 +}
 45.1578 +
 45.1579 +/* static */
 45.1580 +int     Thread::GetCPUCount()
 45.1581 +{
 45.1582 +    return 1;
 45.1583 +}
 45.1584 +
 45.1585 +
 45.1586 +#ifdef OVR_OS_PS3
 45.1587 +
 45.1588 +sys_lwmutex_attribute_t Lock::LockAttr = { SYS_SYNC_PRIORITY, SYS_SYNC_RECURSIVE };
 45.1589 +
 45.1590 +#endif
 45.1591 +
 45.1592 +}
 45.1593 +
 45.1594 +#endif  // OVR_ENABLE_THREADS
    46.1 --- a/libovr/Src/osx/OVR_ThreadsPthread.cpp	Sat Sep 14 17:51:03 2013 +0300
    46.2 +++ b/libovr/Src/osx/OVR_ThreadsPthread.cpp	Sun Sep 15 04:10:05 2013 +0300
    46.3 @@ -1,1 +1,795 @@
    46.4 -
    46.5 #include "OVR_Threads.h"
    46.6 #include "OVR_Hash.h"
    46.7 
    46.8 #ifdef OVR_ENABLE_THREADS
    46.9 
   46.10 #include "OVR_Timer.h"
   46.11 #include "OVR_Log.h"
   46.12 
   46.13 #include <pthread.h>
   46.14 #include <time.h>
   46.15 
   46.16 #ifdef OVR_OS_PS3
   46.17 #include <sys/sys_time.h>
   46.18 #include <sys/timer.h>
   46.19 #include <sys/synchronization.h>
   46.20 #define sleep(x) sys_timer_sleep(x)
   46.21 #define usleep(x) sys_timer_usleep(x)
   46.22 using std::timespec;
   46.23 #else
   46.24 #include <unistd.h>
   46.25 #include <sys/time.h>
   46.26 #include <errno.h>
   46.27 #endif
   46.28 
   46.29 namespace OVR {
   46.30 
   46.31 // ***** Mutex implementation
   46.32 
   46.33 
   46.34 // *** Internal Mutex implementation structure
   46.35 
   46.36 class MutexImpl : public NewOverrideBase
   46.37 {
   46.38     // System mutex or semaphore
   46.39     pthread_mutex_t   SMutex;
   46.40     bool          Recursive;
   46.41     unsigned      LockCount;
   46.42     pthread_t     LockedBy;
   46.43 
   46.44     friend class WaitConditionImpl;
   46.45 
   46.46 public:
   46.47     // Constructor/destructor
   46.48     MutexImpl(Mutex* pmutex, bool recursive = 1);
   46.49     ~MutexImpl();
   46.50 
   46.51     // Locking functions
   46.52     void                DoLock();
   46.53     bool                TryLock();
   46.54     void                Unlock(Mutex* pmutex);
   46.55     // Returns 1 if the mutes is currently locked
   46.56     bool                IsLockedByAnotherThread(Mutex* pmutex);        
   46.57     bool                IsSignaled() const;
   46.58 };
   46.59 
   46.60 pthread_mutexattr_t Lock::RecursiveAttr;
   46.61 bool Lock::RecursiveAttrInit = 0;
   46.62 
   46.63 // *** Constructor/destructor
   46.64 MutexImpl::MutexImpl(Mutex* pmutex, bool recursive)
   46.65 {   
   46.66     Recursive           = recursive;
   46.67     LockCount           = 0;
   46.68 
   46.69     if (Recursive)
   46.70     {
   46.71         if (!Lock::RecursiveAttrInit)
   46.72         {
   46.73             pthread_mutexattr_init(&Lock::RecursiveAttr);
   46.74             pthread_mutexattr_settype(&Lock::RecursiveAttr, PTHREAD_MUTEX_RECURSIVE);
   46.75             Lock::RecursiveAttrInit = 1;
   46.76         }
   46.77 
   46.78         pthread_mutex_init(&SMutex, &Lock::RecursiveAttr);
   46.79     }
   46.80     else
   46.81         pthread_mutex_init(&SMutex, 0);
   46.82 }
   46.83 
   46.84 MutexImpl::~MutexImpl()
   46.85 {
   46.86     pthread_mutex_destroy(&SMutex);
   46.87 }
   46.88 
   46.89 
   46.90 // Lock and try lock
   46.91 void MutexImpl::DoLock()
   46.92 {
   46.93     while (pthread_mutex_lock(&SMutex));
   46.94     LockCount++;
   46.95     LockedBy = pthread_self();
   46.96 }
   46.97 
   46.98 bool MutexImpl::TryLock()
   46.99 {
  46.100     if (!pthread_mutex_trylock(&SMutex))
  46.101     {
  46.102         LockCount++;
  46.103         LockedBy = pthread_self();
  46.104         return 1;
  46.105     }
  46.106     
  46.107     return 0;
  46.108 }
  46.109 
  46.110 void MutexImpl::Unlock(Mutex* pmutex)
  46.111 {
  46.112     OVR_ASSERT(pthread_self() == LockedBy && LockCount > 0);
  46.113 
  46.114     unsigned lockCount;
  46.115     LockCount--;
  46.116     lockCount = LockCount;
  46.117 
  46.118     pthread_mutex_unlock(&SMutex);
  46.119 }
  46.120 
  46.121 bool    MutexImpl::IsLockedByAnotherThread(Mutex* pmutex)
  46.122 {
  46.123     // There could be multiple interpretations of IsLocked with respect to current thread
  46.124     if (LockCount == 0)
  46.125         return 0;
  46.126     if (pthread_self() != LockedBy)
  46.127         return 1;
  46.128     return 0;
  46.129 }
  46.130 
  46.131 bool    MutexImpl::IsSignaled() const
  46.132 {
  46.133     // An mutex is signaled if it is not locked ANYWHERE
  46.134     // Note that this is different from IsLockedByAnotherThread function,
  46.135     // that takes current thread into account
  46.136     return LockCount == 0;
  46.137 }
  46.138 
  46.139 
  46.140 // *** Actual Mutex class implementation
  46.141 
  46.142 Mutex::Mutex(bool recursive)
  46.143 {
  46.144     // NOTE: RefCount mode already thread-safe for all waitables.
  46.145     pImpl = new MutexImpl(this, recursive);
  46.146 }
  46.147 
  46.148 Mutex::~Mutex()
  46.149 {
  46.150     delete pImpl;
  46.151 }
  46.152 
  46.153 // Lock and try lock
  46.154 void Mutex::DoLock()
  46.155 {
  46.156     pImpl->DoLock();
  46.157 }
  46.158 bool Mutex::TryLock()
  46.159 {
  46.160     return pImpl->TryLock();
  46.161 }
  46.162 void Mutex::Unlock()
  46.163 {
  46.164     pImpl->Unlock(this);
  46.165 }
  46.166 bool    Mutex::IsLockedByAnotherThread()
  46.167 {
  46.168     return pImpl->IsLockedByAnotherThread(this);
  46.169 }
  46.170 
  46.171 
  46.172 
  46.173 //-----------------------------------------------------------------------------------
  46.174 // ***** Event
  46.175 
  46.176 bool Event::Wait(unsigned delay)
  46.177 {
  46.178     Mutex::Locker lock(&StateMutex);
  46.179 
  46.180     // Do the correct amount of waiting
  46.181     if (delay == OVR_WAIT_INFINITE)
  46.182     {
  46.183         while(!State)
  46.184             StateWaitCondition.Wait(&StateMutex);
  46.185     }
  46.186     else if (delay)
  46.187     {
  46.188         if (!State)
  46.189             StateWaitCondition.Wait(&StateMutex, delay);
  46.190     }
  46.191 
  46.192     bool state = State;
  46.193     // Take care of temporary 'pulsing' of a state
  46.194     if (Temporary)
  46.195     {
  46.196         Temporary   = false;
  46.197         State       = false;
  46.198     }
  46.199     return state;
  46.200 }
  46.201 
  46.202 void Event::updateState(bool newState, bool newTemp, bool mustNotify)
  46.203 {
  46.204     Mutex::Locker lock(&StateMutex);
  46.205     State       = newState;
  46.206     Temporary   = newTemp;
  46.207     if (mustNotify)
  46.208         StateWaitCondition.NotifyAll();    
  46.209 }
  46.210 
  46.211 
  46.212 
  46.213 // ***** Wait Condition Implementation
  46.214 
  46.215 // Internal implementation class
  46.216 class WaitConditionImpl : public NewOverrideBase
  46.217 {
  46.218     pthread_mutex_t     SMutex;
  46.219     pthread_cond_t      Condv;
  46.220 
  46.221 public:
  46.222 
  46.223     // Constructor/destructor
  46.224     WaitConditionImpl();
  46.225     ~WaitConditionImpl();
  46.226 
  46.227     // Release mutex and wait for condition. The mutex is re-aqured after the wait.
  46.228     bool    Wait(Mutex *pmutex, unsigned delay = OVR_WAIT_INFINITE);
  46.229 
  46.230     // Notify a condition, releasing at one object waiting
  46.231     void    Notify();
  46.232     // Notify a condition, releasing all objects waiting
  46.233     void    NotifyAll();
  46.234 };
  46.235 
  46.236 
  46.237 WaitConditionImpl::WaitConditionImpl()
  46.238 {
  46.239     pthread_mutex_init(&SMutex, 0);
  46.240     pthread_cond_init(&Condv, 0);
  46.241 }
  46.242 
  46.243 WaitConditionImpl::~WaitConditionImpl()
  46.244 {
  46.245     pthread_mutex_destroy(&SMutex);
  46.246     pthread_cond_destroy(&Condv);
  46.247 }    
  46.248 
  46.249 bool    WaitConditionImpl::Wait(Mutex *pmutex, unsigned delay)
  46.250 {
  46.251     bool            result = 1;
  46.252     unsigned            lockCount = pmutex->pImpl->LockCount;
  46.253 
  46.254     // Mutex must have been locked
  46.255     if (lockCount == 0)
  46.256         return 0;
  46.257 
  46.258     pthread_mutex_lock(&SMutex);
  46.259 
  46.260     // Finally, release a mutex or semaphore
  46.261     if (pmutex->pImpl->Recursive)
  46.262     {
  46.263         // Release the recursive mutex N times
  46.264         pmutex->pImpl->LockCount = 0;
  46.265         for(unsigned i=0; i<lockCount; i++)
  46.266             pthread_mutex_unlock(&pmutex->pImpl->SMutex);
  46.267     }
  46.268     else
  46.269     {
  46.270         pmutex->pImpl->LockCount = 0;
  46.271         pthread_mutex_unlock(&pmutex->pImpl->SMutex);
  46.272     }
  46.273 
  46.274     // Note that there is a gap here between mutex.Unlock() and Wait().
  46.275     // The other mutex protects this gap.
  46.276 
  46.277     if (delay == OVR_WAIT_INFINITE)
  46.278         pthread_cond_wait(&Condv,&SMutex);
  46.279     else
  46.280     {
  46.281         timespec ts;
  46.282 #ifdef OVR_OS_PS3
  46.283         sys_time_sec_t s;
  46.284         sys_time_nsec_t ns;
  46.285         sys_time_get_current_time(&s, &ns);
  46.286 
  46.287         ts.tv_sec = s + (delay / 1000);
  46.288         ts.tv_nsec = ns + (delay % 1000) * 1000000;
  46.289 
  46.290 #else
  46.291         struct timeval tv;
  46.292         gettimeofday(&tv, 0);
  46.293 
  46.294         ts.tv_sec = tv.tv_sec + (delay / 1000);
  46.295         ts.tv_nsec = (tv.tv_usec + (delay % 1000) * 1000) * 1000;
  46.296 #endif
  46.297         if (ts.tv_nsec > 999999999)
  46.298         {
  46.299             ts.tv_sec++;
  46.300             ts.tv_nsec -= 1000000000;
  46.301         }
  46.302         int r = pthread_cond_timedwait(&Condv,&SMutex, &ts);
  46.303         OVR_ASSERT(r == 0 || r == ETIMEDOUT);
  46.304         if (r)
  46.305             result = 0;
  46.306     }
  46.307 
  46.308     pthread_mutex_unlock(&SMutex);
  46.309 
  46.310     // Re-aquire the mutex
  46.311     for(unsigned i=0; i<lockCount; i++)
  46.312         pmutex->DoLock(); 
  46.313 
  46.314     // Return the result
  46.315     return result;
  46.316 }
  46.317 
  46.318 // Notify a condition, releasing the least object in a queue
  46.319 void    WaitConditionImpl::Notify()
  46.320 {
  46.321     pthread_mutex_lock(&SMutex);
  46.322     pthread_cond_signal(&Condv);
  46.323     pthread_mutex_unlock(&SMutex);
  46.324 }
  46.325 
  46.326 // Notify a condition, releasing all objects waiting
  46.327 void    WaitConditionImpl::NotifyAll()
  46.328 {
  46.329     pthread_mutex_lock(&SMutex);
  46.330     pthread_cond_broadcast(&Condv);
  46.331     pthread_mutex_unlock(&SMutex);
  46.332 }
  46.333 
  46.334 
  46.335 
  46.336 // *** Actual implementation of WaitCondition
  46.337 
  46.338 WaitCondition::WaitCondition()
  46.339 {
  46.340     pImpl = new WaitConditionImpl;
  46.341 }
  46.342 WaitCondition::~WaitCondition()
  46.343 {
  46.344     delete pImpl;
  46.345 }
  46.346     
  46.347 bool    WaitCondition::Wait(Mutex *pmutex, unsigned delay)
  46.348 {
  46.349     return pImpl->Wait(pmutex, delay);
  46.350 }
  46.351 // Notification
  46.352 void    WaitCondition::Notify()
  46.353 {
  46.354     pImpl->Notify();
  46.355 }
  46.356 void    WaitCondition::NotifyAll()
  46.357 {
  46.358     pImpl->NotifyAll();
  46.359 }
  46.360 
  46.361 
  46.362 // ***** Current thread
  46.363 
  46.364 // Per-thread variable
  46.365 /*
  46.366 static __thread Thread* pCurrentThread = 0;
  46.367 
  46.368 // Static function to return a pointer to the current thread
  46.369 void    Thread::InitCurrentThread(Thread *pthread)
  46.370 {
  46.371     pCurrentThread = pthread;
  46.372 }
  46.373 
  46.374 // Static function to return a pointer to the current thread
  46.375 Thread*    Thread::GetThread()
  46.376 {
  46.377     return pCurrentThread;
  46.378 }
  46.379 */
  46.380 
  46.381 
  46.382 // *** Thread constructors.
  46.383 
  46.384 Thread::Thread(UPInt stackSize, int processor)
  46.385 {
  46.386     // NOTE: RefCount mode already thread-safe for all Waitable objects.
  46.387     CreateParams params;
  46.388     params.stackSize = stackSize;
  46.389     params.processor = processor;
  46.390     Init(params);
  46.391 }
  46.392 
  46.393 Thread::Thread(Thread::ThreadFn threadFunction, void*  userHandle, UPInt stackSize,
  46.394                  int processor, Thread::ThreadState initialState)
  46.395 {
  46.396     CreateParams params(threadFunction, userHandle, stackSize, processor, initialState);
  46.397     Init(params);
  46.398 }
  46.399 
  46.400 Thread::Thread(const CreateParams& params)
  46.401 {
  46.402     Init(params);
  46.403 }
  46.404 
  46.405 void Thread::Init(const CreateParams& params)
  46.406 {
  46.407     // Clear the variables    
  46.408     ThreadFlags     = 0;
  46.409     ThreadHandle    = 0;
  46.410     ExitCode        = 0;
  46.411     SuspendCount    = 0;
  46.412     StackSize       = params.stackSize;
  46.413     Processor       = params.processor;
  46.414     Priority        = params.priority;
  46.415 
  46.416     // Clear Function pointers
  46.417     ThreadFunction  = params.threadFunction;
  46.418     UserHandle      = params.userHandle;
  46.419     if (params.initialState != NotRunning)
  46.420         Start(params.initialState);
  46.421 }
  46.422 
  46.423 Thread::~Thread()
  46.424 {
  46.425     // Thread should not running while object is being destroyed,
  46.426     // this would indicate ref-counting issue.
  46.427     //OVR_ASSERT(IsRunning() == 0);
  46.428 
  46.429     // Clean up thread.    
  46.430     ThreadHandle = 0;
  46.431 }
  46.432 
  46.433 
  46.434 
  46.435 // *** Overridable User functions.
  46.436 
  46.437 // Default Run implementation
  46.438 int    Thread::Run()
  46.439 {
  46.440     // Call pointer to function, if available.    
  46.441     return (ThreadFunction) ? ThreadFunction(this, UserHandle) : 0;
  46.442 }
  46.443 void    Thread::OnExit()
  46.444 {   
  46.445 }
  46.446 
  46.447 
  46.448 // Finishes the thread and releases internal reference to it.
  46.449 void    Thread::FinishAndRelease()
  46.450 {
  46.451     // Note: thread must be US.
  46.452     ThreadFlags &= (UInt32)~(OVR_THREAD_STARTED);
  46.453     ThreadFlags |= OVR_THREAD_FINISHED;
  46.454 
  46.455     // Release our reference; this is equivalent to 'delete this'
  46.456     // from the point of view of our thread.
  46.457     Release();
  46.458 }
  46.459 
  46.460 
  46.461 
  46.462 // *** ThreadList - used to track all created threads
  46.463 
  46.464 class ThreadList : public NewOverrideBase
  46.465 {
  46.466     //------------------------------------------------------------------------
  46.467     struct ThreadHashOp
  46.468     {
  46.469         size_t operator()(const Thread* ptr)
  46.470         {
  46.471             return (((size_t)ptr) >> 6) ^ (size_t)ptr;
  46.472         }
  46.473     };
  46.474 
  46.475     HashSet<Thread*, ThreadHashOp>        ThreadSet;
  46.476     Mutex                                 ThreadMutex;
  46.477     WaitCondition                         ThreadsEmpty;
  46.478     // Track the root thread that created us.
  46.479     pthread_t                             RootThreadId;
  46.480 
  46.481     static ThreadList* volatile pRunningThreads;
  46.482 
  46.483     void addThread(Thread *pthread)
  46.484     {
  46.485         Mutex::Locker lock(&ThreadMutex);
  46.486         ThreadSet.Add(pthread);
  46.487     }
  46.488 
  46.489     void removeThread(Thread *pthread)
  46.490     {
  46.491         Mutex::Locker lock(&ThreadMutex);
  46.492         ThreadSet.Remove(pthread);
  46.493         if (ThreadSet.GetSize() == 0)
  46.494             ThreadsEmpty.Notify();
  46.495     }
  46.496 
  46.497     void finishAllThreads()
  46.498     {
  46.499         // Only original root thread can call this.
  46.500         OVR_ASSERT(pthread_self() == RootThreadId);
  46.501 
  46.502         Mutex::Locker lock(&ThreadMutex);
  46.503         while (ThreadSet.GetSize() != 0)
  46.504             ThreadsEmpty.Wait(&ThreadMutex);
  46.505     }
  46.506 
  46.507 public:
  46.508 
  46.509     ThreadList()
  46.510     {
  46.511         RootThreadId = pthread_self();
  46.512     }
  46.513     ~ThreadList() { }
  46.514 
  46.515 
  46.516     static void AddRunningThread(Thread *pthread)
  46.517     {
  46.518         // Non-atomic creation ok since only the root thread
  46.519         if (!pRunningThreads)
  46.520         {
  46.521             pRunningThreads = new ThreadList;
  46.522             OVR_ASSERT(pRunningThreads);
  46.523         }
  46.524         pRunningThreads->addThread(pthread);
  46.525     }
  46.526 
  46.527     // NOTE: 'pthread' might be a dead pointer when this is
  46.528     // called so it should not be accessed; it is only used
  46.529     // for removal.
  46.530     static void RemoveRunningThread(Thread *pthread)
  46.531     {
  46.532         OVR_ASSERT(pRunningThreads);        
  46.533         pRunningThreads->removeThread(pthread);
  46.534     }
  46.535 
  46.536     static void FinishAllThreads()
  46.537     {
  46.538         // This is ok because only root thread can wait for other thread finish.
  46.539         if (pRunningThreads)
  46.540         {           
  46.541             pRunningThreads->finishAllThreads();
  46.542             delete pRunningThreads;
  46.543             pRunningThreads = 0;
  46.544         }        
  46.545     }
  46.546 };
  46.547 
  46.548 // By default, we have no thread list.
  46.549 ThreadList* volatile ThreadList::pRunningThreads = 0;
  46.550 
  46.551 
  46.552 // FinishAllThreads - exposed publicly in Thread.
  46.553 void Thread::FinishAllThreads()
  46.554 {
  46.555     ThreadList::FinishAllThreads();
  46.556 }
  46.557 
  46.558 // *** Run override
  46.559 
  46.560 int    Thread::PRun()
  46.561 {
  46.562     // Suspend us on start, if requested
  46.563     if (ThreadFlags & OVR_THREAD_START_SUSPENDED)
  46.564     {
  46.565         Suspend();
  46.566         ThreadFlags &= (UInt32)~OVR_THREAD_START_SUSPENDED;
  46.567     }
  46.568 
  46.569     // Call the virtual run function
  46.570     ExitCode = Run();    
  46.571     return ExitCode;
  46.572 }
  46.573 
  46.574 
  46.575 
  46.576 
  46.577 // *** User overridables
  46.578 
  46.579 bool    Thread::GetExitFlag() const
  46.580 {
  46.581     return (ThreadFlags & OVR_THREAD_EXIT) != 0;
  46.582 }       
  46.583 
  46.584 void    Thread::SetExitFlag(bool exitFlag)
  46.585 {
  46.586     // The below is atomic since ThreadFlags is AtomicInt.
  46.587     if (exitFlag)
  46.588         ThreadFlags |= OVR_THREAD_EXIT;
  46.589     else
  46.590         ThreadFlags &= (UInt32) ~OVR_THREAD_EXIT;
  46.591 }
  46.592 
  46.593 
  46.594 // Determines whether the thread was running and is now finished
  46.595 bool    Thread::IsFinished() const
  46.596 {
  46.597     return (ThreadFlags & OVR_THREAD_FINISHED) != 0;
  46.598 }
  46.599 // Determines whether the thread is suspended
  46.600 bool    Thread::IsSuspended() const
  46.601 {   
  46.602     return SuspendCount > 0;
  46.603 }
  46.604 // Returns current thread state
  46.605 Thread::ThreadState Thread::GetThreadState() const
  46.606 {
  46.607     if (IsSuspended())
  46.608         return Suspended;    
  46.609     if (ThreadFlags & OVR_THREAD_STARTED)
  46.610         return Running;    
  46.611     return NotRunning;
  46.612 }
  46.613 /*
  46.614 static const char* mapsched_policy(int policy)
  46.615 {
  46.616     switch(policy)
  46.617     {
  46.618     case SCHED_OTHER:
  46.619         return "SCHED_OTHER";
  46.620     case SCHED_RR:
  46.621         return "SCHED_RR";
  46.622     case SCHED_FIFO:
  46.623         return "SCHED_FIFO";
  46.624 
  46.625     }
  46.626     return "UNKNOWN";
  46.627 }
  46.628     int policy;
  46.629     sched_param sparam;
  46.630     pthread_getschedparam(pthread_self(), &policy, &sparam);
  46.631     int max_prior = sched_get_priority_max(policy);
  46.632     int min_prior = sched_get_priority_min(policy);
  46.633     printf(" !!!! policy: %s, priority: %d, max priority: %d, min priority: %d\n", mapsched_policy(policy), sparam.sched_priority, max_prior, min_prior);
  46.634 #include <stdio.h>
  46.635 */
  46.636 // ***** Thread management
  46.637 
  46.638 // The actual first function called on thread start
  46.639 void* Thread_PthreadStartFn(void* phandle)
  46.640 {
  46.641     Thread* pthread = (Thread*)phandle;
  46.642     int     result = pthread->PRun();
  46.643     // Signal the thread as done and release it atomically.
  46.644     pthread->FinishAndRelease();
  46.645     // At this point Thread object might be dead; however we can still pass
  46.646     // it to RemoveRunningThread since it is only used as a key there.   
  46.647     ThreadList::RemoveRunningThread(pthread);
  46.648     return (void*) result;
  46.649 }
  46.650 
  46.651 int Thread::InitAttr = 0;
  46.652 pthread_attr_t Thread::Attr; 
  46.653 
  46.654 /* static */
  46.655 int Thread::GetOSPriority(ThreadPriority p)
  46.656 //static inline int MapToSystemPrority(Thread::ThreadPriority p)
  46.657 {
  46.658 #ifdef OVR_OS_PS3 
  46.659     switch(p)
  46.660     {
  46.661     case Thread::CriticalPriority:     return 0;
  46.662     case Thread::HighestPriority:      return 300;
  46.663     case Thread::AboveNormalPriority:  return 600;
  46.664     case Thread::NormalPriority:       return 1000;
  46.665     case Thread::BelowNormalPriority:  return 1500;
  46.666     case Thread::LowestPriority:       return 2500;
  46.667     case Thread::IdlePriority:         return 3071;
  46.668     }                                  return 1000;
  46.669 #else
  46.670     OVR_UNUSED(p);
  46.671     return -1;
  46.672 #endif
  46.673 }
  46.674 
  46.675 bool    Thread::Start(ThreadState initialState)
  46.676 {
  46.677     if (initialState == NotRunning)
  46.678         return 0;
  46.679     if (GetThreadState() != NotRunning)
  46.680     {
  46.681         OVR_DEBUG_LOG(("Thread::Start failed - thread %p already running", this));
  46.682         return 0;
  46.683     }
  46.684 
  46.685     if (!InitAttr)
  46.686     {
  46.687         pthread_attr_init(&Attr);
  46.688         pthread_attr_setdetachstate(&Attr, PTHREAD_CREATE_DETACHED);
  46.689         pthread_attr_setstacksize(&Attr, 128 * 1024);
  46.690         sched_param sparam;
  46.691         sparam.sched_priority = Thread::GetOSPriority(NormalPriority);
  46.692         pthread_attr_setschedparam(&Attr, &sparam);
  46.693         InitAttr = 1;
  46.694     }
  46.695 
  46.696     ExitCode        = 0;
  46.697     SuspendCount    = 0;
  46.698     ThreadFlags     = (initialState == Running) ? 0 : OVR_THREAD_START_SUSPENDED;
  46.699 
  46.700     // AddRef to us until the thread is finished
  46.701     AddRef();
  46.702     ThreadList::AddRunningThread(this);
  46.703 
  46.704     int result;
  46.705     if (StackSize != 128 * 1024 || Priority != NormalPriority)
  46.706     {
  46.707         pthread_attr_t attr;
  46.708 
  46.709         pthread_attr_init(&attr);
  46.710         pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
  46.711         pthread_attr_setstacksize(&attr, StackSize);
  46.712         sched_param sparam;
  46.713         sparam.sched_priority = Thread::GetOSPriority(Priority);
  46.714         pthread_attr_setschedparam(&attr, &sparam);
  46.715         result = pthread_create(&ThreadHandle, &attr, Thread_PthreadStartFn, this);
  46.716         pthread_attr_destroy(&attr);
  46.717     }
  46.718     else
  46.719         result = pthread_create(&ThreadHandle, &Attr, Thread_PthreadStartFn, this);
  46.720 
  46.721     if (result)
  46.722     {
  46.723         ThreadFlags = 0;
  46.724         Release();
  46.725         ThreadList::RemoveRunningThread(this);
  46.726         return 0;
  46.727     }
  46.728     return 1;
  46.729 }
  46.730 
  46.731 
  46.732 // Suspend the thread until resumed
  46.733 bool    Thread::Suspend()
  46.734 {
  46.735     OVR_DEBUG_LOG(("Thread::Suspend - cannot suspend threads on this system"));
  46.736     return 0;
  46.737 }
  46.738 
  46.739 // Resumes currently suspended thread
  46.740 bool    Thread::Resume()
  46.741 {
  46.742     return 0;
  46.743 }
  46.744 
  46.745 
  46.746 // Quits with an exit code  
  46.747 void    Thread::Exit(int exitCode)
  46.748 {
  46.749     // Can only exist the current thread
  46.750    // if (GetThread() != this)
  46.751    //     return;
  46.752 
  46.753     // Call the virtual OnExit function
  46.754     OnExit();   
  46.755 
  46.756     // Signal this thread object as done and release it's references.
  46.757     FinishAndRelease();
  46.758     ThreadList::RemoveRunningThread(this);
  46.759 
  46.760     pthread_exit((void *) exitCode);
  46.761 }
  46.762 
  46.763 ThreadId GetCurrentThreadId()
  46.764 {
  46.765     return (void*)pthread_self();
  46.766 }
  46.767 
  46.768 // *** Sleep functions
  46.769 
  46.770 /* static */
  46.771 bool    Thread::Sleep(unsigned secs)
  46.772 {
  46.773     sleep(secs);
  46.774     return 1;
  46.775 }
  46.776 /* static */
  46.777 bool    Thread::MSleep(unsigned msecs)
  46.778 {
  46.779     usleep(msecs*1000);
  46.780     return 1;
  46.781 }
  46.782 
  46.783 /* static */
  46.784 int     Thread::GetCPUCount()
  46.785 {
  46.786     return 1;
  46.787 }
  46.788 
  46.789 
  46.790 #ifdef OVR_OS_PS3
  46.791 
  46.792 sys_lwmutex_attribute_t Lock::LockAttr = { SYS_SYNC_PRIORITY, SYS_SYNC_RECURSIVE };
  46.793 
  46.794 #endif
  46.795 
  46.796 }
  46.797 
  46.798 #endif  // OVR_ENABLE_THREADS
  46.799 \ No newline at end of file
  46.800 +
  46.801 +#include "OVR_Threads.h"
  46.802 +#include "OVR_Hash.h"
  46.803 +
  46.804 +#ifdef OVR_ENABLE_THREADS
  46.805 +
  46.806 +#include "OVR_Timer.h"
  46.807 +#include "OVR_Log.h"
  46.808 +
  46.809 +#include <pthread.h>
  46.810 +#include <time.h>
  46.811 +
  46.812 +#ifdef OVR_OS_PS3
  46.813 +#include <sys/sys_time.h>
  46.814 +#include <sys/timer.h>
  46.815 +#include <sys/synchronization.h>
  46.816 +#define sleep(x) sys_timer_sleep(x)
  46.817 +#define usleep(x) sys_timer_usleep(x)
  46.818 +using std::timespec;
  46.819 +#else
  46.820 +#include <unistd.h>
  46.821 +#include <sys/time.h>
  46.822 +#include <errno.h>
  46.823 +#endif
  46.824 +
  46.825 +namespace OVR {
  46.826 +
  46.827 +// ***** Mutex implementation
  46.828 +
  46.829 +
  46.830 +// *** Internal Mutex implementation structure
  46.831 +
  46.832 +class MutexImpl : public NewOverrideBase
  46.833 +{
  46.834 +    // System mutex or semaphore
  46.835 +    pthread_mutex_t   SMutex;
  46.836 +    bool          Recursive;
  46.837 +    unsigned      LockCount;
  46.838 +    pthread_t     LockedBy;
  46.839 +
  46.840 +    friend class WaitConditionImpl;
  46.841 +
  46.842 +public:
  46.843 +    // Constructor/destructor
  46.844 +    MutexImpl(Mutex* pmutex, bool recursive = 1);
  46.845 +    ~MutexImpl();
  46.846 +
  46.847 +    // Locking functions
  46.848 +    void                DoLock();
  46.849 +    bool                TryLock();
  46.850 +    void                Unlock(Mutex* pmutex);
  46.851 +    // Returns 1 if the mutes is currently locked
  46.852 +    bool                IsLockedByAnotherThread(Mutex* pmutex);        
  46.853 +    bool                IsSignaled() const;
  46.854 +};
  46.855 +
  46.856 +pthread_mutexattr_t Lock::RecursiveAttr;
  46.857 +bool Lock::RecursiveAttrInit = 0;
  46.858 +
  46.859 +// *** Constructor/destructor
  46.860 +MutexImpl::MutexImpl(Mutex* pmutex, bool recursive)
  46.861 +{   
  46.862 +    Recursive           = recursive;
  46.863 +    LockCount           = 0;
  46.864 +
  46.865 +    if (Recursive)
  46.866 +    {
  46.867 +        if (!Lock::RecursiveAttrInit)
  46.868 +        {
  46.869 +            pthread_mutexattr_init(&Lock::RecursiveAttr);
  46.870 +            pthread_mutexattr_settype(&Lock::RecursiveAttr, PTHREAD_MUTEX_RECURSIVE);
  46.871 +            Lock::RecursiveAttrInit = 1;
  46.872 +        }
  46.873 +
  46.874 +        pthread_mutex_init(&SMutex, &Lock::RecursiveAttr);
  46.875 +    }
  46.876 +    else
  46.877 +        pthread_mutex_init(&SMutex, 0);
  46.878 +}
  46.879 +
  46.880 +MutexImpl::~MutexImpl()
  46.881 +{
  46.882 +    pthread_mutex_destroy(&SMutex);
  46.883 +}
  46.884 +
  46.885 +
  46.886 +// Lock and try lock
  46.887 +void MutexImpl::DoLock()
  46.888 +{
  46.889 +    while (pthread_mutex_lock(&SMutex));
  46.890 +    LockCount++;
  46.891 +    LockedBy = pthread_self();
  46.892 +}
  46.893 +
  46.894 +bool MutexImpl::TryLock()
  46.895 +{
  46.896 +    if (!pthread_mutex_trylock(&SMutex))
  46.897 +    {
  46.898 +        LockCount++;
  46.899 +        LockedBy = pthread_self();
  46.900 +        return 1;
  46.901 +    }
  46.902 +    
  46.903 +    return 0;
  46.904 +}
  46.905 +
  46.906 +void MutexImpl::Unlock(Mutex* pmutex)
  46.907 +{
  46.908 +    OVR_ASSERT(pthread_self() == LockedBy && LockCount > 0);
  46.909 +
  46.910 +    unsigned lockCount;
  46.911 +    LockCount--;
  46.912 +    lockCount = LockCount;
  46.913 +
  46.914 +    pthread_mutex_unlock(&SMutex);
  46.915 +}
  46.916 +
  46.917 +bool    MutexImpl::IsLockedByAnotherThread(Mutex* pmutex)
  46.918 +{
  46.919 +    // There could be multiple interpretations of IsLocked with respect to current thread
  46.920 +    if (LockCount == 0)
  46.921 +        return 0;
  46.922 +    if (pthread_self() != LockedBy)
  46.923 +        return 1;
  46.924 +    return 0;
  46.925 +}
  46.926 +
  46.927 +bool    MutexImpl::IsSignaled() const
  46.928 +{
  46.929 +    // An mutex is signaled if it is not locked ANYWHERE
  46.930 +    // Note that this is different from IsLockedByAnotherThread function,
  46.931 +    // that takes current thread into account
  46.932 +    return LockCount == 0;
  46.933 +}
  46.934 +
  46.935 +
  46.936 +// *** Actual Mutex class implementation
  46.937 +
  46.938 +Mutex::Mutex(bool recursive)
  46.939 +{
  46.940 +    // NOTE: RefCount mode already thread-safe for all waitables.
  46.941 +    pImpl = new MutexImpl(this, recursive);
  46.942 +}
  46.943 +
  46.944 +Mutex::~Mutex()
  46.945 +{
  46.946 +    delete pImpl;
  46.947 +}
  46.948 +
  46.949 +// Lock and try lock
  46.950 +void Mutex::DoLock()
  46.951 +{
  46.952 +    pImpl->DoLock();
  46.953 +}
  46.954 +bool Mutex::TryLock()
  46.955 +{
  46.956 +    return pImpl->TryLock();
  46.957 +}
  46.958 +void Mutex::Unlock()
  46.959 +{
  46.960 +    pImpl->Unlock(this);
  46.961 +}
  46.962 +bool    Mutex::IsLockedByAnotherThread()
  46.963 +{
  46.964 +    return pImpl->IsLockedByAnotherThread(this);
  46.965 +}
  46.966 +
  46.967 +
  46.968 +
  46.969 +//-----------------------------------------------------------------------------------
  46.970 +// ***** Event
  46.971 +
  46.972 +bool Event::Wait(unsigned delay)
  46.973 +{
  46.974 +    Mutex::Locker lock(&StateMutex);
  46.975 +
  46.976 +    // Do the correct amount of waiting
  46.977 +    if (delay == OVR_WAIT_INFINITE)
  46.978 +    {
  46.979 +        while(!State)
  46.980 +            StateWaitCondition.Wait(&StateMutex);
  46.981 +    }
  46.982 +    else if (delay)
  46.983 +    {
  46.984 +        if (!State)
  46.985 +            StateWaitCondition.Wait(&StateMutex, delay);
  46.986 +    }
  46.987 +
  46.988 +    bool state = State;
  46.989 +    // Take care of temporary 'pulsing' of a state
  46.990 +    if (Temporary)
  46.991 +    {
  46.992 +        Temporary   = false;
  46.993 +        State       = false;
  46.994 +    }
  46.995 +    return state;
  46.996 +}
  46.997 +
  46.998 +void Event::updateState(bool newState, bool newTemp, bool mustNotify)
  46.999 +{
 46.1000 +    Mutex::Locker lock(&StateMutex);
 46.1001 +    State       = newState;
 46.1002 +    Temporary   = newTemp;
 46.1003 +    if (mustNotify)
 46.1004 +        StateWaitCondition.NotifyAll();    
 46.1005 +}
 46.1006 +
 46.1007 +
 46.1008 +
 46.1009 +// ***** Wait Condition Implementation
 46.1010 +
 46.1011 +// Internal implementation class
 46.1012 +class WaitConditionImpl : public NewOverrideBase
 46.1013 +{
 46.1014 +    pthread_mutex_t     SMutex;
 46.1015 +    pthread_cond_t      Condv;
 46.1016 +
 46.1017 +public:
 46.1018 +
 46.1019 +    // Constructor/destructor
 46.1020 +    WaitConditionImpl();
 46.1021 +    ~WaitConditionImpl();
 46.1022 +
 46.1023 +    // Release mutex and wait for condition. The mutex is re-aqured after the wait.
 46.1024 +    bool    Wait(Mutex *pmutex, unsigned delay = OVR_WAIT_INFINITE);
 46.1025 +
 46.1026 +    // Notify a condition, releasing at one object waiting
 46.1027 +    void    Notify();
 46.1028 +    // Notify a condition, releasing all objects waiting
 46.1029 +    void    NotifyAll();
 46.1030 +};
 46.1031 +
 46.1032 +
 46.1033 +WaitConditionImpl::WaitConditionImpl()
 46.1034 +{
 46.1035 +    pthread_mutex_init(&SMutex, 0);
 46.1036 +    pthread_cond_init(&Condv, 0);
 46.1037 +}
 46.1038 +
 46.1039 +WaitConditionImpl::~WaitConditionImpl()
 46.1040 +{
 46.1041 +    pthread_mutex_destroy(&SMutex);
 46.1042 +    pthread_cond_destroy(&Condv);
 46.1043 +}    
 46.1044 +
 46.1045 +bool    WaitConditionImpl::Wait(Mutex *pmutex, unsigned delay)
 46.1046 +{
 46.1047 +    bool            result = 1;
 46.1048 +    unsigned            lockCount = pmutex->pImpl->LockCount;
 46.1049 +
 46.1050 +    // Mutex must have been locked
 46.1051 +    if (lockCount == 0)
 46.1052 +        return 0;
 46.1053 +
 46.1054 +    pthread_mutex_lock(&SMutex);
 46.1055 +
 46.1056 +    // Finally, release a mutex or semaphore
 46.1057 +    if (pmutex->pImpl->Recursive)
 46.1058 +    {
 46.1059 +        // Release the recursive mutex N times
 46.1060 +        pmutex->pImpl->LockCount = 0;
 46.1061 +        for(unsigned i=0; i<lockCount; i++)
 46.1062 +            pthread_mutex_unlock(&pmutex->pImpl->SMutex);
 46.1063 +    }
 46.1064 +    else
 46.1065 +    {
 46.1066 +        pmutex->pImpl->LockCount = 0;
 46.1067 +        pthread_mutex_unlock(&pmutex->pImpl->SMutex);
 46.1068 +    }
 46.1069 +
 46.1070 +    // Note that there is a gap here between mutex.Unlock() and Wait().
 46.1071 +    // The other mutex protects this gap.
 46.1072 +
 46.1073 +    if (delay == OVR_WAIT_INFINITE)
 46.1074 +        pthread_cond_wait(&Condv,&SMutex);
 46.1075 +    else
 46.1076 +    {
 46.1077 +        timespec ts;
 46.1078 +#ifdef OVR_OS_PS3
 46.1079 +        sys_time_sec_t s;
 46.1080 +        sys_time_nsec_t ns;
 46.1081 +        sys_time_get_current_time(&s, &ns);
 46.1082 +
 46.1083 +        ts.tv_sec = s + (delay / 1000);
 46.1084 +        ts.tv_nsec = ns + (delay % 1000) * 1000000;
 46.1085 +
 46.1086 +#else
 46.1087 +        struct timeval tv;
 46.1088 +        gettimeofday(&tv, 0);
 46.1089 +
 46.1090 +        ts.tv_sec = tv.tv_sec + (delay / 1000);
 46.1091 +        ts.tv_nsec = (tv.tv_usec + (delay % 1000) * 1000) * 1000;
 46.1092 +#endif
 46.1093 +        if (ts.tv_nsec > 999999999)
 46.1094 +        {
 46.1095 +            ts.tv_sec++;
 46.1096 +            ts.tv_nsec -= 1000000000;
 46.1097 +        }
 46.1098 +        int r = pthread_cond_timedwait(&Condv,&SMutex, &ts);
 46.1099 +        OVR_ASSERT(r == 0 || r == ETIMEDOUT);
 46.1100 +        if (r)
 46.1101 +            result = 0;
 46.1102 +    }
 46.1103 +
 46.1104 +    pthread_mutex_unlock(&SMutex);
 46.1105 +
 46.1106 +    // Re-aquire the mutex
 46.1107 +    for(unsigned i=0; i<lockCount; i++)
 46.1108 +        pmutex->DoLock(); 
 46.1109 +
 46.1110 +    // Return the result
 46.1111 +    return result;
 46.1112 +}
 46.1113 +
 46.1114 +// Notify a condition, releasing the least object in a queue
 46.1115 +void    WaitConditionImpl::Notify()
 46.1116 +{
 46.1117 +    pthread_mutex_lock(&SMutex);
 46.1118 +    pthread_cond_signal(&Condv);
 46.1119 +    pthread_mutex_unlock(&SMutex);
 46.1120 +}
 46.1121 +
 46.1122 +// Notify a condition, releasing all objects waiting
 46.1123 +void    WaitConditionImpl::NotifyAll()
 46.1124 +{
 46.1125 +    pthread_mutex_lock(&SMutex);
 46.1126 +    pthread_cond_broadcast(&Condv);
 46.1127 +    pthread_mutex_unlock(&SMutex);
 46.1128 +}
 46.1129 +
 46.1130 +
 46.1131 +
 46.1132 +// *** Actual implementation of WaitCondition
 46.1133 +
 46.1134 +WaitCondition::WaitCondition()
 46.1135 +{
 46.1136 +    pImpl = new WaitConditionImpl;
 46.1137 +}
 46.1138 +WaitCondition::~WaitCondition()
 46.1139 +{
 46.1140 +    delete pImpl;
 46.1141 +}
 46.1142 +    
 46.1143 +bool    WaitCondition::Wait(Mutex *pmutex, unsigned delay)
 46.1144 +{
 46.1145 +    return pImpl->Wait(pmutex, delay);
 46.1146 +}
 46.1147 +// Notification
 46.1148 +void    WaitCondition::Notify()
 46.1149 +{
 46.1150 +    pImpl->Notify();
 46.1151 +}
 46.1152 +void    WaitCondition::NotifyAll()
 46.1153 +{
 46.1154 +    pImpl->NotifyAll();
 46.1155 +}
 46.1156 +
 46.1157 +
 46.1158 +// ***** Current thread
 46.1159 +
 46.1160 +// Per-thread variable
 46.1161 +/*
 46.1162 +static __thread Thread* pCurrentThread = 0;
 46.1163 +
 46.1164 +// Static function to return a pointer to the current thread
 46.1165 +void    Thread::InitCurrentThread(Thread *pthread)
 46.1166 +{
 46.1167 +    pCurrentThread = pthread;
 46.1168 +}
 46.1169 +
 46.1170 +// Static function to return a pointer to the current thread
 46.1171 +Thread*    Thread::GetThread()
 46.1172 +{
 46.1173 +    return pCurrentThread;
 46.1174 +}
 46.1175 +*/
 46.1176 +
 46.1177 +
 46.1178 +// *** Thread constructors.
 46.1179 +
 46.1180 +Thread::Thread(UPInt stackSize, int processor)
 46.1181 +{
 46.1182 +    // NOTE: RefCount mode already thread-safe for all Waitable objects.
 46.1183 +    CreateParams params;
 46.1184 +    params.stackSize = stackSize;
 46.1185 +    params.processor = processor;
 46.1186 +    Init(params);
 46.1187 +}
 46.1188 +
 46.1189 +Thread::Thread(Thread::ThreadFn threadFunction, void*  userHandle, UPInt stackSize,
 46.1190 +                 int processor, Thread::ThreadState initialState)
 46.1191 +{
 46.1192 +    CreateParams params(threadFunction, userHandle, stackSize, processor, initialState);
 46.1193 +    Init(params);
 46.1194 +}
 46.1195 +
 46.1196 +Thread::Thread(const CreateParams& params)
 46.1197 +{
 46.1198 +    Init(params);
 46.1199 +}
 46.1200 +
 46.1201 +void Thread::Init(const CreateParams& params)
 46.1202 +{
 46.1203 +    // Clear the variables    
 46.1204 +    ThreadFlags     = 0;
 46.1205 +    ThreadHandle    = 0;
 46.1206 +    ExitCode        = 0;
 46.1207 +    SuspendCount    = 0;
 46.1208 +    StackSize       = params.stackSize;
 46.1209 +    Processor       = params.processor;
 46.1210 +    Priority        = params.priority;
 46.1211 +
 46.1212 +    // Clear Function pointers
 46.1213 +    ThreadFunction  = params.threadFunction;
 46.1214 +    UserHandle      = params.userHandle;
 46.1215 +    if (params.initialState != NotRunning)
 46.1216 +        Start(params.initialState);
 46.1217 +}
 46.1218 +
 46.1219 +Thread::~Thread()
 46.1220 +{
 46.1221 +    // Thread should not running while object is being destroyed,
 46.1222 +    // this would indicate ref-counting issue.
 46.1223 +    //OVR_ASSERT(IsRunning() == 0);
 46.1224 +
 46.1225 +    // Clean up thread.    
 46.1226 +    ThreadHandle = 0;
 46.1227 +}
 46.1228 +
 46.1229 +
 46.1230 +
 46.1231 +// *** Overridable User functions.
 46.1232 +
 46.1233 +// Default Run implementation
 46.1234 +int    Thread::Run()
 46.1235 +{
 46.1236 +    // Call pointer to function, if available.    
 46.1237 +    return (ThreadFunction) ? ThreadFunction(this, UserHandle) : 0;
 46.1238 +}
 46.1239 +void    Thread::OnExit()
 46.1240 +{   
 46.1241 +}
 46.1242 +
 46.1243 +
 46.1244 +// Finishes the thread and releases internal reference to it.
 46.1245 +void    Thread::FinishAndRelease()
 46.1246 +{
 46.1247 +    // Note: thread must be US.
 46.1248 +    ThreadFlags &= (UInt32)~(OVR_THREAD_STARTED);
 46.1249 +    ThreadFlags |= OVR_THREAD_FINISHED;
 46.1250 +
 46.1251 +    // Release our reference; this is equivalent to 'delete this'
 46.1252 +    // from the point of view of our thread.
 46.1253 +    Release();
 46.1254 +}
 46.1255 +
 46.1256 +
 46.1257 +
 46.1258 +// *** ThreadList - used to track all created threads
 46.1259 +
 46.1260 +class ThreadList : public NewOverrideBase
 46.1261 +{
 46.1262 +    //------------------------------------------------------------------------
 46.1263 +    struct ThreadHashOp
 46.1264 +    {
 46.1265 +        size_t operator()(const Thread* ptr)
 46.1266 +        {
 46.1267 +            return (((size_t)ptr) >> 6) ^ (size_t)ptr;
 46.1268 +        }
 46.1269 +    };
 46.1270 +
 46.1271 +    HashSet<Thread*, ThreadHashOp>        ThreadSet;
 46.1272 +    Mutex                                 ThreadMutex;
 46.1273 +    WaitCondition                         ThreadsEmpty;
 46.1274 +    // Track the root thread that created us.
 46.1275 +    pthread_t                             RootThreadId;
 46.1276 +
 46.1277 +    static ThreadList* volatile pRunningThreads;
 46.1278 +
 46.1279 +    void addThread(Thread *pthread)
 46.1280 +    {
 46.1281 +        Mutex::Locker lock(&ThreadMutex);
 46.1282 +        ThreadSet.Add(pthread);
 46.1283 +    }
 46.1284 +
 46.1285 +    void removeThread(Thread *pthread)
 46.1286 +    {
 46.1287 +        Mutex::Locker lock(&ThreadMutex);
 46.1288 +        ThreadSet.Remove(pthread);
 46.1289 +        if (ThreadSet.GetSize() == 0)
 46.1290 +            ThreadsEmpty.Notify();
 46.1291 +    }
 46.1292 +
 46.1293 +    void finishAllThreads()
 46.1294 +    {
 46.1295 +        // Only original root thread can call this.
 46.1296 +        OVR_ASSERT(pthread_self() == RootThreadId);
 46.1297 +
 46.1298 +        Mutex::Locker lock(&ThreadMutex);
 46.1299 +        while (ThreadSet.GetSize() != 0)
 46.1300 +            ThreadsEmpty.Wait(&ThreadMutex);
 46.1301 +    }
 46.1302 +
 46.1303 +public:
 46.1304 +
 46.1305 +    ThreadList()
 46.1306 +    {
 46.1307 +        RootThreadId = pthread_self();
 46.1308 +    }
 46.1309 +    ~ThreadList() { }
 46.1310 +
 46.1311 +
 46.1312 +    static void AddRunningThread(Thread *pthread)
 46.1313 +    {
 46.1314 +        // Non-atomic creation ok since only the root thread
 46.1315 +        if (!pRunningThreads)
 46.1316 +        {
 46.1317 +            pRunningThreads = new ThreadList;
 46.1318 +            OVR_ASSERT(pRunningThreads);
 46.1319 +        }
 46.1320 +        pRunningThreads->addThread(pthread);
 46.1321 +    }
 46.1322 +
 46.1323 +    // NOTE: 'pthread' might be a dead pointer when this is
 46.1324 +    // called so it should not be accessed; it is only used
 46.1325 +    // for removal.
 46.1326 +    static void RemoveRunningThread(Thread *pthread)
 46.1327 +    {
 46.1328 +        OVR_ASSERT(pRunningThreads);        
 46.1329 +        pRunningThreads->removeThread(pthread);
 46.1330 +    }
 46.1331 +
 46.1332 +    static void FinishAllThreads()
 46.1333 +    {
 46.1334 +        // This is ok because only root thread can wait for other thread finish.
 46.1335 +        if (pRunningThreads)
 46.1336 +        {           
 46.1337 +            pRunningThreads->finishAllThreads();
 46.1338 +            delete pRunningThreads;
 46.1339 +            pRunningThreads = 0;
 46.1340 +        }        
 46.1341 +    }
 46.1342 +};
 46.1343 +
 46.1344 +// By default, we have no thread list.
 46.1345 +ThreadList* volatile ThreadList::pRunningThreads = 0;
 46.1346 +
 46.1347 +
 46.1348 +// FinishAllThreads - exposed publicly in Thread.
 46.1349 +void Thread::FinishAllThreads()
 46.1350 +{
 46.1351 +    ThreadList::FinishAllThreads();
 46.1352 +}
 46.1353 +
 46.1354 +// *** Run override
 46.1355 +
 46.1356 +int    Thread::PRun()
 46.1357 +{
 46.1358 +    // Suspend us on start, if requested
 46.1359 +    if (ThreadFlags & OVR_THREAD_START_SUSPENDED)
 46.1360 +    {
 46.1361 +        Suspend();
 46.1362 +        ThreadFlags &= (UInt32)~OVR_THREAD_START_SUSPENDED;
 46.1363 +    }
 46.1364 +
 46.1365 +    // Call the virtual run function
 46.1366 +    ExitCode = Run();    
 46.1367 +    return ExitCode;
 46.1368 +}
 46.1369 +
 46.1370 +
 46.1371 +
 46.1372 +
 46.1373 +// *** User overridables
 46.1374 +
 46.1375 +bool    Thread::GetExitFlag() const
 46.1376 +{
 46.1377 +    return (ThreadFlags & OVR_THREAD_EXIT) != 0;
 46.1378 +}       
 46.1379 +
 46.1380 +void    Thread::SetExitFlag(bool exitFlag)
 46.1381 +{
 46.1382 +    // The below is atomic since ThreadFlags is AtomicInt.
 46.1383 +    if (exitFlag)
 46.1384 +        ThreadFlags |= OVR_THREAD_EXIT;
 46.1385 +    else
 46.1386 +        ThreadFlags &= (UInt32) ~OVR_THREAD_EXIT;
 46.1387 +}
 46.1388 +
 46.1389 +
 46.1390 +// Determines whether the thread was running and is now finished
 46.1391 +bool    Thread::IsFinished() const
 46.1392 +{
 46.1393 +    return (ThreadFlags & OVR_THREAD_FINISHED) != 0;
 46.1394 +}
 46.1395 +// Determines whether the thread is suspended
 46.1396 +bool    Thread::IsSuspended() const
 46.1397 +{   
 46.1398 +    return SuspendCount > 0;
 46.1399 +}
 46.1400 +// Returns current thread state
 46.1401 +Thread::ThreadState Thread::GetThreadState() const
 46.1402 +{
 46.1403 +    if (IsSuspended())
 46.1404 +        return Suspended;    
 46.1405 +    if (ThreadFlags & OVR_THREAD_STARTED)
 46.1406 +        return Running;    
 46.1407 +    return NotRunning;
 46.1408 +}
 46.1409 +/*
 46.1410 +static const char* mapsched_policy(int policy)
 46.1411 +{
 46.1412 +    switch(policy)
 46.1413 +    {
 46.1414 +    case SCHED_OTHER:
 46.1415 +        return "SCHED_OTHER";
 46.1416 +    case SCHED_RR:
 46.1417 +        return "SCHED_RR";
 46.1418 +    case SCHED_FIFO:
 46.1419 +        return "SCHED_FIFO";
 46.1420 +
 46.1421 +    }
 46.1422 +    return "UNKNOWN";
 46.1423 +}
 46.1424 +    int policy;
 46.1425 +    sched_param sparam;
 46.1426 +    pthread_getschedparam(pthread_self(), &policy, &sparam);
 46.1427 +    int max_prior = sched_get_priority_max(policy);
 46.1428 +    int min_prior = sched_get_priority_min(policy);
 46.1429 +    printf(" !!!! policy: %s, priority: %d, max priority: %d, min priority: %d\n", mapsched_policy(policy), sparam.sched_priority, max_prior, min_prior);
 46.1430 +#include <stdio.h>
 46.1431 +*/
 46.1432 +// ***** Thread management
 46.1433 +
 46.1434 +// The actual first function called on thread start
 46.1435 +void* Thread_PthreadStartFn(void* phandle)
 46.1436 +{
 46.1437 +    Thread* pthread = (Thread*)phandle;
 46.1438 +    int     result = pthread->PRun();
 46.1439 +    // Signal the thread as done and release it atomically.
 46.1440 +    pthread->FinishAndRelease();
 46.1441 +    // At this point Thread object might be dead; however we can still pass
 46.1442 +    // it to RemoveRunningThread since it is only used as a key there.   
 46.1443 +    ThreadList::RemoveRunningThread(pthread);
 46.1444 +    return (void*) result;
 46.1445 +}
 46.1446 +
 46.1447 +int Thread::InitAttr = 0;
 46.1448 +pthread_attr_t Thread::Attr; 
 46.1449 +
 46.1450 +/* static */
 46.1451 +int Thread::GetOSPriority(ThreadPriority p)
 46.1452 +//static inline int MapToSystemPrority(Thread::ThreadPriority p)
 46.1453 +{
 46.1454 +#ifdef OVR_OS_PS3 
 46.1455 +    switch(p)
 46.1456 +    {
 46.1457 +    case Thread::CriticalPriority:     return 0;
 46.1458 +    case Thread::HighestPriority:      return 300;
 46.1459 +    case Thread::AboveNormalPriority:  return 600;
 46.1460 +    case Thread::NormalPriority:       return 1000;
 46.1461 +    case Thread::BelowNormalPriority:  return 1500;
 46.1462 +    case Thread::LowestPriority:       return 2500;
 46.1463 +    case Thread::IdlePriority:         return 3071;
 46.1464 +    }                                  return 1000;
 46.1465 +#else
 46.1466 +    OVR_UNUSED(p);
 46.1467 +    return -1;
 46.1468 +#endif
 46.1469 +}
 46.1470 +
 46.1471 +bool    Thread::Start(ThreadState initialState)
 46.1472 +{
 46.1473 +    if (initialState == NotRunning)
 46.1474 +        return 0;
 46.1475 +    if (GetThreadState() != NotRunning)
 46.1476 +    {
 46.1477 +        OVR_DEBUG_LOG(("Thread::Start failed - thread %p already running", this));
 46.1478 +        return 0;
 46.1479 +    }
 46.1480 +
 46.1481 +    if (!InitAttr)
 46.1482 +    {
 46.1483 +        pthread_attr_init(&Attr);
 46.1484 +        pthread_attr_setdetachstate(&Attr, PTHREAD_CREATE_DETACHED);
 46.1485 +        pthread_attr_setstacksize(&Attr, 128 * 1024);
 46.1486 +        sched_param sparam;
 46.1487 +        sparam.sched_priority = Thread::GetOSPriority(NormalPriority);
 46.1488 +        pthread_attr_setschedparam(&Attr, &sparam);
 46.1489 +        InitAttr = 1;
 46.1490 +    }
 46.1491 +
 46.1492 +    ExitCode        = 0;
 46.1493 +    SuspendCount    = 0;
 46.1494 +    ThreadFlags     = (initialState == Running) ? 0 : OVR_THREAD_START_SUSPENDED;
 46.1495 +
 46.1496 +    // AddRef to us until the thread is finished
 46.1497 +    AddRef();
 46.1498 +    ThreadList::AddRunningThread(this);
 46.1499 +
 46.1500 +    int result;
 46.1501 +    if (StackSize != 128 * 1024 || Priority != NormalPriority)
 46.1502 +    {
 46.1503 +        pthread_attr_t attr;
 46.1504 +
 46.1505 +        pthread_attr_init(&attr);
 46.1506 +        pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
 46.1507 +        pthread_attr_setstacksize(&attr, StackSize);
 46.1508 +        sched_param sparam;
 46.1509 +        sparam.sched_priority = Thread::GetOSPriority(Priority);
 46.1510 +        pthread_attr_setschedparam(&attr, &sparam);
 46.1511 +        result = pthread_create(&ThreadHandle, &attr, Thread_PthreadStartFn, this);
 46.1512 +        pthread_attr_destroy(&attr);
 46.1513 +    }
 46.1514 +    else
 46.1515 +        result = pthread_create(&ThreadHandle, &Attr, Thread_PthreadStartFn, this);
 46.1516 +
 46.1517 +    if (result)
 46.1518 +    {
 46.1519 +        ThreadFlags = 0;
 46.1520 +        Release();
 46.1521 +        ThreadList::RemoveRunningThread(this);
 46.1522 +        return 0;
 46.1523 +    }
 46.1524 +    return 1;
 46.1525 +}
 46.1526 +
 46.1527 +
 46.1528 +// Suspend the thread until resumed
 46.1529 +bool    Thread::Suspend()
 46.1530 +{
 46.1531 +    OVR_DEBUG_LOG(("Thread::Suspend - cannot suspend threads on this system"));
 46.1532 +    return 0;
 46.1533 +}
 46.1534 +
 46.1535 +// Resumes currently suspended thread
 46.1536 +bool    Thread::Resume()
 46.1537 +{
 46.1538 +    return 0;
 46.1539 +}
 46.1540 +
 46.1541 +
 46.1542 +// Quits with an exit code  
 46.1543 +void    Thread::Exit(int exitCode)
 46.1544 +{
 46.1545 +    // Can only exist the current thread
 46.1546 +   // if (GetThread() != this)
 46.1547 +   //     return;
 46.1548 +
 46.1549 +    // Call the virtual OnExit function
 46.1550 +    OnExit();   
 46.1551 +
 46.1552 +    // Signal this thread object as done and release it's references.
 46.1553 +    FinishAndRelease();
 46.1554 +    ThreadList::RemoveRunningThread(this);
 46.1555 +
 46.1556 +    pthread_exit((void *) exitCode);
 46.1557 +}
 46.1558 +
 46.1559 +ThreadId GetCurrentThreadId()
 46.1560 +{
 46.1561 +    return (void*)pthread_self();
 46.1562 +}
 46.1563 +
 46.1564 +// *** Sleep functions
 46.1565 +
 46.1566 +/* static */
 46.1567 +bool    Thread::Sleep(unsigned secs)
 46.1568 +{
 46.1569 +    sleep(secs);
 46.1570 +    return 1;
 46.1571 +}
 46.1572 +/* static */
 46.1573 +bool    Thread::MSleep(unsigned msecs)
 46.1574 +{
 46.1575 +    usleep(msecs*1000);
 46.1576 +    return 1;
 46.1577 +}
 46.1578 +
 46.1579 +/* static */
 46.1580 +int     Thread::GetCPUCount()
 46.1581 +{
 46.1582 +    return 1;
 46.1583 +}
 46.1584 +
 46.1585 +
 46.1586 +#ifdef OVR_OS_PS3
 46.1587 +
 46.1588 +sys_lwmutex_attribute_t Lock::LockAttr = { SYS_SYNC_PRIORITY, SYS_SYNC_RECURSIVE };
 46.1589 +
 46.1590 +#endif
 46.1591 +
 46.1592 +}
 46.1593 +
 46.1594 +#endif  // OVR_ENABLE_THREADS
    47.1 --- a/libovr/Src/win32/OVR_ThreadsWinAPI.cpp	Sat Sep 14 17:51:03 2013 +0300
    47.2 +++ b/libovr/Src/win32/OVR_ThreadsWinAPI.cpp	Sun Sep 15 04:10:05 2013 +0300
    47.3 @@ -1,1 +1,994 @@
    47.4 -/************************************************************************************
    47.5 
    47.6 Filename    :   OVR_ThreadsWinAPI.cpp
    47.7 Platform    :   WinAPI
    47.8 Content     :   Windows specific thread-related (safe) functionality
    47.9 Created     :   September 19, 2012
   47.10 Notes       : 
   47.11 
   47.12 Copyright   :   Copyright 2012 Oculus VR, Inc. All Rights reserved.
   47.13 
   47.14 Use of this software is subject to the terms of the Oculus license
   47.15 agreement provided at the time of installation or download, or which
   47.16 otherwise accompanies this software in either electronic or hard copy form.
   47.17 
   47.18 ************************************************************************************/
   47.19 
   47.20 #include "OVR_Threads.h"
   47.21 #include "OVR_Hash.h"
   47.22 #include "OVR_Log.h"
   47.23 
   47.24 #ifdef OVR_ENABLE_THREADS
   47.25 
   47.26 // For _beginthreadex / _endtheadex
   47.27 #include <process.h>
   47.28 
   47.29 namespace OVR {
   47.30 
   47.31 
   47.32 //-----------------------------------------------------------------------------------
   47.33 // *** Internal Mutex implementation class
   47.34 
   47.35 class MutexImpl : public NewOverrideBase
   47.36 {
   47.37     // System mutex or semaphore
   47.38     HANDLE            hMutexOrSemaphore;
   47.39     bool              Recursive;
   47.40     volatile unsigned LockCount;
   47.41     
   47.42     friend class WaitConditionImpl;
   47.43 
   47.44 public:
   47.45     // Constructor/destructor
   47.46     MutexImpl(bool recursive = 1);
   47.47     ~MutexImpl();
   47.48 
   47.49     // Locking functions
   47.50     void                DoLock();
   47.51     bool                TryLock();
   47.52     void                Unlock(Mutex* pmutex);
   47.53     // Returns 1 if the mutes is currently locked
   47.54     bool                IsLockedByAnotherThread(Mutex* pmutex);
   47.55 };
   47.56 
   47.57 // *** Constructor/destructor
   47.58 MutexImpl::MutexImpl(bool recursive)
   47.59 {    
   47.60     Recursive                   = recursive;
   47.61     LockCount                   = 0;
   47.62     hMutexOrSemaphore           = Recursive ? CreateMutex(NULL, 0, NULL) : CreateSemaphore(NULL, 1, 1, NULL);
   47.63 }
   47.64 MutexImpl::~MutexImpl()
   47.65 {
   47.66     CloseHandle(hMutexOrSemaphore);
   47.67 }
   47.68 
   47.69 
   47.70 // Lock and try lock
   47.71 void MutexImpl::DoLock()
   47.72 {
   47.73     if (::WaitForSingleObject(hMutexOrSemaphore, INFINITE) != WAIT_OBJECT_0)
   47.74         return;
   47.75     LockCount++;
   47.76 }
   47.77 
   47.78 bool MutexImpl::TryLock()
   47.79 {
   47.80     DWORD ret;
   47.81     if ((ret=::WaitForSingleObject(hMutexOrSemaphore, 0)) != WAIT_OBJECT_0)
   47.82         return 0;
   47.83     LockCount++;
   47.84     return 1;
   47.85 }
   47.86 
   47.87 void MutexImpl::Unlock(Mutex* pmutex)
   47.88 {
   47.89     OVR_UNUSED(pmutex);
   47.90 
   47.91     unsigned lockCount;
   47.92     LockCount--;
   47.93     lockCount = LockCount;
   47.94 
   47.95     // Release mutex
   47.96     if ((Recursive ? ReleaseMutex(hMutexOrSemaphore) :
   47.97                      ReleaseSemaphore(hMutexOrSemaphore, 1, NULL))  != 0)
   47.98     {
   47.99         // This used to call Wait handlers if lockCount == 0.
  47.100     }
  47.101 }
  47.102 
  47.103 bool MutexImpl::IsLockedByAnotherThread(Mutex* pmutex)
  47.104 {
  47.105     // There could be multiple interpretations of IsLocked with respect to current thread
  47.106     if (LockCount == 0)
  47.107         return 0;
  47.108     if (!TryLock())
  47.109         return 1;
  47.110     Unlock(pmutex);
  47.111     return 0;
  47.112 }
  47.113 
  47.114 /*
  47.115 bool    MutexImpl::IsSignaled() const
  47.116 {
  47.117     // An mutex is signaled if it is not locked ANYWHERE
  47.118     // Note that this is different from IsLockedByAnotherThread function,
  47.119     // that takes current thread into account
  47.120     return LockCount == 0;
  47.121 }
  47.122 */
  47.123 
  47.124 
  47.125 // *** Actual Mutex class implementation
  47.126 
  47.127 Mutex::Mutex(bool recursive)
  47.128 {    
  47.129     pImpl = new MutexImpl(recursive);
  47.130 }
  47.131 Mutex::~Mutex()
  47.132 {
  47.133     delete pImpl;
  47.134 }
  47.135 
  47.136 // Lock and try lock
  47.137 void Mutex::DoLock()
  47.138 {
  47.139     pImpl->DoLock();
  47.140 }
  47.141 bool Mutex::TryLock()
  47.142 {
  47.143     return pImpl->TryLock();
  47.144 }
  47.145 void Mutex::Unlock()
  47.146 {
  47.147     pImpl->Unlock(this);
  47.148 }
  47.149 bool Mutex::IsLockedByAnotherThread()
  47.150 {
  47.151     return pImpl->IsLockedByAnotherThread(this);
  47.152 }
  47.153 
  47.154 //-----------------------------------------------------------------------------------
  47.155 // ***** Event
  47.156 
  47.157 bool Event::Wait(unsigned delay)
  47.158 {
  47.159     Mutex::Locker lock(&StateMutex);
  47.160 
  47.161     // Do the correct amount of waiting
  47.162     if (delay == OVR_WAIT_INFINITE)
  47.163     {
  47.164         while(!State)
  47.165             StateWaitCondition.Wait(&StateMutex);
  47.166     }
  47.167     else if (delay)
  47.168     {
  47.169         if (!State)
  47.170             StateWaitCondition.Wait(&StateMutex, delay);
  47.171     }
  47.172 
  47.173     bool state = State;
  47.174     // Take care of temporary 'pulsing' of a state
  47.175     if (Temporary)
  47.176     {
  47.177         Temporary   = false;
  47.178         State       = false;
  47.179     }
  47.180     return state;
  47.181 }
  47.182 
  47.183 void Event::updateState(bool newState, bool newTemp, bool mustNotify)
  47.184 {
  47.185     Mutex::Locker lock(&StateMutex);
  47.186     State       = newState;
  47.187     Temporary   = newTemp;
  47.188     if (mustNotify)
  47.189         StateWaitCondition.NotifyAll();    
  47.190 }
  47.191 
  47.192 
  47.193 //-----------------------------------------------------------------------------------
  47.194 // ***** Win32 Wait Condition Implementation
  47.195 
  47.196 // Internal implementation class
  47.197 class WaitConditionImpl : public NewOverrideBase
  47.198 {   
  47.199     // Event pool entries for extra events
  47.200     struct EventPoolEntry  : public NewOverrideBase
  47.201     {
  47.202         HANDLE          hEvent;
  47.203         EventPoolEntry  *pNext;
  47.204         EventPoolEntry  *pPrev;
  47.205     };
  47.206     
  47.207     Lock                WaitQueueLoc;
  47.208     // Stores free events that can be used later
  47.209     EventPoolEntry  *   pFreeEventList;
  47.210     
  47.211     // A queue of waiting objects to be signaled    
  47.212     EventPoolEntry*     pQueueHead;
  47.213     EventPoolEntry*     pQueueTail;
  47.214 
  47.215     // Allocation functions for free events
  47.216     EventPoolEntry*     GetNewEvent();
  47.217     void                ReleaseEvent(EventPoolEntry* pevent);
  47.218 
  47.219     // Queue operations
  47.220     void                QueuePush(EventPoolEntry* pentry);
  47.221     EventPoolEntry*     QueuePop();
  47.222     void                QueueFindAndRemove(EventPoolEntry* pentry);
  47.223 
  47.224 public:
  47.225 
  47.226     // Constructor/destructor
  47.227     WaitConditionImpl();
  47.228     ~WaitConditionImpl();
  47.229 
  47.230     // Release mutex and wait for condition. The mutex is re-acqured after the wait.
  47.231     bool    Wait(Mutex *pmutex, unsigned delay = OVR_WAIT_INFINITE);
  47.232 
  47.233     // Notify a condition, releasing at one object waiting
  47.234     void    Notify();
  47.235     // Notify a condition, releasing all objects waiting
  47.236     void    NotifyAll();
  47.237 };
  47.238 
  47.239 
  47.240 
  47.241 WaitConditionImpl::WaitConditionImpl()
  47.242 {
  47.243     pFreeEventList  = 0;
  47.244     pQueueHead      =
  47.245     pQueueTail      = 0;
  47.246 }
  47.247 
  47.248 WaitConditionImpl::~WaitConditionImpl()
  47.249 {
  47.250     // Free all the resources
  47.251     EventPoolEntry* p       = pFreeEventList;
  47.252     EventPoolEntry* pentry;
  47.253 
  47.254     while(p)
  47.255     {
  47.256         // Move to next
  47.257         pentry = p;
  47.258         p = p->pNext;
  47.259         // Delete old
  47.260         ::CloseHandle(pentry->hEvent);
  47.261         delete pentry;  
  47.262     }   
  47.263     // Shouldn't we also consider the queue?
  47.264 
  47.265     // To be safe
  47.266     pFreeEventList  = 0;
  47.267     pQueueHead      =
  47.268     pQueueTail      = 0;
  47.269 }
  47.270 
  47.271 
  47.272 // Allocation functions for free events
  47.273 WaitConditionImpl::EventPoolEntry* WaitConditionImpl::GetNewEvent()
  47.274 {
  47.275     EventPoolEntry* pentry;
  47.276 
  47.277     // If there are any free nodes, use them
  47.278     if (pFreeEventList)
  47.279     {
  47.280         pentry          = pFreeEventList;
  47.281         pFreeEventList  = pFreeEventList->pNext;        
  47.282     }
  47.283     else
  47.284     {
  47.285         // Allocate a new node
  47.286         pentry          = new EventPoolEntry;
  47.287         pentry->pNext   = 0;
  47.288         pentry->pPrev   = 0;
  47.289         // Non-signaled manual event
  47.290         pentry->hEvent  = ::CreateEvent(NULL, TRUE, 0, NULL);
  47.291     }
  47.292     
  47.293     return pentry;
  47.294 }
  47.295 
  47.296 void WaitConditionImpl::ReleaseEvent(EventPoolEntry* pevent)
  47.297 {
  47.298     // Mark event as non-signaled
  47.299     ::ResetEvent(pevent->hEvent);
  47.300     // And add it to free pool
  47.301     pevent->pNext   = pFreeEventList;
  47.302     pevent->pPrev   = 0;
  47.303     pFreeEventList  = pevent;
  47.304 }
  47.305 
  47.306 // Queue operations
  47.307 void WaitConditionImpl::QueuePush(EventPoolEntry* pentry)
  47.308 {
  47.309     // Items already exist? Just add to tail
  47.310     if (pQueueTail)
  47.311     {
  47.312         pentry->pPrev       = pQueueTail;
  47.313         pQueueTail->pNext   = pentry;
  47.314         pentry->pNext       = 0;        
  47.315         pQueueTail          = pentry;       
  47.316     }
  47.317     else
  47.318     {
  47.319         // No items in queue
  47.320         pentry->pNext   = 
  47.321         pentry->pPrev   = 0;
  47.322         pQueueHead      =
  47.323         pQueueTail      = pentry;
  47.324     }
  47.325 }
  47.326 
  47.327 WaitConditionImpl::EventPoolEntry* WaitConditionImpl::QueuePop()
  47.328 {
  47.329     EventPoolEntry* pentry = pQueueHead;
  47.330 
  47.331     // No items, null pointer
  47.332     if (pentry)
  47.333     {
  47.334         // More items after this one? just grab the first item
  47.335         if (pQueueHead->pNext)
  47.336         {       
  47.337             pQueueHead  = pentry->pNext;
  47.338             pQueueHead->pPrev = 0;      
  47.339         }
  47.340         else
  47.341         {
  47.342             // Last item left
  47.343             pQueueTail =
  47.344             pQueueHead = 0;
  47.345         }
  47.346     }   
  47.347     return pentry;
  47.348 }
  47.349 
  47.350 void WaitConditionImpl::QueueFindAndRemove(EventPoolEntry* pentry)
  47.351 {
  47.352     // Do an exhaustive search looking for an entry
  47.353     EventPoolEntry* p = pQueueHead;
  47.354 
  47.355     while(p)
  47.356     {
  47.357         // Entry found? Remove.
  47.358         if (p == pentry)
  47.359         {
  47.360             
  47.361             // Remove the node form the list
  47.362             // Prev link
  47.363             if (pentry->pPrev)
  47.364                 pentry->pPrev->pNext = pentry->pNext;
  47.365             else
  47.366                 pQueueHead = pentry->pNext;
  47.367             // Next link
  47.368             if (pentry->pNext)
  47.369                 pentry->pNext->pPrev = pentry->pPrev;
  47.370             else
  47.371                 pQueueTail = pentry->pPrev;
  47.372             // Done
  47.373             return;
  47.374         }
  47.375 
  47.376         // Move to next item
  47.377         p = p->pNext;
  47.378     }
  47.379 }
  47.380     
  47.381 
  47.382 bool WaitConditionImpl::Wait(Mutex *pmutex, unsigned delay)
  47.383 {
  47.384     bool            result = 0;
  47.385     unsigned        i;
  47.386     unsigned        lockCount = pmutex->pImpl->LockCount;
  47.387     EventPoolEntry* pentry;
  47.388 
  47.389     // Mutex must have been locked
  47.390     if (lockCount == 0)
  47.391         return 0;
  47.392     
  47.393     // Add an object to the wait queue
  47.394     WaitQueueLoc.DoLock();
  47.395     QueuePush(pentry = GetNewEvent());
  47.396     WaitQueueLoc.Unlock();
  47.397 
  47.398     // Finally, release a mutex or semaphore
  47.399     if (pmutex->pImpl->Recursive)
  47.400     {
  47.401         // Release the recursive mutex N times
  47.402         pmutex->pImpl->LockCount = 0;
  47.403         for(i=0; i<lockCount; i++)
  47.404             ::ReleaseMutex(pmutex->pImpl->hMutexOrSemaphore);
  47.405     }
  47.406     else
  47.407     {
  47.408         pmutex->pImpl->LockCount = 0;
  47.409         ::ReleaseSemaphore(pmutex->pImpl->hMutexOrSemaphore, 1, NULL);
  47.410     }
  47.411 
  47.412     // Note that there is a gap here between mutex.Unlock() and Wait(). However,
  47.413     // if notify() comes in at this point in the other thread it will set our
  47.414     // corresponding event so wait will just fall through, as expected.
  47.415 
  47.416     // Block and wait on the event
  47.417     DWORD waitResult = ::WaitForSingleObject(pentry->hEvent,
  47.418                             (delay == OVR_WAIT_INFINITE) ? INFINITE : delay);
  47.419     /*
  47.420 repeat_wait:
  47.421     DWORD waitResult =
  47.422 
  47.423     ::MsgWaitForMultipleObjects(1, &pentry->hEvent, FALSE,
  47.424                                 (delay == OVR_WAIT_INFINITE) ? INFINITE : delay,
  47.425                                 QS_ALLINPUT);
  47.426     */
  47.427 
  47.428     WaitQueueLoc.DoLock();
  47.429     switch(waitResult)
  47.430     {
  47.431         case WAIT_ABANDONED:
  47.432         case WAIT_OBJECT_0: 
  47.433             result = 1;
  47.434             // Wait was successful, therefore the event entry should already be removed
  47.435             // So just add entry back to a free list
  47.436             ReleaseEvent(pentry);
  47.437             break;
  47.438             /*
  47.439         case WAIT_OBJECT_0 + 1:
  47.440             // Messages in WINDOWS queue
  47.441             {
  47.442                 MSG msg;
  47.443                 PeekMessage(&msg, NULL, 0U, 0U, PM_NOREMOVE);             
  47.444                 WaitQueueLoc.Unlock();
  47.445                 goto repeat_wait;
  47.446             }
  47.447             break; */
  47.448         default:
  47.449             // Timeout, our entry should still be in a queue
  47.450             QueueFindAndRemove(pentry);
  47.451             ReleaseEvent(pentry);
  47.452     }
  47.453     WaitQueueLoc.Unlock();
  47.454 
  47.455     // Re-aquire the mutex
  47.456     for(i=0; i<lockCount; i++)
  47.457         pmutex->DoLock(); 
  47.458 
  47.459     // Return the result
  47.460     return result;
  47.461 }
  47.462 
  47.463 // Notify a condition, releasing the least object in a queue
  47.464 void WaitConditionImpl::Notify()
  47.465 {
  47.466     Lock::Locker   lock(&WaitQueueLoc);
  47.467     
  47.468     // Pop last entry & signal it
  47.469     EventPoolEntry* pentry = QueuePop();    
  47.470     if (pentry)
  47.471         ::SetEvent(pentry->hEvent); 
  47.472 }
  47.473 
  47.474 // Notify a condition, releasing all objects waiting
  47.475 void WaitConditionImpl::NotifyAll()
  47.476 {
  47.477     Lock::Locker   lock(&WaitQueueLoc);
  47.478 
  47.479     // Pop and signal all events
  47.480     // NOTE : There is no need to release the events, it's the waiters job to do so 
  47.481     EventPoolEntry* pentry = QueuePop();
  47.482     while (pentry)
  47.483     {
  47.484         ::SetEvent(pentry->hEvent);
  47.485         pentry = QueuePop();
  47.486     }
  47.487 }
  47.488 
  47.489 
  47.490 
  47.491 // *** Actual implementation of WaitCondition
  47.492 
  47.493 WaitCondition::WaitCondition()
  47.494 {
  47.495     pImpl = new WaitConditionImpl;
  47.496 }
  47.497 WaitCondition::~WaitCondition()
  47.498 {
  47.499     delete pImpl;
  47.500 }
  47.501     
  47.502 // Wait without a mutex
  47.503 bool    WaitCondition::Wait(Mutex *pmutex, unsigned delay)
  47.504 {
  47.505     return pImpl->Wait(pmutex, delay);
  47.506 }
  47.507 // Notification
  47.508 void    WaitCondition::Notify()
  47.509 {
  47.510     pImpl->Notify();
  47.511 }
  47.512 void    WaitCondition::NotifyAll()
  47.513 {
  47.514     pImpl->NotifyAll();
  47.515 }
  47.516 
  47.517 
  47.518 
  47.519 //-----------------------------------------------------------------------------------
  47.520 // ***** Thread Class
  47.521 
  47.522 //  Per-thread variable
  47.523 //  MA: Don't use TLS for now - portability issues with DLLs, etc.
  47.524 /*
  47.525 #if !defined(OVR_CC_MSVC) || (OVR_CC_MSVC < 1300)
  47.526 __declspec(thread)  Thread*    pCurrentThread      = 0;
  47.527 #else
  47.528 #pragma data_seg(".tls$")
  47.529 __declspec(thread)  Thread*    pCurrentThread      = 0;
  47.530 #pragma data_seg(".rwdata")
  47.531 #endif
  47.532 */
  47.533 
  47.534 // *** Thread constructors.
  47.535 
  47.536 Thread::Thread(UPInt stackSize, int processor)
  47.537 {    
  47.538     CreateParams params;
  47.539     params.stackSize = stackSize;
  47.540     params.processor = processor;
  47.541     Init(params);
  47.542 }
  47.543 
  47.544 Thread::Thread(Thread::ThreadFn threadFunction, void*  userHandle, UPInt stackSize, 
  47.545                  int processor, Thread::ThreadState initialState)
  47.546 {
  47.547     CreateParams params(threadFunction, userHandle, stackSize, processor, initialState);
  47.548     Init(params);
  47.549 }
  47.550 
  47.551 Thread::Thread(const CreateParams& params)
  47.552 {
  47.553     Init(params);
  47.554 }
  47.555 void Thread::Init(const CreateParams& params)
  47.556 {
  47.557     // Clear the variables    
  47.558     ThreadFlags     = 0;
  47.559     ThreadHandle    = 0;
  47.560     IdValue         = 0;
  47.561     ExitCode        = 0;
  47.562     SuspendCount    = 0;
  47.563     StackSize       = params.stackSize;
  47.564     Processor       = params.processor;
  47.565     Priority        = params.priority;
  47.566 
  47.567     // Clear Function pointers
  47.568     ThreadFunction  = params.threadFunction;
  47.569     UserHandle      = params.userHandle;
  47.570     if (params.initialState != NotRunning)
  47.571         Start(params.initialState);
  47.572 
  47.573 }
  47.574 
  47.575 Thread::~Thread()
  47.576 {
  47.577     // Thread should not running while object is being destroyed,
  47.578     // this would indicate ref-counting issue.
  47.579     //OVR_ASSERT(IsRunning() == 0);
  47.580   
  47.581     // Clean up thread.    
  47.582     CleanupSystemThread();
  47.583     ThreadHandle = 0;
  47.584 }
  47.585 
  47.586 
  47.587 // *** Overridable User functions.
  47.588 
  47.589 // Default Run implementation
  47.590 int Thread::Run()
  47.591 {
  47.592     // Call pointer to function, if available.    
  47.593     return (ThreadFunction) ? ThreadFunction(this, UserHandle) : 0;
  47.594 }
  47.595 void Thread::OnExit()
  47.596 {   
  47.597 }
  47.598 
  47.599 // Finishes the thread and releases internal reference to it.
  47.600 void Thread::FinishAndRelease()
  47.601 {
  47.602     // Note: thread must be US.
  47.603     ThreadFlags &= (UInt32)~(OVR_THREAD_STARTED);
  47.604     ThreadFlags |= OVR_THREAD_FINISHED;
  47.605 
  47.606     // Release our reference; this is equivalent to 'delete this'
  47.607     // from the point of view of our thread.
  47.608     Release();
  47.609 }
  47.610 
  47.611 
  47.612 // *** ThreadList - used to tack all created threads
  47.613 
  47.614 class ThreadList : public NewOverrideBase
  47.615 {
  47.616     //------------------------------------------------------------------------
  47.617     struct ThreadHashOp
  47.618     {
  47.619         UPInt operator()(const Thread* ptr)
  47.620         {
  47.621             return (((UPInt)ptr) >> 6) ^ (UPInt)ptr;
  47.622         }
  47.623     };
  47.624 
  47.625     HashSet<Thread*, ThreadHashOp>  ThreadSet;
  47.626     Mutex                           ThreadMutex;
  47.627     WaitCondition                   ThreadsEmpty;
  47.628     // Track the root thread that created us.
  47.629     ThreadId                        RootThreadId;
  47.630 
  47.631     static ThreadList* volatile pRunningThreads;
  47.632 
  47.633     void addThread(Thread *pthread)
  47.634     {
  47.635          Mutex::Locker lock(&ThreadMutex);
  47.636          ThreadSet.Add(pthread);
  47.637     }
  47.638 
  47.639     void removeThread(Thread *pthread)
  47.640     {
  47.641         Mutex::Locker lock(&ThreadMutex);
  47.642         ThreadSet.Remove(pthread);
  47.643         if (ThreadSet.GetSize() == 0)
  47.644             ThreadsEmpty.Notify();
  47.645     }
  47.646 
  47.647     void finishAllThreads()
  47.648     {
  47.649         // Only original root thread can call this.
  47.650         OVR_ASSERT(GetCurrentThreadId() == RootThreadId);
  47.651 
  47.652         Mutex::Locker lock(&ThreadMutex);
  47.653         while (ThreadSet.GetSize() != 0)
  47.654             ThreadsEmpty.Wait(&ThreadMutex);
  47.655     }
  47.656 
  47.657 public:
  47.658 
  47.659     ThreadList()
  47.660     {
  47.661         RootThreadId = GetCurrentThreadId();
  47.662     }
  47.663     ~ThreadList() { }
  47.664 
  47.665 
  47.666     static void AddRunningThread(Thread *pthread)
  47.667     {
  47.668         // Non-atomic creation ok since only the root thread
  47.669         if (!pRunningThreads)
  47.670         {
  47.671             pRunningThreads = new ThreadList;
  47.672             OVR_ASSERT(pRunningThreads);
  47.673         }
  47.674         pRunningThreads->addThread(pthread);
  47.675     }
  47.676 
  47.677     // NOTE: 'pthread' might be a dead pointer when this is
  47.678     // called so it should not be accessed; it is only used
  47.679     // for removal.
  47.680     static void RemoveRunningThread(Thread *pthread)
  47.681     {
  47.682         OVR_ASSERT(pRunningThreads);        
  47.683         pRunningThreads->removeThread(pthread);
  47.684     }
  47.685 
  47.686     static void FinishAllThreads()
  47.687     {
  47.688         // This is ok because only root thread can wait for other thread finish.
  47.689         if (pRunningThreads)
  47.690         {           
  47.691             pRunningThreads->finishAllThreads();
  47.692             delete pRunningThreads;
  47.693             pRunningThreads = 0;
  47.694         }        
  47.695     }
  47.696 };
  47.697 
  47.698 // By default, we have no thread list.
  47.699 ThreadList* volatile ThreadList::pRunningThreads = 0;
  47.700 
  47.701 
  47.702 // FinishAllThreads - exposed publicly in Thread.
  47.703 void Thread::FinishAllThreads()
  47.704 {
  47.705     ThreadList::FinishAllThreads();
  47.706 }
  47.707 
  47.708 
  47.709 // *** Run override
  47.710 
  47.711 int Thread::PRun()
  47.712 {
  47.713     // Suspend us on start, if requested
  47.714     if (ThreadFlags & OVR_THREAD_START_SUSPENDED)
  47.715     {
  47.716         Suspend();
  47.717         ThreadFlags &= (UInt32)~OVR_THREAD_START_SUSPENDED;
  47.718     }
  47.719 
  47.720     // Call the virtual run function
  47.721     ExitCode = Run();    
  47.722     return ExitCode;
  47.723 }
  47.724 
  47.725 
  47.726 
  47.727 /* MA: Don't use TLS for now.
  47.728 
  47.729 // Static function to return a pointer to the current thread
  47.730 void    Thread::InitCurrentThread(Thread *pthread)
  47.731 {
  47.732     pCurrentThread = pthread;
  47.733 }
  47.734 
  47.735 // Static function to return a pointer to the current thread
  47.736 Thread*    Thread::GetThread()
  47.737 {
  47.738     return pCurrentThread;
  47.739 }
  47.740 */
  47.741 
  47.742 
  47.743 // *** User overridables
  47.744 
  47.745 bool    Thread::GetExitFlag() const
  47.746 {
  47.747     return (ThreadFlags & OVR_THREAD_EXIT) != 0;
  47.748 }       
  47.749 
  47.750 void    Thread::SetExitFlag(bool exitFlag)
  47.751 {
  47.752     // The below is atomic since ThreadFlags is AtomicInt.
  47.753     if (exitFlag)
  47.754         ThreadFlags |= OVR_THREAD_EXIT;
  47.755     else
  47.756         ThreadFlags &= (UInt32) ~OVR_THREAD_EXIT;
  47.757 }
  47.758 
  47.759 
  47.760 // Determines whether the thread was running and is now finished
  47.761 bool    Thread::IsFinished() const
  47.762 {
  47.763     return (ThreadFlags & OVR_THREAD_FINISHED) != 0;
  47.764 }
  47.765 // Determines whether the thread is suspended
  47.766 bool    Thread::IsSuspended() const
  47.767 {   
  47.768     return SuspendCount > 0;
  47.769 }
  47.770 // Returns current thread state
  47.771 Thread::ThreadState Thread::GetThreadState() const
  47.772 {
  47.773     if (IsSuspended())
  47.774         return Suspended;    
  47.775     if (ThreadFlags & OVR_THREAD_STARTED)
  47.776         return Running;    
  47.777     return NotRunning;
  47.778 }
  47.779 
  47.780 
  47.781 
  47.782 // ***** Thread management
  47.783 /* static */
  47.784 int Thread::GetOSPriority(ThreadPriority p)
  47.785 {
  47.786     switch(p)
  47.787     {
  47.788     case Thread::CriticalPriority:      return THREAD_PRIORITY_TIME_CRITICAL;
  47.789     case Thread::HighestPriority:       return THREAD_PRIORITY_HIGHEST;
  47.790     case Thread::AboveNormalPriority:   return THREAD_PRIORITY_ABOVE_NORMAL;
  47.791     case Thread::NormalPriority:        return THREAD_PRIORITY_NORMAL;
  47.792     case Thread::BelowNormalPriority:   return THREAD_PRIORITY_BELOW_NORMAL;
  47.793     case Thread::LowestPriority:        return THREAD_PRIORITY_LOWEST;
  47.794     case Thread::IdlePriority:          return THREAD_PRIORITY_IDLE;
  47.795     }
  47.796     return THREAD_PRIORITY_NORMAL;
  47.797 }
  47.798 
  47.799 // The actual first function called on thread start
  47.800 unsigned WINAPI Thread_Win32StartFn(void * phandle)
  47.801 {
  47.802     Thread *   pthread = (Thread*)phandle;
  47.803     if (pthread->Processor != -1)
  47.804     {
  47.805         DWORD_PTR ret = SetThreadAffinityMask(GetCurrentThread(), (DWORD)pthread->Processor);
  47.806         if (ret == 0)
  47.807             OVR_DEBUG_LOG(("Could not set hardware processor for the thread"));
  47.808     }
  47.809     BOOL ret = ::SetThreadPriority(GetCurrentThread(), Thread::GetOSPriority(pthread->Priority));
  47.810     if (ret == 0)
  47.811         OVR_DEBUG_LOG(("Could not set thread priority"));
  47.812     OVR_UNUSED(ret);
  47.813 
  47.814     // Ensure that ThreadId is assigned once thread is running, in case
  47.815     // beginthread hasn't filled it in yet.
  47.816     pthread->IdValue = (ThreadId)::GetCurrentThreadId();
  47.817 
  47.818     DWORD       result = pthread->PRun();
  47.819     // Signal the thread as done and release it atomically.
  47.820     pthread->FinishAndRelease();
  47.821     // At this point Thread object might be dead; however we can still pass
  47.822     // it to RemoveRunningThread since it is only used as a key there.    
  47.823     ThreadList::RemoveRunningThread(pthread);
  47.824     return (unsigned) result;
  47.825 }
  47.826 
  47.827 bool Thread::Start(ThreadState initialState)
  47.828 {
  47.829     if (initialState == NotRunning)
  47.830         return 0;
  47.831     if (GetThreadState() != NotRunning)
  47.832     {
  47.833         OVR_DEBUG_LOG(("Thread::Start failed - thread %p already running", this));
  47.834         return 0;
  47.835     }
  47.836 
  47.837     // Free old thread handle before creating the new one
  47.838     CleanupSystemThread();
  47.839 
  47.840     // AddRef to us until the thread is finished.
  47.841     AddRef();
  47.842     ThreadList::AddRunningThread(this);
  47.843     
  47.844     ExitCode        = 0;
  47.845     SuspendCount    = 0;
  47.846     ThreadFlags     = (initialState == Running) ? 0 : OVR_THREAD_START_SUSPENDED;
  47.847     ThreadHandle = (HANDLE) _beginthreadex(0, (unsigned)StackSize,
  47.848                                            Thread_Win32StartFn, this, 0, (unsigned*)&IdValue);
  47.849 
  47.850     // Failed? Fail the function
  47.851     if (ThreadHandle == 0)
  47.852     {
  47.853         ThreadFlags = 0;
  47.854         Release();
  47.855         ThreadList::RemoveRunningThread(this);
  47.856         return 0;
  47.857     }
  47.858     return 1;
  47.859 }
  47.860 
  47.861 
  47.862 // Suspend the thread until resumed
  47.863 bool Thread::Suspend()
  47.864 {
  47.865     // Can't suspend a thread that wasn't started
  47.866     if (!(ThreadFlags & OVR_THREAD_STARTED))
  47.867         return 0;
  47.868 
  47.869     if (::SuspendThread(ThreadHandle) != 0xFFFFFFFF)
  47.870     {        
  47.871         SuspendCount++;        
  47.872         return 1;
  47.873     }
  47.874     return 0;
  47.875 }
  47.876 
  47.877 // Resumes currently suspended thread
  47.878 bool Thread::Resume()
  47.879 {
  47.880     // Can't suspend a thread that wasn't started
  47.881     if (!(ThreadFlags & OVR_THREAD_STARTED))
  47.882         return 0;
  47.883 
  47.884     // Decrement count, and resume thread if it is 0
  47.885     SInt32 oldCount = SuspendCount.ExchangeAdd_Acquire(-1);
  47.886     if (oldCount >= 1)
  47.887     {
  47.888         if (oldCount == 1)
  47.889         {
  47.890             if (::ResumeThread(ThreadHandle) != 0xFFFFFFFF)            
  47.891                 return 1;            
  47.892         }
  47.893         else
  47.894         {
  47.895             return 1;
  47.896         }
  47.897     }   
  47.898     return 0;
  47.899 }
  47.900 
  47.901 
  47.902 // Quits with an exit code  
  47.903 void Thread::Exit(int exitCode)
  47.904 {
  47.905     // Can only exist the current thread.
  47.906     // MA: Don't use TLS for now.
  47.907     //if (GetThread() != this)
  47.908     //    return;
  47.909 
  47.910     // Call the virtual OnExit function.
  47.911     OnExit();   
  47.912 
  47.913     // Signal this thread object as done and release it's references.
  47.914     FinishAndRelease();
  47.915     ThreadList::RemoveRunningThread(this);
  47.916 
  47.917     // Call the exit function.    
  47.918     _endthreadex((unsigned)exitCode);
  47.919 }
  47.920 
  47.921 
  47.922 void Thread::CleanupSystemThread()
  47.923 {
  47.924     if (ThreadHandle != 0)
  47.925     {
  47.926         ::CloseHandle(ThreadHandle);
  47.927         ThreadHandle = 0;
  47.928     }
  47.929 }
  47.930 
  47.931 // *** Sleep functions
  47.932 // static
  47.933 bool Thread::Sleep(unsigned secs)
  47.934 {
  47.935     ::Sleep(secs*1000);
  47.936     return 1;
  47.937 }
  47.938 
  47.939 // static
  47.940 bool Thread::MSleep(unsigned msecs)
  47.941 {
  47.942     ::Sleep(msecs);
  47.943     return 1;
  47.944 }
  47.945 
  47.946 void Thread::SetThreadName( const char* name )
  47.947 {
  47.948 #if !defined(OVR_BUILD_SHIPPING) || defined(OVR_BUILD_PROFILING)
  47.949     // Looks ugly, but it is the recommended way to name a thread.
  47.950     typedef struct tagTHREADNAME_INFO {
  47.951         DWORD dwType;     // Must be 0x1000
  47.952         LPCSTR szName;    // Pointer to name (in user address space)
  47.953         DWORD dwThreadID; // Thread ID (-1 for caller thread)
  47.954         DWORD dwFlags;    // Reserved for future use; must be zero
  47.955     } THREADNAME_INFO;
  47.956 
  47.957     THREADNAME_INFO info;
  47.958 
  47.959     info.dwType = 0x1000;
  47.960     info.szName = name;
  47.961     info.dwThreadID = reinterpret_cast<DWORD>(GetThreadId());
  47.962     info.dwFlags = 0;
  47.963 
  47.964     __try
  47.965     {
  47.966 #ifdef _WIN64
  47.967         RaiseException( 0x406D1388, 0, sizeof(info)/sizeof(DWORD), (const ULONG_PTR *)&info );
  47.968 #else
  47.969         RaiseException( 0x406D1388, 0, sizeof(info)/sizeof(DWORD), (DWORD *)&info );
  47.970 #endif
  47.971     }
  47.972     __except( GetExceptionCode()==0x406D1388 ? EXCEPTION_CONTINUE_EXECUTION : EXCEPTION_EXECUTE_HANDLER )
  47.973     {
  47.974     }
  47.975 #endif // OVR_BUILD_SHIPPING
  47.976 }
  47.977 
  47.978 // static
  47.979 int  Thread::GetCPUCount()
  47.980 {
  47.981     SYSTEM_INFO sysInfo;
  47.982     GetSystemInfo(&sysInfo);
  47.983     return (int) sysInfo.dwNumberOfProcessors;
  47.984 }
  47.985 
  47.986 // Returns the unique Id of a thread it is called on, intended for
  47.987 // comparison purposes.
  47.988 ThreadId GetCurrentThreadId()
  47.989 {
  47.990     return (ThreadId)::GetCurrentThreadId();
  47.991 }
  47.992 
  47.993 } // OVR
  47.994 
  47.995 #endif
  47.996 
  47.997 
  47.998 \ No newline at end of file
  47.999 +/************************************************************************************
 47.1000 +
 47.1001 +Filename    :   OVR_ThreadsWinAPI.cpp
 47.1002 +Platform    :   WinAPI
 47.1003 +Content     :   Windows specific thread-related (safe) functionality
 47.1004 +Created     :   September 19, 2012
 47.1005 +Notes       : 
 47.1006 +
 47.1007 +Copyright   :   Copyright 2012 Oculus VR, Inc. All Rights reserved.
 47.1008 +
 47.1009 +Use of this software is subject to the terms of the Oculus license
 47.1010 +agreement provided at the time of installation or download, or which
 47.1011 +otherwise accompanies this software in either electronic or hard copy form.
 47.1012 +
 47.1013 +************************************************************************************/
 47.1014 +
 47.1015 +#include "OVR_Threads.h"
 47.1016 +#include "OVR_Hash.h"
 47.1017 +#include "OVR_Log.h"
 47.1018 +
 47.1019 +#ifdef OVR_ENABLE_THREADS
 47.1020 +
 47.1021 +// For _beginthreadex / _endtheadex
 47.1022 +#include <process.h>
 47.1023 +
 47.1024 +namespace OVR {
 47.1025 +
 47.1026 +
 47.1027 +//-----------------------------------------------------------------------------------
 47.1028 +// *** Internal Mutex implementation class
 47.1029 +
 47.1030 +class MutexImpl : public NewOverrideBase
 47.1031 +{
 47.1032 +    // System mutex or semaphore
 47.1033 +    HANDLE            hMutexOrSemaphore;
 47.1034 +    bool              Recursive;
 47.1035 +    volatile unsigned LockCount;
 47.1036 +    
 47.1037 +    friend class WaitConditionImpl;
 47.1038 +
 47.1039 +public:
 47.1040 +    // Constructor/destructor
 47.1041 +    MutexImpl(bool recursive = 1);
 47.1042 +    ~MutexImpl();
 47.1043 +
 47.1044 +    // Locking functions
 47.1045 +    void                DoLock();
 47.1046 +    bool                TryLock();
 47.1047 +    void                Unlock(Mutex* pmutex);
 47.1048 +    // Returns 1 if the mutes is currently locked
 47.1049 +    bool                IsLockedByAnotherThread(Mutex* pmutex);
 47.1050 +};
 47.1051 +
 47.1052 +// *** Constructor/destructor
 47.1053 +MutexImpl::MutexImpl(bool recursive)
 47.1054 +{    
 47.1055 +    Recursive                   = recursive;
 47.1056 +    LockCount                   = 0;
 47.1057 +    hMutexOrSemaphore           = Recursive ? CreateMutex(NULL, 0, NULL) : CreateSemaphore(NULL, 1, 1, NULL);
 47.1058 +}
 47.1059 +MutexImpl::~MutexImpl()
 47.1060 +{
 47.1061 +    CloseHandle(hMutexOrSemaphore);
 47.1062 +}
 47.1063 +
 47.1064 +
 47.1065 +// Lock and try lock
 47.1066 +void MutexImpl::DoLock()
 47.1067 +{
 47.1068 +    if (::WaitForSingleObject(hMutexOrSemaphore, INFINITE) != WAIT_OBJECT_0)
 47.1069 +        return;
 47.1070 +    LockCount++;
 47.1071 +}
 47.1072 +
 47.1073 +bool MutexImpl::TryLock()
 47.1074 +{
 47.1075 +    DWORD ret;
 47.1076 +    if ((ret=::WaitForSingleObject(hMutexOrSemaphore, 0)) != WAIT_OBJECT_0)
 47.1077 +        return 0;
 47.1078 +    LockCount++;
 47.1079 +    return 1;
 47.1080 +}
 47.1081 +
 47.1082 +void MutexImpl::Unlock(Mutex* pmutex)
 47.1083 +{
 47.1084 +    OVR_UNUSED(pmutex);
 47.1085 +
 47.1086 +    unsigned lockCount;
 47.1087 +    LockCount--;
 47.1088 +    lockCount = LockCount;
 47.1089 +
 47.1090 +    // Release mutex
 47.1091 +    if ((Recursive ? ReleaseMutex(hMutexOrSemaphore) :
 47.1092 +                     ReleaseSemaphore(hMutexOrSemaphore, 1, NULL))  != 0)
 47.1093 +    {
 47.1094 +        // This used to call Wait handlers if lockCount == 0.
 47.1095 +    }
 47.1096 +}
 47.1097 +
 47.1098 +bool MutexImpl::IsLockedByAnotherThread(Mutex* pmutex)
 47.1099 +{
 47.1100 +    // There could be multiple interpretations of IsLocked with respect to current thread
 47.1101 +    if (LockCount == 0)
 47.1102 +        return 0;
 47.1103 +    if (!TryLock())
 47.1104 +        return 1;
 47.1105 +    Unlock(pmutex);
 47.1106 +    return 0;
 47.1107 +}
 47.1108 +
 47.1109 +/*
 47.1110 +bool    MutexImpl::IsSignaled() const
 47.1111 +{
 47.1112 +    // An mutex is signaled if it is not locked ANYWHERE
 47.1113 +    // Note that this is different from IsLockedByAnotherThread function,
 47.1114 +    // that takes current thread into account
 47.1115 +    return LockCount == 0;
 47.1116 +}
 47.1117 +*/
 47.1118 +
 47.1119 +
 47.1120 +// *** Actual Mutex class implementation
 47.1121 +
 47.1122 +Mutex::Mutex(bool recursive)
 47.1123 +{    
 47.1124 +    pImpl = new MutexImpl(recursive);
 47.1125 +}
 47.1126 +Mutex::~Mutex()
 47.1127 +{
 47.1128 +    delete pImpl;
 47.1129 +}
 47.1130 +
 47.1131 +// Lock and try lock
 47.1132 +void Mutex::DoLock()
 47.1133 +{
 47.1134 +    pImpl->DoLock();
 47.1135 +}
 47.1136 +bool Mutex::TryLock()
 47.1137 +{
 47.1138 +    return pImpl->TryLock();
 47.1139 +}
 47.1140 +void Mutex::Unlock()
 47.1141 +{
 47.1142 +    pImpl->Unlock(this);
 47.1143 +}
 47.1144 +bool Mutex::IsLockedByAnotherThread()
 47.1145 +{
 47.1146 +    return pImpl->IsLockedByAnotherThread(this);
 47.1147 +}
 47.1148 +
 47.1149 +//-----------------------------------------------------------------------------------
 47.1150 +// ***** Event
 47.1151 +
 47.1152 +bool Event::Wait(unsigned delay)
 47.1153 +{
 47.1154 +    Mutex::Locker lock(&StateMutex);
 47.1155 +
 47.1156 +    // Do the correct amount of waiting
 47.1157 +    if (delay == OVR_WAIT_INFINITE)
 47.1158 +    {
 47.1159 +        while(!State)
 47.1160 +            StateWaitCondition.Wait(&StateMutex);
 47.1161 +    }
 47.1162 +    else if (delay)
 47.1163 +    {
 47.1164 +        if (!State)
 47.1165 +            StateWaitCondition.Wait(&StateMutex, delay);
 47.1166 +    }
 47.1167 +
 47.1168 +    bool state = State;
 47.1169 +    // Take care of temporary 'pulsing' of a state
 47.1170 +    if (Temporary)
 47.1171 +    {
 47.1172 +        Temporary   = false;
 47.1173 +        State       = false;
 47.1174 +    }
 47.1175 +    return state;
 47.1176 +}
 47.1177 +
 47.1178 +void Event::updateState(bool newState, bool newTemp, bool mustNotify)
 47.1179 +{
 47.1180 +    Mutex::Locker lock(&StateMutex);
 47.1181 +    State       = newState;
 47.1182 +    Temporary   = newTemp;
 47.1183 +    if (mustNotify)
 47.1184 +        StateWaitCondition.NotifyAll();    
 47.1185 +}
 47.1186 +
 47.1187 +
 47.1188 +//-----------------------------------------------------------------------------------
 47.1189 +// ***** Win32 Wait Condition Implementation
 47.1190 +
 47.1191 +// Internal implementation class
 47.1192 +class WaitConditionImpl : public NewOverrideBase
 47.1193 +{   
 47.1194 +    // Event pool entries for extra events
 47.1195 +    struct EventPoolEntry  : public NewOverrideBase
 47.1196 +    {
 47.1197 +        HANDLE          hEvent;
 47.1198 +        EventPoolEntry  *pNext;
 47.1199 +        EventPoolEntry  *pPrev;
 47.1200 +    };
 47.1201 +    
 47.1202 +    Lock                WaitQueueLoc;
 47.1203 +    // Stores free events that can be used later
 47.1204 +    EventPoolEntry  *   pFreeEventList;
 47.1205 +    
 47.1206 +    // A queue of waiting objects to be signaled    
 47.1207 +    EventPoolEntry*     pQueueHead;
 47.1208 +    EventPoolEntry*     pQueueTail;
 47.1209 +
 47.1210 +    // Allocation functions for free events
 47.1211 +    EventPoolEntry*     GetNewEvent();
 47.1212 +    void                ReleaseEvent(EventPoolEntry* pevent);
 47.1213 +
 47.1214 +    // Queue operations
 47.1215 +    void                QueuePush(EventPoolEntry* pentry);
 47.1216 +    EventPoolEntry*     QueuePop();
 47.1217 +    void                QueueFindAndRemove(EventPoolEntry* pentry);
 47.1218 +
 47.1219 +public:
 47.1220 +
 47.1221 +    // Constructor/destructor
 47.1222 +    WaitConditionImpl();
 47.1223 +    ~WaitConditionImpl();
 47.1224 +
 47.1225 +    // Release mutex and wait for condition. The mutex is re-acqured after the wait.
 47.1226 +    bool    Wait(Mutex *pmutex, unsigned delay = OVR_WAIT_INFINITE);
 47.1227 +
 47.1228 +    // Notify a condition, releasing at one object waiting
 47.1229 +    void    Notify();
 47.1230 +    // Notify a condition, releasing all objects waiting
 47.1231 +    void    NotifyAll();
 47.1232 +};
 47.1233 +
 47.1234 +
 47.1235 +
 47.1236 +WaitConditionImpl::WaitConditionImpl()
 47.1237 +{
 47.1238 +    pFreeEventList  = 0;
 47.1239 +    pQueueHead      =
 47.1240 +    pQueueTail      = 0;
 47.1241 +}
 47.1242 +
 47.1243 +WaitConditionImpl::~WaitConditionImpl()
 47.1244 +{
 47.1245 +    // Free all the resources
 47.1246 +    EventPoolEntry* p       = pFreeEventList;
 47.1247 +    EventPoolEntry* pentry;
 47.1248 +
 47.1249 +    while(p)
 47.1250 +    {
 47.1251 +        // Move to next
 47.1252 +        pentry = p;
 47.1253 +        p = p->pNext;
 47.1254 +        // Delete old
 47.1255 +        ::CloseHandle(pentry->hEvent);
 47.1256 +        delete pentry;  
 47.1257 +    }   
 47.1258 +    // Shouldn't we also consider the queue?
 47.1259 +
 47.1260 +    // To be safe
 47.1261 +    pFreeEventList  = 0;
 47.1262 +    pQueueHead      =
 47.1263 +    pQueueTail      = 0;
 47.1264 +}
 47.1265 +
 47.1266 +
 47.1267 +// Allocation functions for free events
 47.1268 +WaitConditionImpl::EventPoolEntry* WaitConditionImpl::GetNewEvent()
 47.1269 +{
 47.1270 +    EventPoolEntry* pentry;
 47.1271 +
 47.1272 +    // If there are any free nodes, use them
 47.1273 +    if (pFreeEventList)
 47.1274 +    {
 47.1275 +        pentry          = pFreeEventList;
 47.1276 +        pFreeEventList  = pFreeEventList->pNext;        
 47.1277 +    }
 47.1278 +    else
 47.1279 +    {
 47.1280 +        // Allocate a new node
 47.1281 +        pentry          = new EventPoolEntry;
 47.1282 +        pentry->pNext   = 0;
 47.1283 +        pentry->pPrev   = 0;
 47.1284 +        // Non-signaled manual event
 47.1285 +        pentry->hEvent  = ::CreateEvent(NULL, TRUE, 0, NULL);
 47.1286 +    }
 47.1287 +    
 47.1288 +    return pentry;
 47.1289 +}
 47.1290 +
 47.1291 +void WaitConditionImpl::ReleaseEvent(EventPoolEntry* pevent)
 47.1292 +{
 47.1293 +    // Mark event as non-signaled
 47.1294 +    ::ResetEvent(pevent->hEvent);
 47.1295 +    // And add it to free pool
 47.1296 +    pevent->pNext   = pFreeEventList;
 47.1297 +    pevent->pPrev   = 0;
 47.1298 +    pFreeEventList  = pevent;
 47.1299 +}
 47.1300 +
 47.1301 +// Queue operations
 47.1302 +void WaitConditionImpl::QueuePush(EventPoolEntry* pentry)
 47.1303 +{
 47.1304 +    // Items already exist? Just add to tail
 47.1305 +    if (pQueueTail)
 47.1306 +    {
 47.1307 +        pentry->pPrev       = pQueueTail;
 47.1308 +        pQueueTail->pNext   = pentry;
 47.1309 +        pentry->pNext       = 0;        
 47.1310 +        pQueueTail          = pentry;       
 47.1311 +    }
 47.1312 +    else
 47.1313 +    {
 47.1314 +        // No items in queue
 47.1315 +        pentry->pNext   = 
 47.1316 +        pentry->pPrev   = 0;
 47.1317 +        pQueueHead      =
 47.1318 +        pQueueTail      = pentry;
 47.1319 +    }
 47.1320 +}
 47.1321 +
 47.1322 +WaitConditionImpl::EventPoolEntry* WaitConditionImpl::QueuePop()
 47.1323 +{
 47.1324 +    EventPoolEntry* pentry = pQueueHead;
 47.1325 +
 47.1326 +    // No items, null pointer
 47.1327 +    if (pentry)
 47.1328 +    {
 47.1329 +        // More items after this one? just grab the first item
 47.1330 +        if (pQueueHead->pNext)
 47.1331 +        {       
 47.1332 +            pQueueHead  = pentry->pNext;
 47.1333 +            pQueueHead->pPrev = 0;      
 47.1334 +        }
 47.1335 +        else
 47.1336 +        {
 47.1337 +            // Last item left
 47.1338 +            pQueueTail =
 47.1339 +            pQueueHead = 0;
 47.1340 +        }
 47.1341 +    }   
 47.1342 +    return pentry;
 47.1343 +}
 47.1344 +
 47.1345 +void WaitConditionImpl::QueueFindAndRemove(EventPoolEntry* pentry)
 47.1346 +{
 47.1347 +    // Do an exhaustive search looking for an entry
 47.1348 +    EventPoolEntry* p = pQueueHead;
 47.1349 +
 47.1350 +    while(p)
 47.1351 +    {
 47.1352 +        // Entry found? Remove.
 47.1353 +        if (p == pentry)
 47.1354 +        {
 47.1355 +            
 47.1356 +            // Remove the node form the list
 47.1357 +            // Prev link
 47.1358 +            if (pentry->pPrev)
 47.1359 +                pentry->pPrev->pNext = pentry->pNext;
 47.1360 +            else
 47.1361 +                pQueueHead = pentry->pNext;
 47.1362 +            // Next link
 47.1363 +            if (pentry->pNext)
 47.1364 +                pentry->pNext->pPrev = pentry->pPrev;
 47.1365 +            else
 47.1366 +                pQueueTail = pentry->pPrev;
 47.1367 +            // Done
 47.1368 +            return;
 47.1369 +        }
 47.1370 +
 47.1371 +        // Move to next item
 47.1372 +        p = p->pNext;
 47.1373 +    }
 47.1374 +}
 47.1375 +    
 47.1376 +
 47.1377 +bool WaitConditionImpl::Wait(Mutex *pmutex, unsigned delay)
 47.1378 +{
 47.1379 +    bool            result = 0;
 47.1380 +    unsigned        i;
 47.1381 +    unsigned        lockCount = pmutex->pImpl->LockCount;
 47.1382 +    EventPoolEntry* pentry;
 47.1383 +
 47.1384 +    // Mutex must have been locked
 47.1385 +    if (lockCount == 0)
 47.1386 +        return 0;
 47.1387 +    
 47.1388 +    // Add an object to the wait queue
 47.1389 +    WaitQueueLoc.DoLock();
 47.1390 +    QueuePush(pentry = GetNewEvent());
 47.1391 +    WaitQueueLoc.Unlock();
 47.1392 +
 47.1393 +    // Finally, release a mutex or semaphore
 47.1394 +    if (pmutex->pImpl->Recursive)
 47.1395 +    {
 47.1396 +        // Release the recursive mutex N times
 47.1397 +        pmutex->pImpl->LockCount = 0;
 47.1398 +        for(i=0; i<lockCount; i++)
 47.1399 +            ::ReleaseMutex(pmutex->pImpl->hMutexOrSemaphore);
 47.1400 +    }
 47.1401 +    else
 47.1402 +    {
 47.1403 +        pmutex->pImpl->LockCount = 0;
 47.1404 +        ::ReleaseSemaphore(pmutex->pImpl->hMutexOrSemaphore, 1, NULL);
 47.1405 +    }
 47.1406 +
 47.1407 +    // Note that there is a gap here between mutex.Unlock() and Wait(). However,
 47.1408 +    // if notify() comes in at this point in the other thread it will set our
 47.1409 +    // corresponding event so wait will just fall through, as expected.
 47.1410 +
 47.1411 +    // Block and wait on the event
 47.1412 +    DWORD waitResult = ::WaitForSingleObject(pentry->hEvent,
 47.1413 +                            (delay == OVR_WAIT_INFINITE) ? INFINITE : delay);
 47.1414 +    /*
 47.1415 +repeat_wait:
 47.1416 +    DWORD waitResult =
 47.1417 +
 47.1418 +    ::MsgWaitForMultipleObjects(1, &pentry->hEvent, FALSE,
 47.1419 +                                (delay == OVR_WAIT_INFINITE) ? INFINITE : delay,
 47.1420 +                                QS_ALLINPUT);
 47.1421 +    */
 47.1422 +
 47.1423 +    WaitQueueLoc.DoLock();
 47.1424 +    switch(waitResult)
 47.1425 +    {
 47.1426 +        case WAIT_ABANDONED:
 47.1427 +        case WAIT_OBJECT_0: 
 47.1428 +            result = 1;
 47.1429 +            // Wait was successful, therefore the event entry should already be removed
 47.1430 +            // So just add entry back to a free list
 47.1431 +            ReleaseEvent(pentry);
 47.1432 +            break;
 47.1433 +            /*
 47.1434 +        case WAIT_OBJECT_0 + 1:
 47.1435 +            // Messages in WINDOWS queue
 47.1436 +            {
 47.1437 +                MSG msg;
 47.1438 +                PeekMessage(&msg, NULL, 0U, 0U, PM_NOREMOVE);             
 47.1439 +                WaitQueueLoc.Unlock();
 47.1440 +                goto repeat_wait;
 47.1441 +            }
 47.1442 +            break; */
 47.1443 +        default:
 47.1444 +            // Timeout, our entry should still be in a queue
 47.1445 +            QueueFindAndRemove(pentry);
 47.1446 +            ReleaseEvent(pentry);
 47.1447 +    }
 47.1448 +    WaitQueueLoc.Unlock();
 47.1449 +
 47.1450 +    // Re-aquire the mutex
 47.1451 +    for(i=0; i<lockCount; i++)
 47.1452 +        pmutex->DoLock(); 
 47.1453 +
 47.1454 +    // Return the result
 47.1455 +    return result;
 47.1456 +}
 47.1457 +
 47.1458 +// Notify a condition, releasing the least object in a queue
 47.1459 +void WaitConditionImpl::Notify()
 47.1460 +{
 47.1461 +    Lock::Locker   lock(&WaitQueueLoc);
 47.1462 +    
 47.1463 +    // Pop last entry & signal it
 47.1464 +    EventPoolEntry* pentry = QueuePop();    
 47.1465 +    if (pentry)
 47.1466 +        ::SetEvent(pentry->hEvent); 
 47.1467 +}
 47.1468 +
 47.1469 +// Notify a condition, releasing all objects waiting
 47.1470 +void WaitConditionImpl::NotifyAll()
 47.1471 +{
 47.1472 +    Lock::Locker   lock(&WaitQueueLoc);
 47.1473 +
 47.1474 +    // Pop and signal all events
 47.1475 +    // NOTE : There is no need to release the events, it's the waiters job to do so 
 47.1476 +    EventPoolEntry* pentry = QueuePop();
 47.1477 +    while (pentry)
 47.1478 +    {
 47.1479 +        ::SetEvent(pentry->hEvent);
 47.1480 +        pentry = QueuePop();
 47.1481 +    }
 47.1482 +}
 47.1483 +
 47.1484 +
 47.1485 +
 47.1486 +// *** Actual implementation of WaitCondition
 47.1487 +
 47.1488 +WaitCondition::WaitCondition()
 47.1489 +{
 47.1490 +    pImpl = new WaitConditionImpl;
 47.1491 +}
 47.1492 +WaitCondition::~WaitCondition()
 47.1493 +{
 47.1494 +    delete pImpl;
 47.1495 +}
 47.1496 +    
 47.1497 +// Wait without a mutex
 47.1498 +bool    WaitCondition::Wait(Mutex *pmutex, unsigned delay)
 47.1499 +{
 47.1500 +    return pImpl->Wait(pmutex, delay);
 47.1501 +}
 47.1502 +// Notification
 47.1503 +void    WaitCondition::Notify()
 47.1504 +{
 47.1505 +    pImpl->Notify();
 47.1506 +}
 47.1507 +void    WaitCondition::NotifyAll()
 47.1508 +{
 47.1509 +    pImpl->NotifyAll();
 47.1510 +}
 47.1511 +
 47.1512 +
 47.1513 +
 47.1514 +//-----------------------------------------------------------------------------------
 47.1515 +// ***** Thread Class
 47.1516 +
 47.1517 +//  Per-thread variable
 47.1518 +//  MA: Don't use TLS for now - portability issues with DLLs, etc.
 47.1519 +/*
 47.1520 +#if !defined(OVR_CC_MSVC) || (OVR_CC_MSVC < 1300)
 47.1521 +__declspec(thread)  Thread*    pCurrentThread      = 0;
 47.1522 +#else
 47.1523 +#pragma data_seg(".tls$")
 47.1524 +__declspec(thread)  Thread*    pCurrentThread      = 0;
 47.1525 +#pragma data_seg(".rwdata")
 47.1526 +#endif
 47.1527 +*/
 47.1528 +
 47.1529 +// *** Thread constructors.
 47.1530 +
 47.1531 +Thread::Thread(UPInt stackSize, int processor)
 47.1532 +{    
 47.1533 +    CreateParams params;
 47.1534 +    params.stackSize = stackSize;
 47.1535 +    params.processor = processor;
 47.1536 +    Init(params);
 47.1537 +}
 47.1538 +
 47.1539 +Thread::Thread(Thread::ThreadFn threadFunction, void*  userHandle, UPInt stackSize, 
 47.1540 +                 int processor, Thread::ThreadState initialState)
 47.1541 +{
 47.1542 +    CreateParams params(threadFunction, userHandle, stackSize, processor, initialState);
 47.1543 +    Init(params);
 47.1544 +}
 47.1545 +
 47.1546 +Thread::Thread(const CreateParams& params)
 47.1547 +{
 47.1548 +    Init(params);
 47.1549 +}
 47.1550 +void Thread::Init(const CreateParams& params)
 47.1551 +{
 47.1552 +    // Clear the variables    
 47.1553 +    ThreadFlags     = 0;
 47.1554 +    ThreadHandle    = 0;
 47.1555 +    IdValue         = 0;
 47.1556 +    ExitCode        = 0;
 47.1557 +    SuspendCount    = 0;
 47.1558 +    StackSize       = params.stackSize;
 47.1559 +    Processor       = params.processor;
 47.1560 +    Priority        = params.priority;
 47.1561 +
 47.1562 +    // Clear Function pointers
 47.1563 +    ThreadFunction  = params.threadFunction;
 47.1564 +    UserHandle      = params.userHandle;
 47.1565 +    if (params.initialState != NotRunning)
 47.1566 +        Start(params.initialState);
 47.1567 +
 47.1568 +}
 47.1569 +
 47.1570 +Thread::~Thread()
 47.1571 +{
 47.1572 +    // Thread should not running while object is being destroyed,
 47.1573 +    // this would indicate ref-counting issue.
 47.1574 +    //OVR_ASSERT(IsRunning() == 0);
 47.1575 +  
 47.1576 +    // Clean up thread.    
 47.1577 +    CleanupSystemThread();
 47.1578 +    ThreadHandle = 0;
 47.1579 +}
 47.1580 +
 47.1581 +
 47.1582 +// *** Overridable User functions.
 47.1583 +
 47.1584 +// Default Run implementation
 47.1585 +int Thread::Run()
 47.1586 +{
 47.1587 +    // Call pointer to function, if available.    
 47.1588 +    return (ThreadFunction) ? ThreadFunction(this, UserHandle) : 0;
 47.1589 +}
 47.1590 +void Thread::OnExit()
 47.1591 +{   
 47.1592 +}
 47.1593 +
 47.1594 +// Finishes the thread and releases internal reference to it.
 47.1595 +void Thread::FinishAndRelease()
 47.1596 +{
 47.1597 +    // Note: thread must be US.
 47.1598 +    ThreadFlags &= (UInt32)~(OVR_THREAD_STARTED);
 47.1599 +    ThreadFlags |= OVR_THREAD_FINISHED;
 47.1600 +
 47.1601 +    // Release our reference; this is equivalent to 'delete this'
 47.1602 +    // from the point of view of our thread.
 47.1603 +    Release();
 47.1604 +}
 47.1605 +
 47.1606 +
 47.1607 +// *** ThreadList - used to tack all created threads
 47.1608 +
 47.1609 +class ThreadList : public NewOverrideBase
 47.1610 +{
 47.1611 +    //------------------------------------------------------------------------
 47.1612 +    struct ThreadHashOp
 47.1613 +    {
 47.1614 +        UPInt operator()(const Thread* ptr)
 47.1615 +        {
 47.1616 +            return (((UPInt)ptr) >> 6) ^ (UPInt)ptr;
 47.1617 +        }
 47.1618 +    };
 47.1619 +
 47.1620 +    HashSet<Thread*, ThreadHashOp>  ThreadSet;
 47.1621 +    Mutex                           ThreadMutex;
 47.1622 +    WaitCondition                   ThreadsEmpty;
 47.1623 +    // Track the root thread that created us.
 47.1624 +    ThreadId                        RootThreadId;
 47.1625 +
 47.1626 +    static ThreadList* volatile pRunningThreads;
 47.1627 +
 47.1628 +    void addThread(Thread *pthread)
 47.1629 +    {
 47.1630 +         Mutex::Locker lock(&ThreadMutex);
 47.1631 +         ThreadSet.Add(pthread);
 47.1632 +    }
 47.1633 +
 47.1634 +    void removeThread(Thread *pthread)
 47.1635 +    {
 47.1636 +        Mutex::Locker lock(&ThreadMutex);
 47.1637 +        ThreadSet.Remove(pthread);
 47.1638 +        if (ThreadSet.GetSize() == 0)
 47.1639 +            ThreadsEmpty.Notify();
 47.1640 +    }
 47.1641 +
 47.1642 +    void finishAllThreads()
 47.1643 +    {
 47.1644 +        // Only original root thread can call this.
 47.1645 +        OVR_ASSERT(GetCurrentThreadId() == RootThreadId);
 47.1646 +
 47.1647 +        Mutex::Locker lock(&ThreadMutex);
 47.1648 +        while (ThreadSet.GetSize() != 0)
 47.1649 +            ThreadsEmpty.Wait(&ThreadMutex);
 47.1650 +    }
 47.1651 +
 47.1652 +public:
 47.1653 +
 47.1654 +    ThreadList()
 47.1655 +    {
 47.1656 +        RootThreadId = GetCurrentThreadId();
 47.1657 +    }
 47.1658 +    ~ThreadList() { }
 47.1659 +
 47.1660 +
 47.1661 +    static void AddRunningThread(Thread *pthread)
 47.1662 +    {
 47.1663 +        // Non-atomic creation ok since only the root thread
 47.1664 +        if (!pRunningThreads)
 47.1665 +        {
 47.1666 +            pRunningThreads = new ThreadList;
 47.1667 +            OVR_ASSERT(pRunningThreads);
 47.1668 +        }
 47.1669 +        pRunningThreads->addThread(pthread);
 47.1670 +    }
 47.1671 +
 47.1672 +    // NOTE: 'pthread' might be a dead pointer when this is
 47.1673 +    // called so it should not be accessed; it is only used
 47.1674 +    // for removal.
 47.1675 +    static void RemoveRunningThread(Thread *pthread)
 47.1676 +    {
 47.1677 +        OVR_ASSERT(pRunningThreads);        
 47.1678 +        pRunningThreads->removeThread(pthread);
 47.1679 +    }
 47.1680 +
 47.1681 +    static void FinishAllThreads()
 47.1682 +    {
 47.1683 +        // This is ok because only root thread can wait for other thread finish.
 47.1684 +        if (pRunningThreads)
 47.1685 +        {           
 47.1686 +            pRunningThreads->finishAllThreads();
 47.1687 +            delete pRunningThreads;
 47.1688 +            pRunningThreads = 0;
 47.1689 +        }        
 47.1690 +    }
 47.1691 +};
 47.1692 +
 47.1693 +// By default, we have no thread list.
 47.1694 +ThreadList* volatile ThreadList::pRunningThreads = 0;
 47.1695 +
 47.1696 +
 47.1697 +// FinishAllThreads - exposed publicly in Thread.
 47.1698 +void Thread::FinishAllThreads()
 47.1699 +{
 47.1700 +    ThreadList::FinishAllThreads();
 47.1701 +}
 47.1702 +
 47.1703 +
 47.1704 +// *** Run override
 47.1705 +
 47.1706 +int Thread::PRun()
 47.1707 +{
 47.1708 +    // Suspend us on start, if requested
 47.1709 +    if (ThreadFlags & OVR_THREAD_START_SUSPENDED)
 47.1710 +    {
 47.1711 +        Suspend();
 47.1712 +        ThreadFlags &= (UInt32)~OVR_THREAD_START_SUSPENDED;
 47.1713 +    }
 47.1714 +
 47.1715 +    // Call the virtual run function
 47.1716 +    ExitCode = Run();    
 47.1717 +    return ExitCode;
 47.1718 +}
 47.1719 +
 47.1720 +
 47.1721 +
 47.1722 +/* MA: Don't use TLS for now.
 47.1723 +
 47.1724 +// Static function to return a pointer to the current thread
 47.1725 +void    Thread::InitCurrentThread(Thread *pthread)
 47.1726 +{
 47.1727 +    pCurrentThread = pthread;
 47.1728 +}
 47.1729 +
 47.1730 +// Static function to return a pointer to the current thread
 47.1731 +Thread*    Thread::GetThread()
 47.1732 +{
 47.1733 +    return pCurrentThread;
 47.1734 +}
 47.1735 +*/
 47.1736 +
 47.1737 +
 47.1738 +// *** User overridables
 47.1739 +
 47.1740 +bool    Thread::GetExitFlag() const
 47.1741 +{
 47.1742 +    return (ThreadFlags & OVR_THREAD_EXIT) != 0;
 47.1743 +}       
 47.1744 +
 47.1745 +void    Thread::SetExitFlag(bool exitFlag)
 47.1746 +{
 47.1747 +    // The below is atomic since ThreadFlags is AtomicInt.
 47.1748 +    if (exitFlag)
 47.1749 +        ThreadFlags |= OVR_THREAD_EXIT;
 47.1750 +    else
 47.1751 +        ThreadFlags &= (UInt32) ~OVR_THREAD_EXIT;
 47.1752 +}
 47.1753 +
 47.1754 +
 47.1755 +// Determines whether the thread was running and is now finished
 47.1756 +bool    Thread::IsFinished() const
 47.1757 +{
 47.1758 +    return (ThreadFlags & OVR_THREAD_FINISHED) != 0;
 47.1759 +}
 47.1760 +// Determines whether the thread is suspended
 47.1761 +bool    Thread::IsSuspended() const
 47.1762 +{   
 47.1763 +    return SuspendCount > 0;
 47.1764 +}
 47.1765 +// Returns current thread state
 47.1766 +Thread::ThreadState Thread::GetThreadState() const
 47.1767 +{
 47.1768 +    if (IsSuspended())
 47.1769 +        return Suspended;    
 47.1770 +    if (ThreadFlags & OVR_THREAD_STARTED)
 47.1771 +        return Running;    
 47.1772 +    return NotRunning;
 47.1773 +}
 47.1774 +
 47.1775 +
 47.1776 +
 47.1777 +// ***** Thread management
 47.1778 +/* static */
 47.1779 +int Thread::GetOSPriority(ThreadPriority p)
 47.1780 +{
 47.1781 +    switch(p)
 47.1782 +    {
 47.1783 +    case Thread::CriticalPriority:      return THREAD_PRIORITY_TIME_CRITICAL;
 47.1784 +    case Thread::HighestPriority:       return THREAD_PRIORITY_HIGHEST;
 47.1785 +    case Thread::AboveNormalPriority:   return THREAD_PRIORITY_ABOVE_NORMAL;
 47.1786 +    case Thread::NormalPriority:        return THREAD_PRIORITY_NORMAL;
 47.1787 +    case Thread::BelowNormalPriority:   return THREAD_PRIORITY_BELOW_NORMAL;
 47.1788 +    case Thread::LowestPriority:        return THREAD_PRIORITY_LOWEST;
 47.1789 +    case Thread::IdlePriority:          return THREAD_PRIORITY_IDLE;
 47.1790 +    }
 47.1791 +    return THREAD_PRIORITY_NORMAL;
 47.1792 +}
 47.1793 +
 47.1794 +// The actual first function called on thread start
 47.1795 +unsigned WINAPI Thread_Win32StartFn(void * phandle)
 47.1796 +{
 47.1797 +    Thread *   pthread = (Thread*)phandle;
 47.1798 +    if (pthread->Processor != -1)
 47.1799 +    {
 47.1800 +        DWORD_PTR ret = SetThreadAffinityMask(GetCurrentThread(), (DWORD)pthread->Processor);
 47.1801 +        if (ret == 0)
 47.1802 +            OVR_DEBUG_LOG(("Could not set hardware processor for the thread"));
 47.1803 +    }
 47.1804 +    BOOL ret = ::SetThreadPriority(GetCurrentThread(), Thread::GetOSPriority(pthread->Priority));
 47.1805 +    if (ret == 0)
 47.1806 +        OVR_DEBUG_LOG(("Could not set thread priority"));
 47.1807 +    OVR_UNUSED(ret);
 47.1808 +
 47.1809 +    // Ensure that ThreadId is assigned once thread is running, in case
 47.1810 +    // beginthread hasn't filled it in yet.
 47.1811 +    pthread->IdValue = (ThreadId)::GetCurrentThreadId();
 47.1812 +
 47.1813 +    DWORD       result = pthread->PRun();
 47.1814 +    // Signal the thread as done and release it atomically.
 47.1815 +    pthread->FinishAndRelease();
 47.1816 +    // At this point Thread object might be dead; however we can still pass
 47.1817 +    // it to RemoveRunningThread since it is only used as a key there.    
 47.1818 +    ThreadList::RemoveRunningThread(pthread);
 47.1819 +    return (unsigned) result;
 47.1820 +}
 47.1821 +
 47.1822 +bool Thread::Start(ThreadState initialState)
 47.1823 +{
 47.1824 +    if (initialState == NotRunning)
 47.1825 +        return 0;
 47.1826 +    if (GetThreadState() != NotRunning)
 47.1827 +    {
 47.1828 +        OVR_DEBUG_LOG(("Thread::Start failed - thread %p already running", this));
 47.1829 +        return 0;
 47.1830 +    }
 47.1831 +
 47.1832 +    // Free old thread handle before creating the new one
 47.1833 +    CleanupSystemThread();
 47.1834 +
 47.1835 +    // AddRef to us until the thread is finished.
 47.1836 +    AddRef();
 47.1837 +    ThreadList::AddRunningThread(this);
 47.1838 +    
 47.1839 +    ExitCode        = 0;
 47.1840 +    SuspendCount    = 0;
 47.1841 +    ThreadFlags     = (initialState == Running) ? 0 : OVR_THREAD_START_SUSPENDED;
 47.1842 +    ThreadHandle = (HANDLE) _beginthreadex(0, (unsigned)StackSize,
 47.1843 +                                           Thread_Win32StartFn, this, 0, (unsigned*)&IdValue);
 47.1844 +
 47.1845 +    // Failed? Fail the function
 47.1846 +    if (ThreadHandle == 0)
 47.1847 +    {
 47.1848 +        ThreadFlags = 0;
 47.1849 +        Release();
 47.1850 +        ThreadList::RemoveRunningThread(this);
 47.1851 +        return 0;
 47.1852 +    }
 47.1853 +    return 1;
 47.1854 +}
 47.1855 +
 47.1856 +
 47.1857 +// Suspend the thread until resumed
 47.1858 +bool Thread::Suspend()
 47.1859 +{
 47.1860 +    // Can't suspend a thread that wasn't started
 47.1861 +    if (!(ThreadFlags & OVR_THREAD_STARTED))
 47.1862 +        return 0;
 47.1863 +
 47.1864 +    if (::SuspendThread(ThreadHandle) != 0xFFFFFFFF)
 47.1865 +    {        
 47.1866 +        SuspendCount++;        
 47.1867 +        return 1;
 47.1868 +    }
 47.1869 +    return 0;
 47.1870 +}
 47.1871 +
 47.1872 +// Resumes currently suspended thread
 47.1873 +bool Thread::Resume()
 47.1874 +{
 47.1875 +    // Can't suspend a thread that wasn't started
 47.1876 +    if (!(ThreadFlags & OVR_THREAD_STARTED))
 47.1877 +        return 0;
 47.1878 +
 47.1879 +    // Decrement count, and resume thread if it is 0
 47.1880 +    SInt32 oldCount = SuspendCount.ExchangeAdd_Acquire(-1);
 47.1881 +    if (oldCount >= 1)
 47.1882 +    {
 47.1883 +        if (oldCount == 1)
 47.1884 +        {
 47.1885 +            if (::ResumeThread(ThreadHandle) != 0xFFFFFFFF)            
 47.1886 +                return 1;            
 47.1887 +        }
 47.1888 +        else
 47.1889 +        {
 47.1890 +            return 1;
 47.1891 +        }
 47.1892 +    }   
 47.1893 +    return 0;
 47.1894 +}
 47.1895 +
 47.1896 +
 47.1897 +// Quits with an exit code  
 47.1898 +void Thread::Exit(int exitCode)
 47.1899 +{
 47.1900 +    // Can only exist the current thread.
 47.1901 +    // MA: Don't use TLS for now.
 47.1902 +    //if (GetThread() != this)
 47.1903 +    //    return;
 47.1904 +
 47.1905 +    // Call the virtual OnExit function.
 47.1906 +    OnExit();   
 47.1907 +
 47.1908 +    // Signal this thread object as done and release it's references.
 47.1909 +    FinishAndRelease();
 47.1910 +    ThreadList::RemoveRunningThread(this);
 47.1911 +
 47.1912 +    // Call the exit function.    
 47.1913 +    _endthreadex((unsigned)exitCode);
 47.1914 +}
 47.1915 +
 47.1916 +
 47.1917 +void Thread::CleanupSystemThread()
 47.1918 +{
 47.1919 +    if (ThreadHandle != 0)
 47.1920 +    {
 47.1921 +        ::CloseHandle(ThreadHandle);
 47.1922 +        ThreadHandle = 0;
 47.1923 +    }
 47.1924 +}
 47.1925 +
 47.1926 +// *** Sleep functions
 47.1927 +// static
 47.1928 +bool Thread::Sleep(unsigned secs)
 47.1929 +{
 47.1930 +    ::Sleep(secs*1000);
 47.1931 +    return 1;
 47.1932 +}
 47.1933 +
 47.1934 +// static
 47.1935 +bool Thread::MSleep(unsigned msecs)
 47.1936 +{
 47.1937 +    ::Sleep(msecs);
 47.1938 +    return 1;
 47.1939 +}
 47.1940 +
 47.1941 +void Thread::SetThreadName( const char* name )
 47.1942 +{
 47.1943 +#if !defined(OVR_BUILD_SHIPPING) || defined(OVR_BUILD_PROFILING)
 47.1944 +    // Looks ugly, but it is the recommended way to name a thread.
 47.1945 +    typedef struct tagTHREADNAME_INFO {
 47.1946 +        DWORD dwType;     // Must be 0x1000
 47.1947 +        LPCSTR szName;    // Pointer to name (in user address space)
 47.1948 +        DWORD dwThreadID; // Thread ID (-1 for caller thread)
 47.1949 +        DWORD dwFlags;    // Reserved for future use; must be zero
 47.1950 +    } THREADNAME_INFO;
 47.1951 +
 47.1952 +    THREADNAME_INFO info;
 47.1953 +
 47.1954 +    info.dwType = 0x1000;
 47.1955 +    info.szName = name;
 47.1956 +    info.dwThreadID = reinterpret_cast<DWORD>(GetThreadId());
 47.1957 +    info.dwFlags = 0;
 47.1958 +
 47.1959 +    __try
 47.1960 +    {
 47.1961 +#ifdef _WIN64
 47.1962 +        RaiseException( 0x406D1388, 0, sizeof(info)/sizeof(DWORD), (const ULONG_PTR *)&info );
 47.1963 +#else
 47.1964 +        RaiseException( 0x406D1388, 0, sizeof(info)/sizeof(DWORD), (DWORD *)&info );
 47.1965 +#endif
 47.1966 +    }
 47.1967 +    __except( GetExceptionCode()==0x406D1388 ? EXCEPTION_CONTINUE_EXECUTION : EXCEPTION_EXECUTE_HANDLER )
 47.1968 +    {
 47.1969 +    }
 47.1970 +#endif // OVR_BUILD_SHIPPING
 47.1971 +}
 47.1972 +
 47.1973 +// static
 47.1974 +int  Thread::GetCPUCount()
 47.1975 +{
 47.1976 +    SYSTEM_INFO sysInfo;
 47.1977 +    GetSystemInfo(&sysInfo);
 47.1978 +    return (int) sysInfo.dwNumberOfProcessors;
 47.1979 +}
 47.1980 +
 47.1981 +// Returns the unique Id of a thread it is called on, intended for
 47.1982 +// comparison purposes.
 47.1983 +ThreadId GetCurrentThreadId()
 47.1984 +{
 47.1985 +    return (ThreadId)::GetCurrentThreadId();
 47.1986 +}
 47.1987 +
 47.1988 +} // OVR
 47.1989 +
 47.1990 +#endif
 47.1991 +
 47.1992 +
    48.1 --- a/src/main.cc	Sat Sep 14 17:51:03 2013 +0300
    48.2 +++ b/src/main.cc	Sun Sep 15 04:10:05 2013 +0300
    48.3 @@ -26,13 +26,13 @@
    48.4  
    48.5  int main(int argc, char **argv)
    48.6  {
    48.7 +	glutInitWindowSize(1280, 800);
    48.8  	glutInit(&argc, argv);
    48.9  
   48.10  	if(!parse_args(argc, argv)) {
   48.11  		return 1;
   48.12  	}
   48.13  
   48.14 -	glutInitWindowSize(1280, 800);
   48.15  	glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE);
   48.16  	glutCreateWindow("oculus test 01");
   48.17  
   48.18 @@ -63,7 +63,7 @@
   48.19  	glEnable(GL_LIGHTING);
   48.20  
   48.21  	if(vr_init(VR_INIT_OCULUS) == -1) {
   48.22 -		return false;
   48.23 +		//return false;
   48.24  	}
   48.25  	return true;
   48.26  }
   48.27 @@ -75,6 +75,15 @@
   48.28  
   48.29  static void disp()
   48.30  {
   48.31 +	// test rift sensor
   48.32 +	float quat[4], euler[3];
   48.33 +
   48.34 +	vr_get_rotation(quat);
   48.35 +	vr_get_rotation_euler(euler);
   48.36 +
   48.37 +	printf("q(%.3f + %.3fi + %.3fj %.3fk)", quat[3], quat[0], quat[1], quat[2]);
   48.38 +	printf(" - euler(%.3f %.3f %.3f)\n", euler[0], euler[1], euler[2]);
   48.39 +
   48.40  	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
   48.41  
   48.42  	glMatrixMode(GL_PROJECTION);
    49.1 --- a/src/vr.cc	Sat Sep 14 17:51:03 2013 +0300
    49.2 +++ b/src/vr.cc	Sun Sep 15 04:10:05 2013 +0300
    49.3 @@ -4,7 +4,7 @@
    49.4  
    49.5  static bool init_ovr();
    49.6  
    49.7 -VRData vr_data;
    49.8 +VRContext vr_ctx;
    49.9  
   49.10  extern "C" int vr_init(enum vr_init_mode mode)
   49.11  {
   49.12 @@ -16,28 +16,26 @@
   49.13  
   49.14  extern "C" void vr_shutdown(void)
   49.15  {
   49.16 -	System::Destroy();
   49.17 +	//System::Destroy();
   49.18  }
   49.19  
   49.20 -
   49.21 -
   49.22  static bool init_ovr()
   49.23  {
   49.24  	// initialize Oculus SDK
   49.25  	System::Init();
   49.26 -	if(!(vr_data.ovr_devman = DeviceManager::Create())) {
   49.27 +	if(!(vr_ctx.ovr_devman = DeviceManager::Create())) {
   49.28  		fprintf(stderr, "failed to create OVR device manager\n");
   49.29  		return false;
   49.30  	}
   49.31  
   49.32  	// create the display device
   49.33 -	if(!(vr_data.ovr_hmd_dev = vr_data.ovr_devman->EnumerateDevices<HMDDevice>().CreateDevice())) {
   49.34 +	if(!(vr_ctx.ovr_hmd_dev = vr_ctx.ovr_devman->EnumerateDevices<HMDDevice>().CreateDevice())) {
   49.35  		fprintf(stderr, "no oculus rift devices found\n");
   49.36  		return false;
   49.37  	}
   49.38  
   49.39  	HMDInfo info;
   49.40 -	if(vr_data.ovr_hmd_dev->GetDeviceInfo(&info)) {
   49.41 +	if(vr_ctx.ovr_hmd_dev->GetDeviceInfo(&info)) {
   49.42  		printf("oculus device info:\n");
   49.43  		printf("  name: %s\n", info.DisplayDeviceName);
   49.44  		printf("  ipd: %f\n", info.InterpupillaryDistance);
   49.45 @@ -46,16 +44,102 @@
   49.46  	}
   49.47  
   49.48  	// get the sensor device
   49.49 -	if(!(vr_data.ovr_sensor_dev = vr_data.ovr_hmd_dev->GetSensor())) {
   49.50 +	if(!(vr_ctx.ovr_sensor_dev = vr_ctx.ovr_hmd_dev->GetSensor())) {
   49.51  		fprintf(stderr, "failed to get oculus sensor device\n");
   49.52  		return false;
   49.53  	}
   49.54  
   49.55  	SensorInfo sinfo;
   49.56 -	if(vr_data.ovr_sensor_dev->GetDeviceInfo(&sinfo)) {
   49.57 +	if(vr_ctx.ovr_sensor_dev->GetDeviceInfo(&sinfo)) {
   49.58  		printf("oculus sensor device info:\n");
   49.59  		printf("  name: %s\n", sinfo.ProductName);
   49.60  	}
   49.61  
   49.62 +	vr_ctx.ovr_sfusion.AttachToSensor(vr_ctx.ovr_sensor_dev);
   49.63 +
   49.64 +	// calculate and store viewing parameters
   49.65 +	float vhalfsz = info.VScreenSize * 0.5;
   49.66 +	vr_ctx.info.fov = 2.0 * atan(vhalfsz / info.EyeToScreenDistance);
   49.67 +
   49.68 +	vr_ctx.info.width = info.HResolution;
   49.69 +	vr_ctx.info.height = info.VResolution;
   49.70 +	vr_ctx.info.aspect = (float)vr_ctx.info.width / (float)vr_ctx.info.height;
   49.71 +
   49.72 +	vr_ctx.info.ipd = info.InterpupillaryDistance;
   49.73 +	for(int i=0; i<4; i++) {
   49.74 +		vr_ctx.info.distort[i] = info.DistortionK[i];
   49.75 +	}
   49.76 +
   49.77  	return true;
   49.78  }
   49.79 +
   49.80 +extern "C" int vr_get_width(void)
   49.81 +{
   49.82 +	return vr_ctx.info.width;
   49.83 +}
   49.84 +
   49.85 +extern "C" int vr_get_height(void)
   49.86 +{
   49.87 +	return vr_ctx.info.height;
   49.88 +}
   49.89 +
   49.90 +extern "C" float vr_get_fov(void)
   49.91 +{
   49.92 +	return vr_ctx.info.fov;
   49.93 +}
   49.94 +
   49.95 +extern "C" float vr_get_aspect(void)
   49.96 +{
   49.97 +	return vr_ctx.info.aspect;
   49.98 +}
   49.99 +
  49.100 +extern "C" void vr_set_eyedist(float ipd)
  49.101 +{
  49.102 +	vr_ctx.info.ipd = ipd;
  49.103 +}
  49.104 +
  49.105 +extern "C" float vr_get_eyedist(void)
  49.106 +{
  49.107 +	return vr_ctx.info.ipd;
  49.108 +}
  49.109 +
  49.110 +extern "C" void vr_set_distort(const float *coef)
  49.111 +{
  49.112 +	memcpy(vr_ctx.info.distort, coef, sizeof vr_ctx.info.distort);
  49.113 +}
  49.114 +
  49.115 +extern "C" void vr_get_distort(float *coef)
  49.116 +{
  49.117 +	memcpy(coef, vr_ctx.info.distort, sizeof vr_ctx.info.distort);
  49.118 +}
  49.119 +
  49.120 +extern "C" void vr_set_prediction_sec(float dt)
  49.121 +{
  49.122 +	vr_ctx.ovr_sfusion.SetPrediction(dt);
  49.123 +}
  49.124 +
  49.125 +extern "C" float vr_get_prediction_sec(void)
  49.126 +{
  49.127 +	return vr_ctx.ovr_sfusion.GetPredictionDelta();
  49.128 +}
  49.129 +
  49.130 +extern "C" void vr_get_translation(float *offs)
  49.131 +{
  49.132 +	// current oculus devkit doesn't do translation
  49.133 +	offs[0] = offs[1] = offs[2] = 0.0f;
  49.134 +}
  49.135 +
  49.136 +extern "C" void vr_get_rotation(float *quat)
  49.137 +{
  49.138 +	Quatf oq = vr_ctx.ovr_sfusion.GetPredictedOrientation();
  49.139 +	quat[0] = oq.x;
  49.140 +	quat[1] = oq.y;
  49.141 +	quat[2] = oq.z;
  49.142 +	quat[3] = oq.w;
  49.143 +}
  49.144 +
  49.145 +extern "C" void vr_get_rotation_euler(float *euler)
  49.146 +{
  49.147 +	Quatf oq = vr_ctx.ovr_sfusion.GetPredictedOrientation();
  49.148 +	oq.GetEulerAngles<Axis_Y, Axis_X, Axis_Z>(euler + 1, euler, euler + 2);
  49.149 +}
    50.1 --- a/src/vr.h	Sat Sep 14 17:51:03 2013 +0300
    50.2 +++ b/src/vr.h	Sun Sep 15 04:10:05 2013 +0300
    50.3 @@ -22,10 +22,7 @@
    50.4  int vr_init(enum vr_init_mode mode);
    50.5  void vr_shutdown(void);
    50.6  
    50.7 -void vr_set_fov(float fov);
    50.8  float vr_get_fov(void);
    50.9 -
   50.10 -void vr_set_aspect(float aspect);
   50.11  float vr_get_aspect(void);
   50.12  
   50.13  void vr_set_eyedist(float ipd);
   50.14 @@ -37,6 +34,9 @@
   50.15  void vr_set_distort(const float *coef);
   50.16  void vr_get_distort(float *coef);
   50.17  
   50.18 +void vr_set_prediction_sec(float dt);
   50.19 +float vr_get_prediction_sec(void);
   50.20 +
   50.21  void vr_get_view_matrix(float *res, int eye);
   50.22  void vr_get_proj_matrix(float *res, int eye);
   50.23  
    51.1 --- a/src/vr_impl.h	Sat Sep 14 17:51:03 2013 +0300
    51.2 +++ b/src/vr_impl.h	Sun Sep 15 04:10:05 2013 +0300
    51.3 @@ -5,17 +5,23 @@
    51.4  
    51.5  using namespace OVR;
    51.6  
    51.7 -struct VRData {
    51.8 +struct VRContext {
    51.9  	DeviceManager *ovr_devman;
   51.10  	HMDDevice *ovr_hmd_dev;
   51.11  	SensorDevice *ovr_sensor_dev;
   51.12 +	SensorFusion ovr_sfusion;
   51.13  
   51.14 -	float fov;
   51.15 -	float aspect;
   51.16 -	float ipd;
   51.17 -	float distort[4];
   51.18 +	struct {
   51.19 +		// the full width and height of the display (both eyes)
   51.20 +		int width, height;
   51.21 +		float fov;
   51.22 +		// the full aspect ratio of the display (both eyes)
   51.23 +		float aspect;
   51.24 +		float ipd;
   51.25 +		float distort[4];
   51.26 +	} info;
   51.27  };
   51.28  
   51.29 -extern VRData vr_data;
   51.30 +extern VRContext vr_ctx;
   51.31  
   51.32  #endif	// VR_IMPL_H_