oculus1

changeset 1:e2f9e4603129

added LibOVR and started a simple vr wrapper.
author John Tsiombikas <nuclear@member.fsf.org>
date Sat, 14 Sep 2013 16:14:59 +0300
parents c7b50cd7184c
children 59fc487ba58e
files .hgignore Makefile libovr/Include/OVR.h libovr/Include/OVRVersion.h 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/OVR_Device.h libovr/Src/OVR_DeviceConstants.h libovr/Src/OVR_DeviceHandle.cpp libovr/Src/OVR_DeviceHandle.h libovr/Src/OVR_DeviceImpl.cpp libovr/Src/OVR_DeviceImpl.h libovr/Src/OVR_DeviceMessages.h libovr/Src/OVR_HIDDevice.h libovr/Src/OVR_HIDDeviceBase.h libovr/Src/OVR_HIDDeviceImpl.h libovr/Src/OVR_JSON.cpp libovr/Src/OVR_JSON.h libovr/Src/OVR_LatencyTestImpl.cpp libovr/Src/OVR_LatencyTestImpl.h libovr/Src/OVR_Profile.cpp libovr/Src/OVR_Profile.h libovr/Src/OVR_SensorFilter.cpp libovr/Src/OVR_SensorFilter.h libovr/Src/OVR_SensorFusion.cpp libovr/Src/OVR_SensorFusion.h libovr/Src/OVR_SensorImpl.cpp libovr/Src/OVR_SensorImpl.h libovr/Src/OVR_ThreadCommandQueue.cpp libovr/Src/OVR_ThreadCommandQueue.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_Linux_DeviceManager.cpp libovr/Src/linux/OVR_Linux_DeviceManager.h libovr/Src/linux/OVR_Linux_HIDDevice.cpp libovr/Src/linux/OVR_Linux_HIDDevice.h libovr/Src/linux/OVR_Linux_HMDDevice.cpp libovr/Src/linux/OVR_Linux_HMDDevice.h libovr/Src/linux/OVR_Linux_SensorDevice.cpp libovr/Src/linux/OVR_ThreadsPthread.cpp libovr/Src/osx/OVR_OSX_DeviceManager.cpp libovr/Src/osx/OVR_OSX_DeviceManager.h libovr/Src/osx/OVR_OSX_HIDDevice.cpp libovr/Src/osx/OVR_OSX_HIDDevice.h libovr/Src/osx/OVR_OSX_HMDDevice.cpp libovr/Src/osx/OVR_OSX_HMDDevice.h libovr/Src/osx/OVR_OSX_SensorDevice.cpp libovr/Src/osx/OVR_ThreadsPthread.cpp libovr/Src/win32/OVR_ThreadsWinAPI.cpp libovr/Src/win32/OVR_Win32_DeviceManager.cpp libovr/Src/win32/OVR_Win32_DeviceManager.h libovr/Src/win32/OVR_Win32_DeviceStatus.cpp libovr/Src/win32/OVR_Win32_DeviceStatus.h libovr/Src/win32/OVR_Win32_HIDDevice.cpp libovr/Src/win32/OVR_Win32_HIDDevice.h libovr/Src/win32/OVR_Win32_HMDDevice.cpp libovr/Src/win32/OVR_Win32_HMDDevice.h libovr/Src/win32/OVR_Win32_SensorDevice.cpp libovr/Src/win32/OVR_Win32_SensorDevice.h src/main.cc src/vr.cc src/vr.h src/vr_impl.h
diffstat 103 files changed, 15643 insertions(+), 11 deletions(-) [+]
line diff
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/.hgignore	Sat Sep 14 16:14:59 2013 +0300
     1.3 @@ -0,0 +1,4 @@
     1.4 +\.o$
     1.5 +\.d$
     1.6 +\.swp$
     1.7 +^oculus1$
     2.1 --- a/Makefile	Fri Aug 30 06:08:34 2013 +0300
     2.2 +++ b/Makefile	Sat Sep 14 16:14:59 2013 +0300
     2.3 @@ -1,16 +1,26 @@
     2.4  src = $(wildcard src/*.cc)
     2.5 -obj = $(src:.cc=.o)
     2.6 +ovr_src = $(wildcard libovr/Src/*.cpp) \
     2.7 +		  $(wildcard libovr/Src/Kernel/*.cpp) \
     2.8 +		  $(wildcard libovr/Src/Util/*.cpp)
     2.9 +
    2.10 +obj = $(src:.cc=.o) $(ovr_src:.cpp=.o) $(ovr_sys_src:.cpp=.o)
    2.11  bin = oculus1
    2.12  
    2.13 -CXXFLAGS = -pedantic -Wall -g -I/usr/local/include
    2.14 +
    2.15 +CXXFLAGS = -Wall -g -I/usr/local/include $(ovr_include) -DUSE_OVR
    2.16  LDFLAGS = -L/usr/local/lib $(libgl) $(ovrlibs) -lm
    2.17  
    2.18  ifeq ($(shell uname -s), Darwin)
    2.19  	libgl = -framework OpenGL -framework GLUT -lGLEW
    2.20 -	ovrlibs = -lovr -framework CoreFoundation -framework ApplicationServices -framework IOKit
    2.21 +	ovrlibs = -framework CoreFoundation -framework ApplicationServices -framework IOKit
    2.22 +
    2.23 +	ovr_include = -Ilibovr/Include -Ilibovr/Src -Ilibovr/Src/osx
    2.24 +	ovr_sys_src = $(wildcard libovr/Src/osx/*.cpp)
    2.25  else
    2.26  	libgl = -lGL -lGLU -lglut -lGLEW
    2.27 -	ovrlibs = -lovr
    2.28 +
    2.29 +	ovr_include = -Ilibovr/Include -Ilibovr/Src -Ilibovr/Src/linux
    2.30 +	ovr_sys_src = $(wildcard libovr/Src/linux/*.cpp)
    2.31  endif
    2.32  
    2.33  $(bin): $(obj)
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/libovr/Include/OVR.h	Sat Sep 14 16:14:59 2013 +0300
     3.3 @@ -0,0 +1,34 @@
     3.4 +/************************************************************************************
     3.5 +
     3.6 +Filename    :   OVR.h
     3.7 +Content     :   This contains references to all OVR-specific headers in Src folder.
     3.8 +                Should be generated automatically based on PublicHeader tags.
     3.9 +
    3.10 +Copyright   :   Copyright 2012 Oculus VR, Inc. All Rights reserved.
    3.11 +
    3.12 +Use of this software is subject to the terms of the Oculus license
    3.13 +agreement provided at the time of installation or download, or which
    3.14 +otherwise accompanies this software in either electronic or hard copy form.
    3.15 +
    3.16 +*************************************************************************************/
    3.17 +
    3.18 +#ifndef OVR_h
    3.19 +#define OVR_h
    3.20 +
    3.21 +#include "../Src/Kernel/OVR_Allocator.h"
    3.22 +#include "../Src/Kernel/OVR_Log.h"
    3.23 +#include "../Src/Kernel/OVR_Math.h"
    3.24 +#include "../Src/Kernel/OVR_System.h"
    3.25 +#include "../Src/Kernel/OVR_Types.h"
    3.26 +#include "../Src/OVR_Device.h"
    3.27 +#include "../Src/OVR_DeviceConstants.h"
    3.28 +#include "../Src/OVR_DeviceHandle.h"
    3.29 +#include "../Src/OVR_DeviceMessages.h"
    3.30 +#include "../Src/OVR_SensorFusion.h"
    3.31 +#include "../Src/OVR_Profile.h"
    3.32 +#include "../Src/Util/Util_LatencyTest.h"
    3.33 +#include "../Src/Util/Util_Render_Stereo.h"
    3.34 +#include "../Src/Util/Util_MagCalibration.h"
    3.35 +
    3.36 +#endif
    3.37 +
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/libovr/Include/OVRVersion.h	Sat Sep 14 16:14:59 2013 +0300
     4.3 @@ -0,0 +1,22 @@
     4.4 +/************************************************************************************
     4.5 +
     4.6 +Filename    :   OVRVersion.h
     4.7 +Content     :   
     4.8 +
     4.9 +Copyright   :   Copyright 2012 Oculus VR, Inc. All Rights reserved.
    4.10 +
    4.11 +Use of this software is subject to the terms of the Oculus license
    4.12 +agreement provided at the time of installation or download, or which
    4.13 +otherwise accompanies this software in either electronic or hard copy form.
    4.14 +
    4.15 +*************************************************************************************/
    4.16 +
    4.17 +#ifndef _OVR_VERSION_H
    4.18 +#define _OVR_VERSION_H
    4.19 +
    4.20 +#define OVR_MAJOR_VERSION 0
    4.21 +#define OVR_MINOR_VERSION 2
    4.22 +#define OVR_BUILD_VERSION 4
    4.23 +#define OVR_VERSION_STRING "0.2.4"
    4.24 +
    4.25 +#endif
     5.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.2 +++ b/libovr/Src/Kernel/OVR_Alg.cpp	Sat Sep 14 16:14:59 2013 +0300
     5.3 @@ -0,0 +1,1 @@
     5.4 +/************************************************************************************
     5.5 
     5.6 Filename    :   OVR_Alg.cpp
     5.7 Content     :   Static lookup tables for Alg functions
     5.8 Created     :   September 19, 2012
     5.9 Notes       : 
    5.10 
    5.11 Copyright   :   Copyright 2012 Oculus VR, Inc. All Rights reserved.
    5.12 
    5.13 Use of this software is subject to the terms of the Oculus license
    5.14 agreement provided at the time of installation or download, or which
    5.15 otherwise accompanies this software in either electronic or hard copy form.
    5.16 
    5.17 ************************************************************************************/
    5.18 
    5.19 #include "OVR_Types.h"
    5.20 
    5.21 namespace OVR { namespace Alg {
    5.22 
    5.23 //------------------------------------------------------------------------
    5.24 extern const UByte UpperBitTable[256] =
    5.25 {
    5.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,
    5.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,
    5.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,
    5.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,
    5.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,
    5.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,
    5.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,
    5.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
    5.34 };
    5.35 
    5.36 extern const UByte LowerBitTable[256] =
    5.37 {
    5.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,
    5.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,
    5.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,
    5.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,
    5.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,
    5.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,
    5.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,
    5.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
    5.46 };
    5.47 
    5.48 
    5.49 }} // OVE::Alg
    5.50 \ No newline at end of file
     6.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     6.2 +++ b/libovr/Src/Kernel/OVR_Alg.h	Sat Sep 14 16:14:59 2013 +0300
     6.3 @@ -0,0 +1,1 @@
     6.4 +/************************************************************************************
     6.5 
     6.6 PublicHeader:   OVR.h
     6.7 Filename    :   OVR_Alg.h
     6.8 Content     :   Simple general purpose algorithms: Sort, Binary Search, etc.
     6.9 Created     :   September 19, 2012
    6.10 Notes       : 
    6.11 
    6.12 Copyright   :   Copyright 2012 Oculus VR, Inc. All Rights reserved.
    6.13 
    6.14 Use of this software is subject to the terms of the Oculus license
    6.15 agreement provided at the time of installation or download, or which
    6.16 otherwise accompanies this software in either electronic or hard copy form.
    6.17 
    6.18 ************************************************************************************/
    6.19 
    6.20 #ifndef OVR_Alg_h
    6.21 #define OVR_Alg_h
    6.22 
    6.23 #include "OVR_Types.h"
    6.24 #include <string.h>
    6.25 
    6.26 namespace OVR { namespace Alg {
    6.27 
    6.28 
    6.29 //-----------------------------------------------------------------------------------
    6.30 // ***** Operator extensions
    6.31 
    6.32 template <typename T> OVR_FORCE_INLINE void Swap(T &a, T &b) 
    6.33 {  T temp(a); a = b; b = temp; }
    6.34 
    6.35 
    6.36 // ***** min/max are not implemented in Visual Studio 6 standard STL
    6.37 
    6.38 template <typename T> OVR_FORCE_INLINE const T Min(const T a, const T b)
    6.39 { return (a < b) ? a : b; }
    6.40 
    6.41 template <typename T> OVR_FORCE_INLINE const T Max(const T a, const T b)
    6.42 { return (b < a) ? a : b; }
    6.43 
    6.44 template <typename T> OVR_FORCE_INLINE const T Clamp(const T v, const T minVal, const T maxVal)
    6.45 { return Max<T>(minVal, Min<T>(v, maxVal)); }
    6.46 
    6.47 template <typename T> OVR_FORCE_INLINE int     Chop(T f)
    6.48 { return (int)f; }
    6.49 
    6.50 template <typename T> OVR_FORCE_INLINE T       Lerp(T a, T b, T f) 
    6.51 { return (b - a) * f + a; }
    6.52 
    6.53 
    6.54 // These functions stand to fix a stupid VC++ warning (with /Wp64 on):
    6.55 // "warning C4267: 'argument' : conversion from 'size_t' to 'const unsigned', possible loss of data"
    6.56 // Use these functions instead of gmin/gmax if the argument has size
    6.57 // of the pointer to avoid the warning. Though, functionally they are
    6.58 // absolutelly the same as regular gmin/gmax.
    6.59 template <typename T>   OVR_FORCE_INLINE const T PMin(const T a, const T b)
    6.60 {
    6.61     OVR_COMPILER_ASSERT(sizeof(T) == sizeof(UPInt));
    6.62     return (a < b) ? a : b;
    6.63 }
    6.64 template <typename T>   OVR_FORCE_INLINE const T PMax(const T a, const T b)
    6.65 {
    6.66     OVR_COMPILER_ASSERT(sizeof(T) == sizeof(UPInt));
    6.67     return (b < a) ? a : b;
    6.68 }
    6.69 
    6.70 
    6.71 template <typename T>   OVR_FORCE_INLINE const T Abs(const T v)
    6.72 { return (v>=0) ? v : -v; }
    6.73 
    6.74 
    6.75 //-----------------------------------------------------------------------------------
    6.76 // ***** OperatorLess
    6.77 //
    6.78 template<class T> struct OperatorLess
    6.79 {
    6.80     static bool Compare(const T& a, const T& b)
    6.81     {
    6.82         return a < b;
    6.83     }
    6.84 };
    6.85 
    6.86 
    6.87 //-----------------------------------------------------------------------------------
    6.88 // ***** QuickSortSliced
    6.89 //
    6.90 // Sort any part of any array: plain, Array, ArrayPaged, ArrayUnsafe.
    6.91 // The range is specified with start, end, where "end" is exclusive!
    6.92 // The comparison predicate must be specified.
    6.93 template<class Array, class Less> 
    6.94 void QuickSortSliced(Array& arr, UPInt start, UPInt end, Less less)
    6.95 {
    6.96     enum 
    6.97     {
    6.98         Threshold = 9
    6.99     };
   6.100 
   6.101     if(end - start <  2) return;
   6.102 
   6.103     SPInt  stack[80];
   6.104     SPInt* top   = stack; 
   6.105     SPInt  base  = (SPInt)start;
   6.106     SPInt  limit = (SPInt)end;
   6.107 
   6.108     for(;;)
   6.109     {
   6.110         SPInt len = limit - base;
   6.111         SPInt i, j, pivot;
   6.112 
   6.113         if(len > Threshold)
   6.114         {
   6.115             // we use base + len/2 as the pivot
   6.116             pivot = base + len / 2;
   6.117             Swap(arr[base], arr[pivot]);
   6.118 
   6.119             i = base + 1;
   6.120             j = limit - 1;
   6.121 
   6.122             // now ensure that *i <= *base <= *j 
   6.123             if(less(arr[j],    arr[i])) Swap(arr[j],    arr[i]);
   6.124             if(less(arr[base], arr[i])) Swap(arr[base], arr[i]);
   6.125             if(less(arr[j], arr[base])) Swap(arr[j], arr[base]);
   6.126 
   6.127             for(;;)
   6.128             {
   6.129                 do i++; while( less(arr[i], arr[base]) );
   6.130                 do j--; while( less(arr[base], arr[j]) );
   6.131 
   6.132                 if( i > j )
   6.133                 {
   6.134                     break;
   6.135                 }
   6.136 
   6.137                 Swap(arr[i], arr[j]);
   6.138             }
   6.139 
   6.140             Swap(arr[base], arr[j]);
   6.141 
   6.142             // now, push the largest sub-array
   6.143             if(j - base > limit - i)
   6.144             {
   6.145                 top[0] = base;
   6.146                 top[1] = j;
   6.147                 base   = i;
   6.148             }
   6.149             else
   6.150             {
   6.151                 top[0] = i;
   6.152                 top[1] = limit;
   6.153                 limit  = j;
   6.154             }
   6.155             top += 2;
   6.156         }
   6.157         else
   6.158         {
   6.159             // the sub-array is small, perform insertion sort
   6.160             j = base;
   6.161             i = j + 1;
   6.162 
   6.163             for(; i < limit; j = i, i++)
   6.164             {
   6.165                 for(; less(arr[j + 1], arr[j]); j--)
   6.166                 {
   6.167                     Swap(arr[j + 1], arr[j]);
   6.168                     if(j == base)
   6.169                     {
   6.170                         break;
   6.171                     }
   6.172                 }
   6.173             }
   6.174             if(top > stack)
   6.175             {
   6.176                 top  -= 2;
   6.177                 base  = top[0];
   6.178                 limit = top[1];
   6.179             }
   6.180             else
   6.181             {
   6.182                 break;
   6.183             }
   6.184         }
   6.185     }
   6.186 }
   6.187 
   6.188 
   6.189 //-----------------------------------------------------------------------------------
   6.190 // ***** QuickSortSliced
   6.191 //
   6.192 // Sort any part of any array: plain, Array, ArrayPaged, ArrayUnsafe.
   6.193 // The range is specified with start, end, where "end" is exclusive!
   6.194 // The data type must have a defined "<" operator.
   6.195 template<class Array> 
   6.196 void QuickSortSliced(Array& arr, UPInt start, UPInt end)
   6.197 {
   6.198     typedef typename Array::ValueType ValueType;
   6.199     QuickSortSliced(arr, start, end, OperatorLess<ValueType>::Compare);
   6.200 }
   6.201 
   6.202 // Same as corresponding G_QuickSortSliced but with checking array limits to avoid
   6.203 // crash in the case of wrong comparator functor.
   6.204 template<class Array, class Less> 
   6.205 bool QuickSortSlicedSafe(Array& arr, UPInt start, UPInt end, Less less)
   6.206 {
   6.207     enum 
   6.208     {
   6.209         Threshold = 9
   6.210     };
   6.211 
   6.212     if(end - start <  2) return true;
   6.213 
   6.214     SPInt  stack[80];
   6.215     SPInt* top   = stack; 
   6.216     SPInt  base  = (SPInt)start;
   6.217     SPInt  limit = (SPInt)end;
   6.218 
   6.219     for(;;)
   6.220     {
   6.221         SPInt len = limit - base;
   6.222         SPInt i, j, pivot;
   6.223 
   6.224         if(len > Threshold)
   6.225         {
   6.226             // we use base + len/2 as the pivot
   6.227             pivot = base + len / 2;
   6.228             Swap(arr[base], arr[pivot]);
   6.229 
   6.230             i = base + 1;
   6.231             j = limit - 1;
   6.232 
   6.233             // now ensure that *i <= *base <= *j 
   6.234             if(less(arr[j],    arr[i])) Swap(arr[j],    arr[i]);
   6.235             if(less(arr[base], arr[i])) Swap(arr[base], arr[i]);
   6.236             if(less(arr[j], arr[base])) Swap(arr[j], arr[base]);
   6.237 
   6.238             for(;;)
   6.239             {
   6.240                 do 
   6.241                 {   
   6.242                     i++; 
   6.243                     if (i >= limit)
   6.244                         return false;
   6.245                 } while( less(arr[i], arr[base]) );
   6.246                 do 
   6.247                 {
   6.248                     j--; 
   6.249                     if (j < 0)
   6.250                         return false;
   6.251                 } while( less(arr[base], arr[j]) );
   6.252 
   6.253                 if( i > j )
   6.254                 {
   6.255                     break;
   6.256                 }
   6.257 
   6.258                 Swap(arr[i], arr[j]);
   6.259             }
   6.260 
   6.261             Swap(arr[base], arr[j]);
   6.262 
   6.263             // now, push the largest sub-array
   6.264             if(j - base > limit - i)
   6.265             {
   6.266                 top[0] = base;
   6.267                 top[1] = j;
   6.268                 base   = i;
   6.269             }
   6.270             else
   6.271             {
   6.272                 top[0] = i;
   6.273                 top[1] = limit;
   6.274                 limit  = j;
   6.275             }
   6.276             top += 2;
   6.277         }
   6.278         else
   6.279         {
   6.280             // the sub-array is small, perform insertion sort
   6.281             j = base;
   6.282             i = j + 1;
   6.283 
   6.284             for(; i < limit; j = i, i++)
   6.285             {
   6.286                 for(; less(arr[j + 1], arr[j]); j--)
   6.287                 {
   6.288                     Swap(arr[j + 1], arr[j]);
   6.289                     if(j == base)
   6.290                     {
   6.291                         break;
   6.292                     }
   6.293                 }
   6.294             }
   6.295             if(top > stack)
   6.296             {
   6.297                 top  -= 2;
   6.298                 base  = top[0];
   6.299                 limit = top[1];
   6.300             }
   6.301             else
   6.302             {
   6.303                 break;
   6.304             }
   6.305         }
   6.306     }
   6.307     return true;
   6.308 }
   6.309 
   6.310 template<class Array> 
   6.311 bool QuickSortSlicedSafe(Array& arr, UPInt start, UPInt end)
   6.312 {
   6.313     typedef typename Array::ValueType ValueType;
   6.314     return QuickSortSlicedSafe(arr, start, end, OperatorLess<ValueType>::Compare);
   6.315 }
   6.316 
   6.317 //-----------------------------------------------------------------------------------
   6.318 // ***** QuickSort
   6.319 //
   6.320 // Sort an array Array, ArrayPaged, ArrayUnsafe.
   6.321 // The array must have GetSize() function.
   6.322 // The comparison predicate must be specified.
   6.323 template<class Array, class Less> 
   6.324 void QuickSort(Array& arr, Less less)
   6.325 {
   6.326     QuickSortSliced(arr, 0, arr.GetSize(), less);
   6.327 }
   6.328 
   6.329 // checks for boundaries
   6.330 template<class Array, class Less> 
   6.331 bool QuickSortSafe(Array& arr, Less less)
   6.332 {
   6.333     return QuickSortSlicedSafe(arr, 0, arr.GetSize(), less);
   6.334 }
   6.335 
   6.336 
   6.337 //-----------------------------------------------------------------------------------
   6.338 // ***** QuickSort
   6.339 //
   6.340 // Sort an array Array, ArrayPaged, ArrayUnsafe.
   6.341 // The array must have GetSize() function.
   6.342 // The data type must have a defined "<" operator.
   6.343 template<class Array> 
   6.344 void QuickSort(Array& arr)
   6.345 {
   6.346     typedef typename Array::ValueType ValueType;
   6.347     QuickSortSliced(arr, 0, arr.GetSize(), OperatorLess<ValueType>::Compare);
   6.348 }
   6.349 
   6.350 template<class Array> 
   6.351 bool QuickSortSafe(Array& arr)
   6.352 {
   6.353     typedef typename Array::ValueType ValueType;
   6.354     return QuickSortSlicedSafe(arr, 0, arr.GetSize(), OperatorLess<ValueType>::Compare);
   6.355 }
   6.356 
   6.357 //-----------------------------------------------------------------------------------
   6.358 // ***** InsertionSortSliced
   6.359 //
   6.360 // Sort any part of any array: plain, Array, ArrayPaged, ArrayUnsafe.
   6.361 // The range is specified with start, end, where "end" is exclusive!
   6.362 // The comparison predicate must be specified.
   6.363 // Unlike Quick Sort, the Insertion Sort works much slower in average, 
   6.364 // but may be much faster on almost sorted arrays. Besides, it guarantees
   6.365 // that the elements will not be swapped if not necessary. For example, 
   6.366 // an array with all equal elements will remain "untouched", while 
   6.367 // Quick Sort will considerably shuffle the elements in this case.
   6.368 template<class Array, class Less> 
   6.369 void InsertionSortSliced(Array& arr, UPInt start, UPInt end, Less less)
   6.370 {
   6.371     UPInt j = start;
   6.372     UPInt i = j + 1;
   6.373     UPInt limit = end;
   6.374 
   6.375     for(; i < limit; j = i, i++)
   6.376     {
   6.377         for(; less(arr[j + 1], arr[j]); j--)
   6.378         {
   6.379             Swap(arr[j + 1], arr[j]);
   6.380             if(j <= start)
   6.381             {
   6.382                 break;
   6.383             }
   6.384         }
   6.385     }
   6.386 }
   6.387 
   6.388 
   6.389 //-----------------------------------------------------------------------------------
   6.390 // ***** InsertionSortSliced
   6.391 //
   6.392 // Sort any part of any array: plain, Array, ArrayPaged, ArrayUnsafe.
   6.393 // The range is specified with start, end, where "end" is exclusive!
   6.394 // The data type must have a defined "<" operator.
   6.395 template<class Array> 
   6.396 void InsertionSortSliced(Array& arr, UPInt start, UPInt end)
   6.397 {
   6.398     typedef typename Array::ValueType ValueType;
   6.399     InsertionSortSliced(arr, start, end, OperatorLess<ValueType>::Compare);
   6.400 }
   6.401 
   6.402 //-----------------------------------------------------------------------------------
   6.403 // ***** InsertionSort
   6.404 //
   6.405 // Sort an array Array, ArrayPaged, ArrayUnsafe.
   6.406 // The array must have GetSize() function.
   6.407 // The comparison predicate must be specified.
   6.408 
   6.409 template<class Array, class Less> 
   6.410 void InsertionSort(Array& arr, Less less)
   6.411 {
   6.412     InsertionSortSliced(arr, 0, arr.GetSize(), less);
   6.413 }
   6.414 
   6.415 //-----------------------------------------------------------------------------------
   6.416 // ***** InsertionSort
   6.417 //
   6.418 // Sort an array Array, ArrayPaged, ArrayUnsafe.
   6.419 // The array must have GetSize() function.
   6.420 // The data type must have a defined "<" operator.
   6.421 template<class Array> 
   6.422 void InsertionSort(Array& arr)
   6.423 {
   6.424     typedef typename Array::ValueType ValueType;
   6.425     InsertionSortSliced(arr, 0, arr.GetSize(), OperatorLess<ValueType>::Compare);
   6.426 }
   6.427 
   6.428 
   6.429 
   6.430 //-----------------------------------------------------------------------------------
   6.431 // ***** LowerBoundSliced
   6.432 //
   6.433 template<class Array, class Value, class Less>
   6.434 UPInt LowerBoundSliced(const Array& arr, UPInt start, UPInt end, const Value& val, Less less)
   6.435 {
   6.436     SPInt first = (SPInt)start;
   6.437     SPInt len   = (SPInt)(end - start);
   6.438     SPInt half;
   6.439     SPInt middle;
   6.440     
   6.441     while(len > 0) 
   6.442     {
   6.443         half = len >> 1;
   6.444         middle = first + half;
   6.445         if(less(arr[middle], val)) 
   6.446         {
   6.447             first = middle + 1;
   6.448             len   = len - half - 1;
   6.449         }
   6.450         else
   6.451         {
   6.452             len = half;
   6.453         }
   6.454     }
   6.455     return (UPInt)first;
   6.456 }
   6.457 
   6.458 
   6.459 //-----------------------------------------------------------------------------------
   6.460 // ***** LowerBoundSliced
   6.461 //
   6.462 template<class Array, class Value>
   6.463 UPInt LowerBoundSliced(const Array& arr, UPInt start, UPInt end, const Value& val)
   6.464 {
   6.465     return LowerBoundSliced(arr, start, end, val, OperatorLess<Value>::Compare);
   6.466 }
   6.467 
   6.468 //-----------------------------------------------------------------------------------
   6.469 // ***** LowerBoundSized
   6.470 //
   6.471 template<class Array, class Value>
   6.472 UPInt LowerBoundSized(const Array& arr, UPInt size, const Value& val)
   6.473 {
   6.474     return LowerBoundSliced(arr, 0, size, val, OperatorLess<Value>::Compare);
   6.475 }
   6.476 
   6.477 //-----------------------------------------------------------------------------------
   6.478 // ***** LowerBound
   6.479 //
   6.480 template<class Array, class Value, class Less>
   6.481 UPInt LowerBound(const Array& arr, const Value& val, Less less)
   6.482 {
   6.483     return LowerBoundSliced(arr, 0, arr.GetSize(), val, less);
   6.484 }
   6.485 
   6.486 
   6.487 //-----------------------------------------------------------------------------------
   6.488 // ***** LowerBound
   6.489 //
   6.490 template<class Array, class Value>
   6.491 UPInt LowerBound(const Array& arr, const Value& val)
   6.492 {
   6.493     return LowerBoundSliced(arr, 0, arr.GetSize(), val, OperatorLess<Value>::Compare);
   6.494 }
   6.495 
   6.496 
   6.497 
   6.498 //-----------------------------------------------------------------------------------
   6.499 // ***** UpperBoundSliced
   6.500 //
   6.501 template<class Array, class Value, class Less>
   6.502 UPInt UpperBoundSliced(const Array& arr, UPInt start, UPInt end, const Value& val, Less less)
   6.503 {
   6.504     SPInt first = (SPInt)start;
   6.505     SPInt len   = (SPInt)(end - start);
   6.506     SPInt half;
   6.507     SPInt middle;
   6.508     
   6.509     while(len > 0) 
   6.510     {
   6.511         half = len >> 1;
   6.512         middle = first + half;
   6.513         if(less(val, arr[middle]))
   6.514         {
   6.515             len = half;
   6.516         }
   6.517         else 
   6.518         {
   6.519             first = middle + 1;
   6.520             len   = len - half - 1;
   6.521         }
   6.522     }
   6.523     return (UPInt)first;
   6.524 }
   6.525 
   6.526 
   6.527 //-----------------------------------------------------------------------------------
   6.528 // ***** UpperBoundSliced
   6.529 //
   6.530 template<class Array, class Value>
   6.531 UPInt UpperBoundSliced(const Array& arr, UPInt start, UPInt end, const Value& val)
   6.532 {
   6.533     return UpperBoundSliced(arr, start, end, val, OperatorLess<Value>::Compare);
   6.534 }
   6.535 
   6.536 
   6.537 //-----------------------------------------------------------------------------------
   6.538 // ***** UpperBoundSized
   6.539 //
   6.540 template<class Array, class Value>
   6.541 UPInt UpperBoundSized(const Array& arr, UPInt size, const Value& val)
   6.542 {
   6.543     return UpperBoundSliced(arr, 0, size, val, OperatorLess<Value>::Compare);
   6.544 }
   6.545 
   6.546 
   6.547 //-----------------------------------------------------------------------------------
   6.548 // ***** UpperBound
   6.549 //
   6.550 template<class Array, class Value, class Less>
   6.551 UPInt UpperBound(const Array& arr, const Value& val, Less less)
   6.552 {
   6.553     return UpperBoundSliced(arr, 0, arr.GetSize(), val, less);
   6.554 }
   6.555 
   6.556 
   6.557 //-----------------------------------------------------------------------------------
   6.558 // ***** UpperBound
   6.559 //
   6.560 template<class Array, class Value>
   6.561 UPInt UpperBound(const Array& arr, const Value& val)
   6.562 {
   6.563     return UpperBoundSliced(arr, 0, arr.GetSize(), val, OperatorLess<Value>::Compare);
   6.564 }
   6.565 
   6.566 
   6.567 //-----------------------------------------------------------------------------------
   6.568 // ***** ReverseArray
   6.569 //
   6.570 template<class Array> void ReverseArray(Array& arr)
   6.571 {
   6.572     SPInt from = 0;
   6.573     SPInt to   = arr.GetSize() - 1;
   6.574     while(from < to)
   6.575     {
   6.576         Swap(arr[from], arr[to]);
   6.577         ++from;
   6.578         --to;
   6.579     }
   6.580 }
   6.581 
   6.582 
   6.583 // ***** AppendArray
   6.584 //
   6.585 template<class CDst, class CSrc> 
   6.586 void AppendArray(CDst& dst, const CSrc& src)
   6.587 {
   6.588     UPInt i;
   6.589     for(i = 0; i < src.GetSize(); i++) 
   6.590         dst.PushBack(src[i]);
   6.591 }
   6.592 
   6.593 //-----------------------------------------------------------------------------------
   6.594 // ***** ArrayAdaptor
   6.595 //
   6.596 // A simple adapter that provides the GetSize() method and overloads 
   6.597 // operator []. Used to wrap plain arrays in QuickSort and such.
   6.598 template<class T> class ArrayAdaptor
   6.599 {
   6.600 public:
   6.601     typedef T ValueType;
   6.602     ArrayAdaptor() : Data(0), Size(0) {}
   6.603     ArrayAdaptor(T* ptr, UPInt size) : Data(ptr), Size(size) {}
   6.604     UPInt GetSize() const { return Size; }
   6.605     const T& operator [] (UPInt i) const { return Data[i]; }
   6.606           T& operator [] (UPInt i)       { return Data[i]; }
   6.607 private:
   6.608     T*      Data;
   6.609     UPInt   Size;
   6.610 };
   6.611 
   6.612 
   6.613 //-----------------------------------------------------------------------------------
   6.614 // ***** GConstArrayAdaptor
   6.615 //
   6.616 // A simple const adapter that provides the GetSize() method and overloads 
   6.617 // operator []. Used to wrap plain arrays in LowerBound and such.
   6.618 template<class T> class ConstArrayAdaptor
   6.619 {
   6.620 public:
   6.621     typedef T ValueType;
   6.622     ConstArrayAdaptor() : Data(0), Size(0) {}
   6.623     ConstArrayAdaptor(const T* ptr, UPInt size) : Data(ptr), Size(size) {}
   6.624     UPInt GetSize() const { return Size; }
   6.625     const T& operator [] (UPInt i) const { return Data[i]; }
   6.626 private:
   6.627     const T* Data;
   6.628     UPInt    Size;
   6.629 };
   6.630 
   6.631 
   6.632 
   6.633 //-----------------------------------------------------------------------------------
   6.634 extern const UByte UpperBitTable[256];
   6.635 extern const UByte LowerBitTable[256];
   6.636 
   6.637 
   6.638 
   6.639 //-----------------------------------------------------------------------------------
   6.640 inline UByte UpperBit(UPInt val)
   6.641 {
   6.642 #ifndef OVR_64BIT_POINTERS
   6.643 
   6.644     if (val & 0xFFFF0000)
   6.645     {
   6.646         return (val & 0xFF000000) ? 
   6.647             UpperBitTable[(val >> 24)       ] + 24: 
   6.648             UpperBitTable[(val >> 16) & 0xFF] + 16;
   6.649     }
   6.650     return (val & 0xFF00) ?
   6.651         UpperBitTable[(val >> 8) & 0xFF] + 8:
   6.652         UpperBitTable[(val     ) & 0xFF];
   6.653 
   6.654 #else
   6.655 
   6.656     if (val & 0xFFFFFFFF00000000)
   6.657     {
   6.658         if (val & 0xFFFF000000000000)
   6.659         {
   6.660             return (val & 0xFF00000000000000) ?
   6.661                 UpperBitTable[(val >> 56)       ] + 56: 
   6.662                 UpperBitTable[(val >> 48) & 0xFF] + 48;
   6.663         }
   6.664         return (val & 0xFF0000000000) ?
   6.665             UpperBitTable[(val >> 40) & 0xFF] + 40:
   6.666             UpperBitTable[(val >> 32) & 0xFF] + 32;
   6.667     }
   6.668     else
   6.669     {
   6.670         if (val & 0xFFFF0000)
   6.671         {
   6.672             return (val & 0xFF000000) ? 
   6.673                 UpperBitTable[(val >> 24)       ] + 24: 
   6.674                 UpperBitTable[(val >> 16) & 0xFF] + 16;
   6.675         }
   6.676         return (val & 0xFF00) ?
   6.677             UpperBitTable[(val >> 8) & 0xFF] + 8:
   6.678             UpperBitTable[(val     ) & 0xFF];
   6.679     }
   6.680 
   6.681 #endif
   6.682 }
   6.683 
   6.684 //-----------------------------------------------------------------------------------
   6.685 inline UByte LowerBit(UPInt val)
   6.686 {
   6.687 #ifndef OVR_64BIT_POINTERS
   6.688 
   6.689     if (val & 0xFFFF)
   6.690     {
   6.691         return (val & 0xFF) ?
   6.692             LowerBitTable[ val & 0xFF]:
   6.693             LowerBitTable[(val >> 8) & 0xFF] + 8;
   6.694     }
   6.695     return (val & 0xFF0000) ?
   6.696             LowerBitTable[(val >> 16) & 0xFF] + 16:
   6.697             LowerBitTable[(val >> 24) & 0xFF] + 24;
   6.698 
   6.699 #else
   6.700 
   6.701     if (val & 0xFFFFFFFF)
   6.702     {
   6.703         if (val & 0xFFFF)
   6.704         {
   6.705             return (val & 0xFF) ?
   6.706                 LowerBitTable[ val & 0xFF]:
   6.707                 LowerBitTable[(val >> 8) & 0xFF] + 8;
   6.708         }
   6.709         return (val & 0xFF0000) ?
   6.710                 LowerBitTable[(val >> 16) & 0xFF] + 16:
   6.711                 LowerBitTable[(val >> 24) & 0xFF] + 24;
   6.712     }
   6.713     else
   6.714     {
   6.715         if (val & 0xFFFF00000000)
   6.716         {
   6.717              return (val & 0xFF00000000) ?
   6.718                 LowerBitTable[(val >> 32) & 0xFF] + 32:
   6.719                 LowerBitTable[(val >> 40) & 0xFF] + 40;
   6.720         }
   6.721         return (val & 0xFF000000000000) ?
   6.722             LowerBitTable[(val >> 48) & 0xFF] + 48:
   6.723             LowerBitTable[(val >> 56) & 0xFF] + 56;
   6.724     }
   6.725 
   6.726 #endif
   6.727 }
   6.728 
   6.729 
   6.730 
   6.731 // ******* Special (optimized) memory routines
   6.732 // Note: null (bad) pointer is not tested
   6.733 class MemUtil
   6.734 {
   6.735 public:
   6.736                                     
   6.737     // Memory compare
   6.738     static int      Cmp  (const void* p1, const void* p2, UPInt byteCount)      { return memcmp(p1, p2, byteCount); }
   6.739     static int      Cmp16(const void* p1, const void* p2, UPInt int16Count);
   6.740     static int      Cmp32(const void* p1, const void* p2, UPInt int32Count);
   6.741     static int      Cmp64(const void* p1, const void* p2, UPInt int64Count); 
   6.742 };
   6.743 
   6.744 // ** Inline Implementation
   6.745 
   6.746 inline int MemUtil::Cmp16(const void* p1, const void* p2, UPInt int16Count)
   6.747 {
   6.748     SInt16*  pa  = (SInt16*)p1; 
   6.749     SInt16*  pb  = (SInt16*)p2;
   6.750     unsigned ic  = 0;
   6.751     if (int16Count == 0)
   6.752         return 0;
   6.753     while (pa[ic] == pb[ic])
   6.754         if (++ic==int16Count)
   6.755             return 0;
   6.756     return pa[ic] > pb[ic] ? 1 : -1;
   6.757 }
   6.758 inline int MemUtil::Cmp32(const void* p1, const void* p2, UPInt int32Count)
   6.759 {
   6.760     SInt32*  pa  = (SInt32*)p1;
   6.761     SInt32*  pb  = (SInt32*)p2;
   6.762     unsigned ic  = 0;
   6.763     if (int32Count == 0)
   6.764         return 0;
   6.765     while (pa[ic] == pb[ic])
   6.766         if (++ic==int32Count)
   6.767             return 0;
   6.768     return pa[ic] > pb[ic] ? 1 : -1;
   6.769 }
   6.770 inline int MemUtil::Cmp64(const void* p1, const void* p2, UPInt int64Count)
   6.771 {
   6.772     SInt64*  pa  = (SInt64*)p1;
   6.773     SInt64*  pb  = (SInt64*)p2;
   6.774     unsigned ic  = 0;
   6.775     if (int64Count == 0)
   6.776         return 0;
   6.777     while (pa[ic] == pb[ic])
   6.778         if (++ic==int64Count)
   6.779             return 0;
   6.780     return pa[ic] > pb[ic] ? 1 : -1;
   6.781 }
   6.782 
   6.783 // ** End Inline Implementation
   6.784 
   6.785 
   6.786 //-----------------------------------------------------------------------------------
   6.787 // ******* Byte Order Conversions
   6.788 namespace ByteUtil {
   6.789 
   6.790     // *** Swap Byte Order
   6.791 
   6.792     // Swap the byte order of a byte array
   6.793     inline void     SwapOrder(void* pv, int size)
   6.794     {
   6.795         UByte*  pb = (UByte*)pv;
   6.796         UByte   temp;
   6.797         for (int i = 0; i < size>>1; i++)
   6.798         { 
   6.799             temp            = pb[size-1-i];
   6.800             pb[size-1-i]    = pb[i];
   6.801             pb[i]           = temp; 
   6.802         }
   6.803     }
   6.804 
   6.805     // Swap the byte order of primitive types
   6.806     inline UByte    SwapOrder(UByte v)      { return v; }
   6.807     inline SByte    SwapOrder(SByte v)      { return v; }
   6.808     inline UInt16   SwapOrder(UInt16 v)     { return UInt16(v>>8)|UInt16(v<<8); }
   6.809     inline SInt16   SwapOrder(SInt16 v)     { return SInt16((UInt16(v)>>8)|(v<<8)); }
   6.810     inline UInt32   SwapOrder(UInt32 v)     { return (v>>24)|((v&0x00FF0000)>>8)|((v&0x0000FF00)<<8)|(v<<24); }
   6.811     inline SInt32   SwapOrder(SInt32 p)     { return (SInt32)SwapOrder(UInt32(p)); }
   6.812     inline UInt64   SwapOrder(UInt64 v)
   6.813     { 
   6.814         return   (v>>56) |
   6.815                  ((v&UInt64(0x00FF000000000000))>>40) |
   6.816                  ((v&UInt64(0x0000FF0000000000))>>24) |
   6.817                  ((v&UInt64(0x000000FF00000000))>>8)  |
   6.818                  ((v&UInt64(0x00000000FF000000))<<8)  |
   6.819                  ((v&UInt64(0x0000000000FF0000))<<24) |
   6.820                  ((v&UInt64(0x000000000000FF00))<<40) |
   6.821                  (v<<56); 
   6.822     }
   6.823     inline SInt64   SwapOrder(SInt64 v)     { return (SInt64)SwapOrder(UInt64(v)); }
   6.824     inline float    SwapOrder(float p)      
   6.825     { 
   6.826         union {
   6.827             float p;
   6.828             UInt32 v;
   6.829         } u;
   6.830         u.p = p;
   6.831         u.v = SwapOrder(u.v);
   6.832         return u.p;
   6.833     }
   6.834 
   6.835     inline double   SwapOrder(double p)
   6.836     { 
   6.837         union {
   6.838             double p;
   6.839             UInt64 v;
   6.840         } u;
   6.841         u.p = p;
   6.842         u.v = SwapOrder(u.v);
   6.843         return u.p;
   6.844     }
   6.845     
   6.846     // *** Byte-order conversion
   6.847 
   6.848 #if (OVR_BYTE_ORDER == OVR_LITTLE_ENDIAN)
   6.849     // Little Endian to System (LE)
   6.850     inline UByte    LEToSystem(UByte  v)    { return v; }
   6.851     inline SByte    LEToSystem(SByte  v)    { return v; }
   6.852     inline UInt16   LEToSystem(UInt16 v)    { return v; }
   6.853     inline SInt16   LEToSystem(SInt16 v)    { return v; }
   6.854     inline UInt32   LEToSystem(UInt32 v)    { return v; }
   6.855     inline SInt32   LEToSystem(SInt32 v)    { return v; }
   6.856     inline UInt64   LEToSystem(UInt64 v)    { return v; }
   6.857     inline SInt64   LEToSystem(SInt64 v)    { return v; }
   6.858     inline float    LEToSystem(float  v)    { return v; }
   6.859     inline double   LEToSystem(double v)    { return v; }
   6.860 
   6.861     // Big Endian to System (LE)
   6.862     inline UByte    BEToSystem(UByte  v)    { return SwapOrder(v); }
   6.863     inline SByte    BEToSystem(SByte  v)    { return SwapOrder(v); }
   6.864     inline UInt16   BEToSystem(UInt16 v)    { return SwapOrder(v); }
   6.865     inline SInt16   BEToSystem(SInt16 v)    { return SwapOrder(v); }
   6.866     inline UInt32   BEToSystem(UInt32 v)    { return SwapOrder(v); }
   6.867     inline SInt32   BEToSystem(SInt32 v)    { return SwapOrder(v); }
   6.868     inline UInt64   BEToSystem(UInt64 v)    { return SwapOrder(v); }
   6.869     inline SInt64   BEToSystem(SInt64 v)    { return SwapOrder(v); }
   6.870     inline float    BEToSystem(float  v)    { return SwapOrder(v); }
   6.871     inline double   BEToSystem(double v)    { return SwapOrder(v); }
   6.872 
   6.873     // System (LE) to Little Endian
   6.874     inline UByte    SystemToLE(UByte  v)    { return v; }
   6.875     inline SByte    SystemToLE(SByte  v)    { return v; }
   6.876     inline UInt16   SystemToLE(UInt16 v)    { return v; }
   6.877     inline SInt16   SystemToLE(SInt16 v)    { return v; }
   6.878     inline UInt32   SystemToLE(UInt32 v)    { return v; }
   6.879     inline SInt32   SystemToLE(SInt32 v)    { return v; }
   6.880     inline UInt64   SystemToLE(UInt64 v)    { return v; }
   6.881     inline SInt64   SystemToLE(SInt64 v)    { return v; }
   6.882     inline float    SystemToLE(float  v)    { return v; }
   6.883     inline double   SystemToLE(double v)    { return v; }   
   6.884 
   6.885     // System (LE) to Big Endian
   6.886     inline UByte    SystemToBE(UByte  v)    { return SwapOrder(v); }
   6.887     inline SByte    SystemToBE(SByte  v)    { return SwapOrder(v); }
   6.888     inline UInt16   SystemToBE(UInt16 v)    { return SwapOrder(v); }
   6.889     inline SInt16   SystemToBE(SInt16 v)    { return SwapOrder(v); }
   6.890     inline UInt32   SystemToBE(UInt32 v)    { return SwapOrder(v); }
   6.891     inline SInt32   SystemToBE(SInt32 v)    { return SwapOrder(v); }
   6.892     inline UInt64   SystemToBE(UInt64 v)    { return SwapOrder(v); }
   6.893     inline SInt64   SystemToBE(SInt64 v)    { return SwapOrder(v); }
   6.894     inline float    SystemToBE(float  v)    { return SwapOrder(v); }
   6.895     inline double   SystemToBE(double v)    { return SwapOrder(v); }
   6.896 
   6.897 #elif (OVR_BYTE_ORDER == OVR_BIG_ENDIAN)
   6.898     // Little Endian to System (BE)
   6.899     inline UByte    LEToSystem(UByte  v)    { return SwapOrder(v); }
   6.900     inline SByte    LEToSystem(SByte  v)    { return SwapOrder(v); }
   6.901     inline UInt16   LEToSystem(UInt16 v)    { return SwapOrder(v); }
   6.902     inline SInt16   LEToSystem(SInt16 v)    { return SwapOrder(v); }
   6.903     inline UInt32   LEToSystem(UInt32 v)    { return SwapOrder(v); }
   6.904     inline SInt32   LEToSystem(SInt32 v)    { return SwapOrder(v); }
   6.905     inline UInt64   LEToSystem(UInt64 v)    { return SwapOrder(v); }
   6.906     inline SInt64   LEToSystem(SInt64 v)    { return SwapOrder(v); }
   6.907     inline float    LEToSystem(float  v)    { return SwapOrder(v); }
   6.908     inline double   LEToSystem(double v)    { return SwapOrder(v); }
   6.909 
   6.910     // Big Endian to System (BE)
   6.911     inline UByte    BEToSystem(UByte  v)    { return v; }
   6.912     inline SByte    BEToSystem(SByte  v)    { return v; }
   6.913     inline UInt16   BEToSystem(UInt16 v)    { return v; }
   6.914     inline SInt16   BEToSystem(SInt16 v)    { return v; }
   6.915     inline UInt32   BEToSystem(UInt32 v)    { return v; }
   6.916     inline SInt32   BEToSystem(SInt32 v)    { return v; }
   6.917     inline UInt64   BEToSystem(UInt64 v)    { return v; }
   6.918     inline SInt64   BEToSystem(SInt64 v)    { return v; }
   6.919     inline float    BEToSystem(float  v)    { return v; }
   6.920     inline double   BEToSystem(double v)    { return v; }
   6.921 
   6.922     // System (BE) to Little Endian
   6.923     inline UByte    SystemToLE(UByte  v)    { return SwapOrder(v); }
   6.924     inline SByte    SystemToLE(SByte  v)    { return SwapOrder(v); }
   6.925     inline UInt16   SystemToLE(UInt16 v)    { return SwapOrder(v); }
   6.926     inline SInt16   SystemToLE(SInt16 v)    { return SwapOrder(v); }
   6.927     inline UInt32   SystemToLE(UInt32 v)    { return SwapOrder(v); }
   6.928     inline SInt32   SystemToLE(SInt32 v)    { return SwapOrder(v); }
   6.929     inline UInt64   SystemToLE(UInt64 v)    { return SwapOrder(v); }
   6.930     inline SInt64   SystemToLE(SInt64 v)    { return SwapOrder(v); }
   6.931     inline float    SystemToLE(float  v)    { return SwapOrder(v); }
   6.932     inline double   SystemToLE(double v)    { return SwapOrder(v); }
   6.933 
   6.934     // System (BE) to Big Endian
   6.935     inline UByte    SystemToBE(UByte  v)    { return v; }
   6.936     inline SByte    SystemToBE(SByte  v)    { return v; }
   6.937     inline UInt16   SystemToBE(UInt16 v)    { return v; }
   6.938     inline SInt16   SystemToBE(SInt16 v)    { return v; }
   6.939     inline UInt32   SystemToBE(UInt32 v)    { return v; }
   6.940     inline SInt32   SystemToBE(SInt32 v)    { return v; }
   6.941     inline UInt64   SystemToBE(UInt64 v)    { return v; }
   6.942     inline SInt64   SystemToBE(SInt64 v)    { return v; }
   6.943     inline float    SystemToBE(float  v)    { return v; }
   6.944     inline double   SystemToBE(double v)    { return v; }
   6.945 
   6.946 #else
   6.947     #error "OVR_BYTE_ORDER must be defined to OVR_LITTLE_ENDIAN or OVR_BIG_ENDIAN"
   6.948 #endif
   6.949 
   6.950 } // namespace ByteUtil
   6.951 
   6.952 
   6.953 
   6.954 }} // OVR::Alg
   6.955 
   6.956 #endif
   6.957 \ No newline at end of file
     7.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     7.2 +++ b/libovr/Src/Kernel/OVR_Allocator.cpp	Sat Sep 14 16:14:59 2013 +0300
     7.3 @@ -0,0 +1,1 @@
     7.4 +/************************************************************************************
     7.5 
     7.6 Filename    :   OVR_Allocator.cpp
     7.7 Content     :   Installable memory allocator implementation
     7.8 Created     :   September 19, 2012
     7.9 Notes       : 
    7.10 
    7.11 Copyright   :   Copyright 2012 Oculus VR, Inc. All Rights reserved.
    7.12 
    7.13 Use of this software is subject to the terms of the Oculus license
    7.14 agreement provided at the time of installation or download, or which
    7.15 otherwise accompanies this software in either electronic or hard copy form.
    7.16 
    7.17 ************************************************************************************/
    7.18 
    7.19 #include "OVR_Allocator.h"
    7.20 #ifdef OVR_OS_MAC
    7.21  #include <stdlib.h>
    7.22 #else
    7.23  #include <malloc.h>
    7.24 #endif
    7.25 
    7.26 namespace OVR {
    7.27 
    7.28 //-----------------------------------------------------------------------------------
    7.29 // ***** Allocator
    7.30 
    7.31 Allocator* Allocator::pInstance = 0;
    7.32 
    7.33 // Default AlignedAlloc implementation will delegate to Alloc/Free after doing rounding.
    7.34 void* Allocator::AllocAligned(UPInt size, UPInt align)
    7.35 {
    7.36     OVR_ASSERT((align & (align-1)) == 0);
    7.37     align = (align > sizeof(UPInt)) ? align : sizeof(UPInt);
    7.38     UPInt p = (UPInt)Alloc(size+align);
    7.39     UPInt aligned = 0;
    7.40     if (p)
    7.41     {
    7.42         aligned = (UPInt(p) + align-1) & ~(align-1);
    7.43         if (aligned == p) 
    7.44             aligned += align;
    7.45         *(((UPInt*)aligned)-1) = aligned-p;
    7.46     }
    7.47     return (void*)aligned;
    7.48 }
    7.49 
    7.50 void Allocator::FreeAligned(void* p)
    7.51 {
    7.52     UPInt src = UPInt(p) - *(((UPInt*)p)-1);
    7.53     Free((void*)src);
    7.54 }
    7.55 
    7.56 
    7.57 //------------------------------------------------------------------------
    7.58 // ***** Default Allocator
    7.59 
    7.60 // This allocator is created and used if no other allocator is installed.
    7.61 // Default allocator delegates to system malloc.
    7.62 
    7.63 void* DefaultAllocator::Alloc(UPInt size)
    7.64 {
    7.65     return malloc(size);
    7.66 }
    7.67 void* DefaultAllocator::AllocDebug(UPInt size, const char* file, unsigned line)
    7.68 {
    7.69 #if defined(OVR_CC_MSVC) && defined(_CRTDBG_MAP_ALLOC)
    7.70     return _malloc_dbg(size, _NORMAL_BLOCK, file, line);
    7.71 #else
    7.72     OVR_UNUSED2(file, line);
    7.73     return malloc(size);
    7.74 #endif
    7.75 }
    7.76 
    7.77 void* DefaultAllocator::Realloc(void* p, UPInt newSize)
    7.78 {
    7.79     return realloc(p, newSize);
    7.80 }
    7.81 void DefaultAllocator::Free(void *p)
    7.82 {
    7.83     return free(p);
    7.84 }
    7.85 
    7.86 
    7.87 } // OVR
    7.88 \ No newline at end of file
     8.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     8.2 +++ b/libovr/Src/Kernel/OVR_Allocator.h	Sat Sep 14 16:14:59 2013 +0300
     8.3 @@ -0,0 +1,1 @@
     8.4 +/************************************************************************************
     8.5 
     8.6 PublicHeader:   OVR.h
     8.7 Filename    :   OVR_Allocator.h
     8.8 Content     :   Installable memory allocator
     8.9 Created     :   September 19, 2012
    8.10 Notes       : 
    8.11 
    8.12 Copyright   :   Copyright 2012 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 
    8.20 #ifndef OVR_Allocator_h
    8.21 #define OVR_Allocator_h
    8.22 
    8.23 #include "OVR_Types.h"
    8.24 
    8.25 //-----------------------------------------------------------------------------------
    8.26 
    8.27 // ***** Disable template-unfriendly MS VC++ warnings
    8.28 #if defined(OVR_CC_MSVC)
    8.29 // Pragma to prevent long name warnings in in VC++
    8.30 #pragma warning(disable : 4503)
    8.31 #pragma warning(disable : 4786)
    8.32 // In MSVC 7.1, warning about placement new POD default initializer
    8.33 #pragma warning(disable : 4345)
    8.34 #endif
    8.35 
    8.36 // Un-define new so that placement constructors work
    8.37 #undef new
    8.38 
    8.39 
    8.40 //-----------------------------------------------------------------------------------
    8.41 // ***** Placement new overrides
    8.42 
    8.43 // Calls constructor on own memory created with "new(ptr) type"
    8.44 #ifndef __PLACEMENT_NEW_INLINE
    8.45 #define __PLACEMENT_NEW_INLINE
    8.46 
    8.47 #   if defined(OVR_CC_MWERKS) || defined(OVR_CC_BORLAND) || defined(OVR_CC_GNU)
    8.48 #      include <new>
    8.49 #   else
    8.50     // Useful on MSVC
    8.51     OVR_FORCE_INLINE void* operator new     (OVR::UPInt n, void *ptr) { OVR_UNUSED(n); return ptr; }
    8.52     OVR_FORCE_INLINE void  operator delete  (void *, void *)     { }
    8.53 #   endif
    8.54 
    8.55 #endif // __PLACEMENT_NEW_INLINE
    8.56 
    8.57 
    8.58 
    8.59 //------------------------------------------------------------------------
    8.60 // ***** Macros to redefine class new/delete operators
    8.61 
    8.62 // Types specifically declared to allow disambiguation of address in
    8.63 // class member operator new.
    8.64 
    8.65 #define OVR_MEMORY_REDEFINE_NEW_IMPL(class_name, check_delete)                          \
    8.66     void*   operator new(UPInt sz)                                                      \
    8.67     { void *p = OVR_ALLOC_DEBUG(sz, __FILE__, __LINE__); return p; }                                              \
    8.68     void*   operator new(UPInt sz, const char* file, int line)                          \
    8.69     { void* p = OVR_ALLOC_DEBUG(sz, file, line); OVR_UNUSED2(file, line); return p; }   \
    8.70     void    operator delete(void *p)                                                    \
    8.71     { check_delete(class_name, p); OVR_FREE(p); }                                       \
    8.72     void    operator delete(void *p, const char*, int)                                  \
    8.73     { check_delete(class_name, p); OVR_FREE(p); }                          
    8.74 
    8.75 #define OVR_MEMORY_DEFINE_PLACEMENT_NEW                                                 \
    8.76     void*   operator new        (UPInt n, void *ptr)    { OVR_UNUSED(n); return ptr; }  \
    8.77     void    operator delete     (void *ptr, void *ptr2) { OVR_UNUSED2(ptr,ptr2); }
    8.78 
    8.79 
    8.80 #define OVR_MEMORY_CHECK_DELETE_NONE(class_name, p)
    8.81 
    8.82 // Redefined all delete/new operators in a class without custom memory initialization
    8.83 #define OVR_MEMORY_REDEFINE_NEW(class_name) \
    8.84     OVR_MEMORY_REDEFINE_NEW_IMPL(class_name, OVR_MEMORY_CHECK_DELETE_NONE)
    8.85 
    8.86 
    8.87 namespace OVR {
    8.88 
    8.89 //-----------------------------------------------------------------------------------
    8.90 // ***** Construct / Destruct
    8.91 
    8.92 // Construct/Destruct functions are useful when new is redefined, as they can
    8.93 // be called instead of placement new constructors.
    8.94 
    8.95 
    8.96 template <class T>
    8.97 OVR_FORCE_INLINE T*  Construct(void *p)
    8.98 {
    8.99     return ::new(p) T;
   8.100 }
   8.101 
   8.102 template <class T>
   8.103 OVR_FORCE_INLINE T*  Construct(void *p, const T& source)
   8.104 {
   8.105     return ::new(p) T(source);
   8.106 }
   8.107 
   8.108 // Same as above, but allows for a different type of constructor.
   8.109 template <class T, class S>
   8.110 OVR_FORCE_INLINE T*  ConstructAlt(void *p, const S& source)
   8.111 {
   8.112     return ::new(p) T(source);
   8.113 }
   8.114 
   8.115 template <class T, class S1, class S2>
   8.116 OVR_FORCE_INLINE T*  ConstructAlt(void *p, const S1& src1, const S2& src2)
   8.117 {
   8.118     return ::new(p) T(src1, src2);
   8.119 }
   8.120 
   8.121 template <class T>
   8.122 OVR_FORCE_INLINE void ConstructArray(void *p, UPInt count)
   8.123 {
   8.124     UByte *pdata = (UByte*)p;
   8.125     for (UPInt i=0; i< count; ++i, pdata += sizeof(T))
   8.126     {
   8.127         Construct<T>(pdata);
   8.128     }
   8.129 }
   8.130 
   8.131 template <class T>
   8.132 OVR_FORCE_INLINE void ConstructArray(void *p, UPInt count, const T& source)
   8.133 {
   8.134     UByte *pdata = (UByte*)p;
   8.135     for (UPInt i=0; i< count; ++i, pdata += sizeof(T))
   8.136     {
   8.137         Construct<T>(pdata, source);
   8.138     }
   8.139 }
   8.140 
   8.141 template <class T>
   8.142 OVR_FORCE_INLINE void Destruct(T *pobj)
   8.143 {
   8.144     pobj->~T();
   8.145     OVR_UNUSED1(pobj); // Fix incorrect 'unused variable' MSVC warning.
   8.146 }
   8.147 
   8.148 template <class T>
   8.149 OVR_FORCE_INLINE void DestructArray(T *pobj, UPInt count)
   8.150 {   
   8.151     for (UPInt i=0; i<count; ++i, ++pobj)
   8.152         pobj->~T();
   8.153 }
   8.154 
   8.155 
   8.156 //-----------------------------------------------------------------------------------
   8.157 // ***** Allocator
   8.158 
   8.159 // Allocator defines a memory allocation interface that developers can override
   8.160 // to to provide memory for OVR; an instance of this class is typically created on
   8.161 // application startup and passed into System or OVR::System constructor.
   8.162 // 
   8.163 //
   8.164 // Users implementing this interface must provide three functions: Alloc, Free,
   8.165 // and Realloc. Implementations of these functions must honor the requested alignment.
   8.166 // Although arbitrary alignment requests are possible, requested alignment will
   8.167 // typically be small, such as 16 bytes or less.
   8.168 
   8.169 class Allocator
   8.170 {
   8.171     friend class System;
   8.172 public:
   8.173 
   8.174     // *** Standard Alignment Alloc/Free
   8.175 
   8.176     // Allocate memory of specified size with default alignment.
   8.177     // Alloc of size==0 will allocate a tiny block & return a valid pointer;
   8.178     // this makes it suitable for new operator.
   8.179     virtual void*   Alloc(UPInt size) = 0;
   8.180     // Same as Alloc, but provides an option of passing debug data.
   8.181     virtual void*   AllocDebug(UPInt size, const char* file, unsigned line)
   8.182     { OVR_UNUSED2(file, line); return Alloc(size); }
   8.183 
   8.184     // Reallocate memory block to a new size, copying data if necessary. Returns the pointer to
   8.185     // new memory block, which may be the same as original pointer. Will return 0 if reallocation
   8.186     // failed, in which case previous memory is still valid.
   8.187     // Realloc to decrease size will never fail.
   8.188     // Realloc of pointer == 0 is equivalent to Alloc
   8.189     // Realloc to size == 0, shrinks to the minimal size, pointer remains valid and requires Free().
   8.190     virtual void*   Realloc(void* p, UPInt newSize) = 0;
   8.191 
   8.192     // Frees memory allocated by Alloc/Realloc.
   8.193     // Free of null pointer is valid and will do nothing.
   8.194     virtual void    Free(void *p) = 0;
   8.195 
   8.196 
   8.197     // *** Standard Alignment Alloc/Free
   8.198 
   8.199     // Allocate memory of specified alignment.
   8.200     // Memory allocated with AllocAligned MUST be freed with FreeAligned.
   8.201     // Default implementation will delegate to Alloc/Free after doing rounding.
   8.202     virtual void*   AllocAligned(UPInt size, UPInt align);    
   8.203     // Frees memory allocated with AllocAligned.
   8.204     virtual void    FreeAligned(void* p);
   8.205     
   8.206     // Returns the pointer to the current globally installed Allocator instance.
   8.207     // This pointer is used for most of the memory allocations.
   8.208     static Allocator* GetInstance() { return pInstance; }
   8.209 
   8.210 
   8.211 protected:
   8.212     // onSystemShutdown is called on the allocator during System::Shutdown.
   8.213     // At this point, all allocations should've been freed.
   8.214     virtual void    onSystemShutdown() { }
   8.215 
   8.216 public:
   8.217     static  void    setInstance(Allocator* palloc)    
   8.218     {
   8.219         OVR_ASSERT((pInstance == 0) || (palloc == 0));
   8.220         pInstance = palloc;
   8.221     }
   8.222 
   8.223 private:
   8.224 
   8.225     static Allocator* pInstance;
   8.226 };
   8.227 
   8.228 
   8.229 
   8.230 //------------------------------------------------------------------------
   8.231 // ***** Allocator_SingletonSupport
   8.232 
   8.233 // Allocator_SingletonSupport is a Allocator wrapper class that implements
   8.234 // the InitSystemSingleton static function, used to create a global singleton
   8.235 // used for the OVR::System default argument initialization.
   8.236 //
   8.237 // End users implementing custom Allocator interface don't need to make use of this base
   8.238 // class; they can just create an instance of their own class on stack and pass it to System.
   8.239 
   8.240 template<class D>
   8.241 class Allocator_SingletonSupport : public Allocator
   8.242 {
   8.243     struct AllocContainer
   8.244     {        
   8.245         UPInt Data[(sizeof(D) + sizeof(UPInt)-1) / sizeof(UPInt)];
   8.246         bool  Initialized;
   8.247         AllocContainer() : Initialized(0) { }
   8.248     };
   8.249 
   8.250     AllocContainer* pContainer;
   8.251 
   8.252 public:
   8.253     Allocator_SingletonSupport() : pContainer(0) { }
   8.254 
   8.255     // Creates a singleton instance of this Allocator class used
   8.256     // on OVR_DEFAULT_ALLOCATOR during System initialization.
   8.257     static  D*  InitSystemSingleton()
   8.258     {
   8.259         static AllocContainer Container;
   8.260         OVR_ASSERT(Container.Initialized == false);
   8.261 
   8.262         Allocator_SingletonSupport<D> *presult = Construct<D>((void*)Container.Data);
   8.263         presult->pContainer   = &Container;
   8.264         Container.Initialized = true;
   8.265         return (D*)presult;
   8.266     }
   8.267 
   8.268 protected:
   8.269     virtual void onSystemShutdown()
   8.270     {
   8.271         Allocator::onSystemShutdown();
   8.272         if (pContainer)
   8.273         {
   8.274             pContainer->Initialized = false;
   8.275             Destruct((D*)this);
   8.276             pContainer = 0;
   8.277         }
   8.278     }
   8.279 };
   8.280 
   8.281 //------------------------------------------------------------------------
   8.282 // ***** Default Allocator
   8.283 
   8.284 // This allocator is created and used if no other allocator is installed.
   8.285 // Default allocator delegates to system malloc.
   8.286 
   8.287 class DefaultAllocator : public Allocator_SingletonSupport<DefaultAllocator>
   8.288 {
   8.289 public:
   8.290     virtual void*   Alloc(UPInt size);
   8.291     virtual void*   AllocDebug(UPInt size, const char* file, unsigned line);
   8.292     virtual void*   Realloc(void* p, UPInt newSize);
   8.293     virtual void    Free(void *p);
   8.294 };
   8.295 
   8.296 
   8.297 //------------------------------------------------------------------------
   8.298 // ***** Memory Allocation Macros
   8.299 
   8.300 // These macros should be used for global allocation. In the future, these
   8.301 // macros will allows allocation to be extended with debug file/line information
   8.302 // if necessary.
   8.303 
   8.304 #define OVR_REALLOC(p,s)        OVR::Allocator::GetInstance()->Realloc((p),(s))
   8.305 #define OVR_FREE(p)             OVR::Allocator::GetInstance()->Free((p))
   8.306 #define OVR_ALLOC_ALIGNED(s,a)  OVR::Allocator::GetInstance()->AllocAligned((s),(a))
   8.307 #define OVR_FREE_ALIGNED(p)     OVR::Allocator::GetInstance()->FreeAligned((p))
   8.308 
   8.309 #ifdef OVR_BUILD_DEBUG
   8.310 #define OVR_ALLOC(s)            OVR::Allocator::GetInstance()->AllocDebug((s), __FILE__, __LINE__)
   8.311 #define OVR_ALLOC_DEBUG(s,f,l)  OVR::Allocator::GetInstance()->AllocDebug((s), f, l)
   8.312 #else
   8.313 #define OVR_ALLOC(s)            OVR::Allocator::GetInstance()->Alloc((s))
   8.314 #define OVR_ALLOC_DEBUG(s,f,l)  OVR::Allocator::GetInstance()->Alloc((s))
   8.315 #endif
   8.316 
   8.317 //------------------------------------------------------------------------
   8.318 
   8.319 // Base class that overrides the new and delete operators.
   8.320 // Deriving from this class, even as a multiple base, incurs no space overhead.
   8.321 class NewOverrideBase
   8.322 {
   8.323 public:
   8.324 
   8.325     // Redefine all new & delete operators.
   8.326     OVR_MEMORY_REDEFINE_NEW(NewOverrideBase)
   8.327 };
   8.328 
   8.329 
   8.330 } // OVR
   8.331 
   8.332 
   8.333 // Redefine operator 'new' if necessary.
   8.334 #if defined(OVR_DEFINE_NEW)
   8.335 #define new OVR_DEFINE_NEW
   8.336 #endif
   8.337 
   8.338 
   8.339 #endif // OVR_Memory
   8.340 \ No newline at end of file
     9.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     9.2 +++ b/libovr/Src/Kernel/OVR_Array.h	Sat Sep 14 16:14:59 2013 +0300
     9.3 @@ -0,0 +1,1 @@
     9.4 +/************************************************************************************
     9.5 
     9.6 PublicHeader:   OVR.h
     9.7 Filename    :   OVR_Array.h
     9.8 Content     :   Template implementation for Array
     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_Array_h
    9.21 #define OVR_Array_h
    9.22 
    9.23 #include "OVR_ContainerAllocator.h"
    9.24 
    9.25 namespace OVR {
    9.26 
    9.27 //-----------------------------------------------------------------------------------
    9.28 // ***** ArrayDefaultPolicy
    9.29 //
    9.30 // Default resize behavior. No minimal capacity, Granularity=4, 
    9.31 // Shrinking as needed. ArrayConstPolicy actually is the same as 
    9.32 // ArrayDefaultPolicy, but parametrized with constants. 
    9.33 // This struct is used only in order to reduce the template "matroska".
    9.34 struct ArrayDefaultPolicy
    9.35 {
    9.36     ArrayDefaultPolicy() : Capacity(0) {}
    9.37     ArrayDefaultPolicy(const ArrayDefaultPolicy&) : Capacity(0) {}
    9.38 
    9.39     UPInt GetMinCapacity() const { return 0; }
    9.40     UPInt GetGranularity() const { return 4; }
    9.41     bool  NeverShrinking() const { return 0; }
    9.42 
    9.43     UPInt GetCapacity()    const      { return Capacity; }
    9.44     void  SetCapacity(UPInt capacity) { Capacity = capacity; }
    9.45 private:
    9.46     UPInt Capacity;
    9.47 };
    9.48 
    9.49 
    9.50 //-----------------------------------------------------------------------------------
    9.51 // ***** ArrayConstPolicy
    9.52 //
    9.53 // Statically parametrized resizing behavior:
    9.54 // MinCapacity, Granularity, and Shrinking flag.
    9.55 template<int MinCapacity=0, int Granularity=4, bool NeverShrink=false>
    9.56 struct ArrayConstPolicy
    9.57 {
    9.58     typedef ArrayConstPolicy<MinCapacity, Granularity, NeverShrink> SelfType;
    9.59 
    9.60     ArrayConstPolicy() : Capacity(0) {}
    9.61     ArrayConstPolicy(const SelfType&) : Capacity(0) {}
    9.62 
    9.63     UPInt GetMinCapacity() const { return MinCapacity; }
    9.64     UPInt GetGranularity() const { return Granularity; }
    9.65     bool  NeverShrinking() const { return NeverShrink; }
    9.66 
    9.67     UPInt GetCapacity()    const      { return Capacity; }
    9.68     void  SetCapacity(UPInt capacity) { Capacity = capacity; }
    9.69 private:
    9.70     UPInt Capacity;
    9.71 };
    9.72 
    9.73 //-----------------------------------------------------------------------------------
    9.74 // ***** ArrayDataBase
    9.75 //
    9.76 // Basic operations with array data: Reserve, Resize, Free, ArrayPolicy.
    9.77 // For internal use only: ArrayData,ArrayDataCC and others.
    9.78 template<class T, class Allocator, class SizePolicy>
    9.79 struct ArrayDataBase
    9.80 {
    9.81     typedef T                                           ValueType;
    9.82     typedef Allocator                                   AllocatorType;
    9.83     typedef SizePolicy                                  SizePolicyType;
    9.84     typedef ArrayDataBase<T, Allocator, SizePolicy>     SelfType;
    9.85 
    9.86     ArrayDataBase()
    9.87         : Data(0), Size(0), Policy() {}
    9.88 
    9.89     ArrayDataBase(const SizePolicy& p)
    9.90         : Data(0), Size(0), Policy(p) {}
    9.91 
    9.92     ~ArrayDataBase() 
    9.93     {
    9.94         Allocator::DestructArray(Data, Size);
    9.95         Allocator::Free(Data);
    9.96     }
    9.97 
    9.98     UPInt GetCapacity() const 
    9.99     { 
   9.100         return Policy.GetCapacity(); 
   9.101     }
   9.102 
   9.103     void ClearAndRelease()
   9.104     {
   9.105         Allocator::DestructArray(Data, Size);
   9.106         Allocator::Free(Data);
   9.107         Data = 0;
   9.108         Size = 0;
   9.109         Policy.SetCapacity(0);
   9.110     }
   9.111 
   9.112     void Reserve(UPInt newCapacity)
   9.113     {
   9.114         if (Policy.NeverShrinking() && newCapacity < GetCapacity())
   9.115             return;
   9.116 
   9.117         if (newCapacity < Policy.GetMinCapacity())
   9.118             newCapacity = Policy.GetMinCapacity();
   9.119 
   9.120         // Resize the buffer.
   9.121         if (newCapacity == 0)
   9.122         {
   9.123             if (Data)
   9.124             {
   9.125                 Allocator::Free(Data);
   9.126                 Data = 0;
   9.127             }
   9.128             Policy.SetCapacity(0);
   9.129         }
   9.130         else
   9.131         {
   9.132             UPInt gran = Policy.GetGranularity();
   9.133             newCapacity = (newCapacity + gran - 1) / gran * gran;
   9.134             if (Data)
   9.135             {
   9.136                 if (Allocator::IsMovable())
   9.137                 {
   9.138                     Data = (T*)Allocator::Realloc(Data, sizeof(T) * newCapacity);
   9.139                 }
   9.140                 else
   9.141                 {
   9.142                     T* newData = (T*)Allocator::Alloc(sizeof(T) * newCapacity);
   9.143                     UPInt i, s;
   9.144                     s = (Size < newCapacity) ? Size : newCapacity;
   9.145                     for (i = 0; i < s; ++i)
   9.146                     {
   9.147                         Allocator::Construct(&newData[i], Data[i]);
   9.148                         Allocator::Destruct(&Data[i]);
   9.149                     }
   9.150                     for (i = s; i < Size; ++i)
   9.151                     {
   9.152                         Allocator::Destruct(&Data[i]);
   9.153                     }
   9.154                     Allocator::Free(Data);
   9.155                     Data = newData;
   9.156                 }
   9.157             }
   9.158             else
   9.159             {
   9.160                 Data = (T*)Allocator::Alloc(sizeof(T) * newCapacity);
   9.161                 //memset(Buffer, 0, (sizeof(ValueType) * newSize)); // Do we need this?
   9.162             }
   9.163             Policy.SetCapacity(newCapacity);
   9.164             // OVR_ASSERT(Data); // need to throw (or something) on alloc failure!
   9.165         }
   9.166     }
   9.167 
   9.168     // This version of Resize DOES NOT construct the elements.
   9.169     // It's done to optimize PushBack, which uses a copy constructor 
   9.170     // instead of the default constructor and assignment
   9.171     void ResizeNoConstruct(UPInt newSize)
   9.172     {
   9.173         UPInt oldSize = Size;
   9.174 
   9.175         if (newSize < oldSize)
   9.176         {
   9.177             Allocator::DestructArray(Data + newSize, oldSize - newSize);
   9.178             if (newSize < (Policy.GetCapacity() >> 1))
   9.179             {
   9.180                 Reserve(newSize);
   9.181             }
   9.182         }
   9.183         else if(newSize >= Policy.GetCapacity())
   9.184         {
   9.185             Reserve(newSize + (newSize >> 2));
   9.186         }
   9.187         //! IMPORTANT to modify Size only after Reserve completes, because garbage collectable
   9.188         // array may use this array and may traverse it during Reserve (in the case, if 
   9.189         // collection occurs because of heap limit exceeded).
   9.190         Size = newSize;
   9.191     }
   9.192 
   9.193     ValueType*  Data;
   9.194     UPInt       Size;
   9.195     SizePolicy  Policy;
   9.196 };
   9.197 
   9.198 
   9.199 
   9.200 //-----------------------------------------------------------------------------------
   9.201 // ***** ArrayData
   9.202 //
   9.203 // General purpose array data.
   9.204 // For internal use only in Array, ArrayLH, ArrayPOD and so on.
   9.205 template<class T, class Allocator, class SizePolicy>
   9.206 struct ArrayData : ArrayDataBase<T, Allocator, SizePolicy>
   9.207 {
   9.208     typedef T ValueType;
   9.209     typedef Allocator                                   AllocatorType;
   9.210     typedef SizePolicy                                  SizePolicyType;
   9.211     typedef ArrayDataBase<T, Allocator, SizePolicy>     BaseType;
   9.212     typedef ArrayData    <T, Allocator, SizePolicy>     SelfType;
   9.213 
   9.214     ArrayData()
   9.215         : BaseType() { }
   9.216 
   9.217     ArrayData(int size)
   9.218         : BaseType() { Resize(size); }
   9.219 
   9.220     ArrayData(const SelfType& a)
   9.221         : BaseType(a.Policy) { Append(a.Data, a.Size); }
   9.222 
   9.223 
   9.224     void Resize(UPInt newSize)
   9.225     {
   9.226         UPInt oldSize = this->Size;
   9.227         BaseType::ResizeNoConstruct(newSize);
   9.228         if(newSize > oldSize)
   9.229             Allocator::ConstructArray(this->Data + oldSize, newSize - oldSize);
   9.230     }
   9.231 
   9.232     void PushBack(const ValueType& val)
   9.233     {
   9.234         BaseType::ResizeNoConstruct(this->Size + 1);
   9.235         Allocator::Construct(this->Data + this->Size - 1, val);
   9.236     }
   9.237 
   9.238     template<class S>
   9.239     void PushBackAlt(const S& val)
   9.240     {
   9.241         BaseType::ResizeNoConstruct(this->Size + 1);
   9.242         Allocator::ConstructAlt(this->Data + this->Size - 1, val);
   9.243     }
   9.244 
   9.245     // Append the given data to the array.
   9.246     void Append(const ValueType other[], UPInt count)
   9.247     {
   9.248         if (count)
   9.249         {
   9.250             UPInt oldSize = this->Size;
   9.251             BaseType::ResizeNoConstruct(this->Size + count);
   9.252             Allocator::ConstructArray(this->Data + oldSize, count, other);
   9.253         }
   9.254     }
   9.255 };
   9.256 
   9.257 
   9.258 
   9.259 //-----------------------------------------------------------------------------------
   9.260 // ***** ArrayDataCC
   9.261 //
   9.262 // A modification of ArrayData that always copy-constructs new elements
   9.263 // using a specified DefaultValue. For internal use only in ArrayCC.
   9.264 template<class T, class Allocator, class SizePolicy>
   9.265 struct ArrayDataCC : ArrayDataBase<T, Allocator, SizePolicy>
   9.266 {
   9.267     typedef T                                           ValueType;
   9.268     typedef Allocator                                   AllocatorType;
   9.269     typedef SizePolicy                                  SizePolicyType;
   9.270     typedef ArrayDataBase<T, Allocator, SizePolicy>     BaseType;
   9.271     typedef ArrayDataCC  <T, Allocator, SizePolicy>     SelfType;
   9.272 
   9.273     ArrayDataCC(const ValueType& defval)
   9.274         : BaseType(), DefaultValue(defval) { }
   9.275 
   9.276     ArrayDataCC(const ValueType& defval, int size)
   9.277         : BaseType(), DefaultValue(defval) { Resize(size); }
   9.278 
   9.279     ArrayDataCC(const SelfType& a)
   9.280         : BaseType(a.Policy), DefaultValue(a.DefaultValue) { Append(a.Data, a.Size); }
   9.281 
   9.282 
   9.283     void Resize(UPInt newSize)
   9.284     {
   9.285         UPInt oldSize = this->Size;
   9.286         BaseType::ResizeNoConstruct(newSize);
   9.287         if(newSize > oldSize)
   9.288             Allocator::ConstructArray(this->Data + oldSize, newSize - oldSize, DefaultValue);
   9.289     }
   9.290 
   9.291     void PushBack(const ValueType& val)
   9.292     {
   9.293         BaseType::ResizeNoConstruct(this->Size + 1);
   9.294         Allocator::Construct(this->Data + this->Size - 1, val);
   9.295     }
   9.296 
   9.297     template<class S>
   9.298     void PushBackAlt(const S& val)
   9.299     {
   9.300         BaseType::ResizeNoConstruct(this->Size + 1);
   9.301         Allocator::ConstructAlt(this->Data + this->Size - 1, val);
   9.302     }
   9.303 
   9.304     // Append the given data to the array.
   9.305     void Append(const ValueType other[], UPInt count)
   9.306     {
   9.307         if (count)
   9.308         {
   9.309             UPInt oldSize = this->Size;
   9.310             BaseType::ResizeNoConstruct(this->Size + count);
   9.311             Allocator::ConstructArray(this->Data + oldSize, count, other);
   9.312         }
   9.313     }
   9.314 
   9.315     ValueType   DefaultValue;
   9.316 };
   9.317 
   9.318 
   9.319 
   9.320 
   9.321 
   9.322 //-----------------------------------------------------------------------------------
   9.323 // ***** ArrayBase
   9.324 //
   9.325 // Resizable array. The behavior can be POD (suffix _POD) and 
   9.326 // Movable (no suffix) depending on the allocator policy.
   9.327 // In case of _POD the constructors and destructors are not called.
   9.328 // 
   9.329 // Arrays can't handle non-movable objects! Don't put anything in here 
   9.330 // that can't be moved around by bitwise copy. 
   9.331 // 
   9.332 // The addresses of elements are not persistent! Don't keep the address 
   9.333 // of an element; the array contents will move around as it gets resized.
   9.334 template<class ArrayData>
   9.335 class ArrayBase
   9.336 {
   9.337 public:
   9.338     typedef typename ArrayData::ValueType       ValueType;
   9.339     typedef typename ArrayData::AllocatorType   AllocatorType;
   9.340     typedef typename ArrayData::SizePolicyType  SizePolicyType;
   9.341     typedef ArrayBase<ArrayData>                SelfType;
   9.342 
   9.343 
   9.344 #undef new
   9.345     OVR_MEMORY_REDEFINE_NEW(ArrayBase)
   9.346 // Redefine operator 'new' if necessary.
   9.347 #if defined(OVR_DEFINE_NEW)
   9.348 #define new OVR_DEFINE_NEW
   9.349 #endif
   9.350 
   9.351 
   9.352     ArrayBase()
   9.353         : Data() {}
   9.354     ArrayBase(int size)
   9.355         : Data(size) {}
   9.356     ArrayBase(const SelfType& a)
   9.357         : Data(a.Data) {}
   9.358 
   9.359     ArrayBase(const ValueType& defval)
   9.360         : Data(defval) {}
   9.361     ArrayBase(const ValueType& defval, int size)
   9.362         : Data(defval, size) {}
   9.363   
   9.364     SizePolicyType* GetSizePolicy() const                  { return Data.Policy; }
   9.365     void            SetSizePolicy(const SizePolicyType& p) { Data.Policy = p; }
   9.366 
   9.367     bool    NeverShrinking()const       { return Data.Policy.NeverShrinking(); }
   9.368     UPInt   GetSize()       const       { return Data.Size;  }
   9.369     bool    IsEmpty()       const       { return Data.Size == 0; }
   9.370     UPInt   GetCapacity()   const       { return Data.GetCapacity(); }
   9.371     UPInt   GetNumBytes()   const       { return Data.GetCapacity() * sizeof(ValueType); }
   9.372 
   9.373     void    ClearAndRelease()           { Data.ClearAndRelease(); }
   9.374     void    Clear()                     { Data.Resize(0); }
   9.375     void    Resize(UPInt newSize)       { Data.Resize(newSize); }
   9.376 
   9.377     // Reserve can only increase the capacity
   9.378     void    Reserve(UPInt newCapacity)  
   9.379     { 
   9.380         if (newCapacity > Data.GetCapacity())
   9.381             Data.Reserve(newCapacity); 
   9.382     }
   9.383 
   9.384     // Basic access.
   9.385     ValueType& At(UPInt index)
   9.386     {
   9.387         OVR_ASSERT(index < Data.Size);
   9.388         return Data.Data[index]; 
   9.389     }
   9.390     const ValueType& At(UPInt index) const
   9.391     {
   9.392         OVR_ASSERT(index < Data.Size);
   9.393         return Data.Data[index]; 
   9.394     }
   9.395 
   9.396     ValueType ValueAt(UPInt index) const
   9.397     {
   9.398         OVR_ASSERT(index < Data.Size);
   9.399         return Data.Data[index]; 
   9.400     }
   9.401 
   9.402     // Basic access.
   9.403     ValueType& operator [] (UPInt index)
   9.404     {
   9.405         OVR_ASSERT(index < Data.Size);
   9.406         return Data.Data[index]; 
   9.407     }
   9.408     const ValueType& operator [] (UPInt index) const
   9.409     {
   9.410         OVR_ASSERT(index < Data.Size);
   9.411         return Data.Data[index]; 
   9.412     }
   9.413 
   9.414     // Raw pointer to the data. Use with caution!
   9.415     const ValueType* GetDataPtr() const { return Data.Data; }
   9.416           ValueType* GetDataPtr()       { return Data.Data; }
   9.417 
   9.418     // Insert the given element at the end of the array.
   9.419     void    PushBack(const ValueType& val)
   9.420     {
   9.421         // DO NOT pass elements of your own vector into
   9.422         // push_back()!  Since we're using references,
   9.423         // resize() may munge the element storage!
   9.424         // OVR_ASSERT(&val < &Buffer[0] || &val > &Buffer[BufferSize]);
   9.425         Data.PushBack(val);
   9.426     }
   9.427 
   9.428     template<class S>
   9.429     void PushBackAlt(const S& val)
   9.430     {
   9.431         Data.PushBackAlt(val);
   9.432     }
   9.433 
   9.434     // Remove the last element.
   9.435     void    PopBack(UPInt count = 1)
   9.436     {
   9.437         OVR_ASSERT(Data.Size >= count);
   9.438         Data.Resize(Data.Size - count);
   9.439     }
   9.440 
   9.441     ValueType& PushDefault()
   9.442     {
   9.443         Data.PushBack(ValueType());
   9.444         return Back();
   9.445     }
   9.446 
   9.447     ValueType Pop()
   9.448     {
   9.449         ValueType t = Back();
   9.450         PopBack();
   9.451         return t;
   9.452     }
   9.453 
   9.454 
   9.455     // Access the first element.
   9.456     ValueType&          Front()         { return At(0); }
   9.457     const ValueType&    Front() const   { return At(0); }
   9.458 
   9.459     // Access the last element.
   9.460     ValueType&          Back()          { return At(Data.Size - 1); }
   9.461     const ValueType&    Back() const    { return At(Data.Size - 1); }
   9.462 
   9.463     // Array copy.  Copies the contents of a into this array.
   9.464     const SelfType& operator = (const SelfType& a)   
   9.465     {
   9.466         Resize(a.GetSize());
   9.467         for (UPInt i = 0; i < Data.Size; i++) {
   9.468             *(Data.Data + i) = a[i];
   9.469         }
   9.470         return *this;
   9.471     }
   9.472 
   9.473     // Removing multiple elements from the array.
   9.474     void    RemoveMultipleAt(UPInt index, UPInt num)
   9.475     {
   9.476         OVR_ASSERT(index + num <= Data.Size);
   9.477         if (Data.Size == num)
   9.478         {
   9.479             Clear();
   9.480         }
   9.481         else
   9.482         {
   9.483             AllocatorType::DestructArray(Data.Data + index, num);
   9.484             AllocatorType::CopyArrayForward(
   9.485                 Data.Data + index, 
   9.486                 Data.Data + index + num,
   9.487                 Data.Size - num - index);
   9.488             Data.Size -= num;
   9.489         }
   9.490     }
   9.491 
   9.492     // Removing an element from the array is an expensive operation!
   9.493     // It compacts only after removing the last element.
   9.494     void    RemoveAt(UPInt index)
   9.495     {
   9.496         OVR_ASSERT(index < Data.Size);
   9.497         if (Data.Size == 1)
   9.498         {
   9.499             Clear();
   9.500         }
   9.501         else
   9.502         {
   9.503             AllocatorType::Destruct(Data.Data + index);
   9.504             AllocatorType::CopyArrayForward(
   9.505                 Data.Data + index, 
   9.506                 Data.Data + index + 1,
   9.507                 Data.Size - 1 - index);
   9.508             --Data.Size;
   9.509         }
   9.510     }
   9.511 
   9.512     // Insert the given object at the given index shifting all the elements up.
   9.513     void    InsertAt(UPInt index, const ValueType& val = ValueType())
   9.514     {
   9.515         OVR_ASSERT(index <= Data.Size);
   9.516 
   9.517         Data.Resize(Data.Size + 1);
   9.518         if (index < Data.Size - 1)
   9.519         {
   9.520             AllocatorType::CopyArrayBackward(
   9.521                 Data.Data + index + 1, 
   9.522                 Data.Data + index, 
   9.523                 Data.Size - 1 - index);
   9.524         }
   9.525         AllocatorType::Construct(Data.Data + index, val);
   9.526     }
   9.527 
   9.528     // Insert the given object at the given index shifting all the elements up.
   9.529     void    InsertMultipleAt(UPInt index, UPInt num, const ValueType& val = ValueType())
   9.530     {
   9.531         OVR_ASSERT(index <= Data.Size);
   9.532 
   9.533         Data.Resize(Data.Size + num);
   9.534         if (index < Data.Size - num)
   9.535         {
   9.536             AllocatorType::CopyArrayBackward(
   9.537                 Data.Data + index + num,
   9.538                 Data.Data + index,
   9.539                 Data.Size - num - index);
   9.540         }
   9.541         for (UPInt i = 0; i < num; ++i)
   9.542             AllocatorType::Construct(Data.Data + index + i, val);
   9.543     }
   9.544 
   9.545     // Append the given data to the array.
   9.546     void    Append(const SelfType& other)
   9.547     {
   9.548         Append(other.Data.Data, other.GetSize());
   9.549     }
   9.550 
   9.551     // Append the given data to the array.
   9.552     void    Append(const ValueType other[], UPInt count)
   9.553     {
   9.554         Data.Append(other, count);
   9.555     }
   9.556 
   9.557     class Iterator
   9.558     {
   9.559         SelfType*       pArray;
   9.560         SPInt           CurIndex;
   9.561 
   9.562     public:
   9.563         Iterator() : pArray(0), CurIndex(-1) {}
   9.564         Iterator(SelfType* parr, SPInt idx = 0) : pArray(parr), CurIndex(idx) {}
   9.565 
   9.566         bool operator==(const Iterator& it) const { return pArray == it.pArray && CurIndex == it.CurIndex; }
   9.567         bool operator!=(const Iterator& it) const { return pArray != it.pArray || CurIndex != it.CurIndex; }
   9.568 
   9.569         Iterator& operator++()
   9.570         {
   9.571             if (pArray)
   9.572             {
   9.573                 if (CurIndex < (SPInt)pArray->GetSize())
   9.574                     ++CurIndex;
   9.575             }
   9.576             return *this;
   9.577         }
   9.578         Iterator operator++(int)
   9.579         {
   9.580             Iterator it(*this);
   9.581             operator++();
   9.582             return it;
   9.583         }
   9.584         Iterator& operator--()
   9.585         {
   9.586             if (pArray)
   9.587             {
   9.588                 if (CurIndex >= 0)
   9.589                     --CurIndex;
   9.590             }
   9.591             return *this;
   9.592         }
   9.593         Iterator operator--(int)
   9.594         {
   9.595             Iterator it(*this);
   9.596             operator--();
   9.597             return it;
   9.598         }
   9.599         Iterator operator+(int delta) const
   9.600         {
   9.601             return Iterator(pArray, CurIndex + delta);
   9.602         }
   9.603         Iterator operator-(int delta) const
   9.604         {
   9.605             return Iterator(pArray, CurIndex - delta);
   9.606         }
   9.607         SPInt operator-(const Iterator& right) const
   9.608         {
   9.609             OVR_ASSERT(pArray == right.pArray);
   9.610             return CurIndex - right.CurIndex;
   9.611         }
   9.612         ValueType& operator*() const    { OVR_ASSERT(pArray); return  (*pArray)[CurIndex]; }
   9.613         ValueType* operator->() const   { OVR_ASSERT(pArray); return &(*pArray)[CurIndex]; }
   9.614         ValueType* GetPtr() const       { OVR_ASSERT(pArray); return &(*pArray)[CurIndex]; }
   9.615 
   9.616         bool IsFinished() const { return !pArray || CurIndex < 0 || CurIndex >= (int)pArray->GetSize(); }
   9.617 
   9.618         void Remove()
   9.619         {
   9.620             if (!IsFinished())
   9.621                 pArray->RemoveAt(CurIndex);
   9.622         }
   9.623 
   9.624         SPInt GetIndex() const { return CurIndex; }
   9.625     };
   9.626 
   9.627     Iterator Begin() { return Iterator(this); }
   9.628     Iterator End()   { return Iterator(this, (SPInt)GetSize()); }
   9.629     Iterator Last()  { return Iterator(this, (SPInt)GetSize() - 1); }
   9.630 
   9.631     class ConstIterator
   9.632     {
   9.633         const SelfType* pArray;
   9.634         SPInt           CurIndex;
   9.635 
   9.636     public:
   9.637         ConstIterator() : pArray(0), CurIndex(-1) {}
   9.638         ConstIterator(const SelfType* parr, SPInt idx = 0) : pArray(parr), CurIndex(idx) {}
   9.639 
   9.640         bool operator==(const ConstIterator& it) const { return pArray == it.pArray && CurIndex == it.CurIndex; }
   9.641         bool operator!=(const ConstIterator& it) const { return pArray != it.pArray || CurIndex != it.CurIndex; }
   9.642 
   9.643         ConstIterator& operator++()
   9.644         {
   9.645             if (pArray)
   9.646             {
   9.647                 if (CurIndex < (int)pArray->GetSize())
   9.648                     ++CurIndex;
   9.649             }
   9.650             return *this;
   9.651         }
   9.652         ConstIterator operator++(int)
   9.653         {
   9.654             ConstIterator it(*this);
   9.655             operator++();
   9.656             return it;
   9.657         }
   9.658         ConstIterator& operator--()
   9.659         {
   9.660             if (pArray)
   9.661             {
   9.662                 if (CurIndex >= 0)
   9.663                     --CurIndex;
   9.664             }
   9.665             return *this;
   9.666         }
   9.667         ConstIterator operator--(int)
   9.668         {
   9.669             ConstIterator it(*this);
   9.670             operator--();
   9.671             return it;
   9.672         }
   9.673         ConstIterator operator+(int delta) const
   9.674         {
   9.675             return ConstIterator(pArray, CurIndex + delta);
   9.676         }
   9.677         ConstIterator operator-(int delta) const
   9.678         {
   9.679             return ConstIterator(pArray, CurIndex - delta);
   9.680         }
   9.681         SPInt operator-(const ConstIterator& right) const
   9.682         {
   9.683             OVR_ASSERT(pArray == right.pArray);
   9.684             return CurIndex - right.CurIndex;
   9.685         }
   9.686         const ValueType& operator*() const  { OVR_ASSERT(pArray); return  (*pArray)[CurIndex]; }
   9.687         const ValueType* operator->() const { OVR_ASSERT(pArray); return &(*pArray)[CurIndex]; }
   9.688         const ValueType* GetPtr() const     { OVR_ASSERT(pArray); return &(*pArray)[CurIndex]; }
   9.689 
   9.690         bool IsFinished() const { return !pArray || CurIndex < 0 || CurIndex >= (int)pArray->GetSize(); }
   9.691 
   9.692         SPInt GetIndex()  const { return CurIndex; }
   9.693     };
   9.694     ConstIterator Begin() const { return ConstIterator(this); }
   9.695     ConstIterator End() const   { return ConstIterator(this, (SPInt)GetSize()); }
   9.696     ConstIterator Last() const  { return ConstIterator(this, (SPInt)GetSize() - 1); }
   9.697 
   9.698 protected:
   9.699     ArrayData   Data;
   9.700 };
   9.701 
   9.702 
   9.703 
   9.704 //-----------------------------------------------------------------------------------
   9.705 // ***** Array
   9.706 //
   9.707 // General purpose array for movable objects that require explicit 
   9.708 // construction/destruction.
   9.709 template<class T, class SizePolicy=ArrayDefaultPolicy>
   9.710 class Array : public ArrayBase<ArrayData<T, ContainerAllocator<T>, SizePolicy> >
   9.711 {
   9.712 public:
   9.713     typedef T                                                           ValueType;
   9.714     typedef ContainerAllocator<T>                                       AllocatorType;
   9.715     typedef SizePolicy                                                  SizePolicyType;
   9.716     typedef Array<T, SizePolicy>                                        SelfType;
   9.717     typedef ArrayBase<ArrayData<T, ContainerAllocator<T>, SizePolicy> > BaseType;
   9.718 
   9.719     Array() : BaseType() {}
   9.720     Array(int size) : BaseType(size) {}
   9.721     Array(const SizePolicyType& p) : BaseType() { SetSizePolicy(p); }
   9.722     Array(const SelfType& a) : BaseType(a) {}
   9.723     const SelfType& operator=(const SelfType& a) { BaseType::operator=(a); return *this; }
   9.724 };
   9.725 
   9.726 // ***** ArrayPOD
   9.727 //
   9.728 // General purpose array for movable objects that DOES NOT require  
   9.729 // construction/destruction. Constructors and destructors are not called! 
   9.730 // Global heap is in use.
   9.731 template<class T, class SizePolicy=ArrayDefaultPolicy>
   9.732 class ArrayPOD : public ArrayBase<ArrayData<T, ContainerAllocator_POD<T>, SizePolicy> >
   9.733 {
   9.734 public:
   9.735     typedef T                                                               ValueType;
   9.736     typedef ContainerAllocator_POD<T>                                       AllocatorType;
   9.737     typedef SizePolicy                                                      SizePolicyType;
   9.738     typedef ArrayPOD<T, SizePolicy>                                         SelfType;
   9.739     typedef ArrayBase<ArrayData<T, ContainerAllocator_POD<T>, SizePolicy> > BaseType;
   9.740 
   9.741     ArrayPOD() : BaseType() {}
   9.742     ArrayPOD(int size) : BaseType(size) {}
   9.743     ArrayPOD(const SizePolicyType& p) : BaseType() { SetSizePolicy(p); }
   9.744     ArrayPOD(const SelfType& a) : BaseType(a) {}
   9.745     const SelfType& operator=(const SelfType& a) { BaseType::operator=(a); return *this; }
   9.746 };
   9.747 
   9.748 
   9.749 // ***** ArrayCPP
   9.750 //
   9.751 // General purpose, fully C++ compliant array. Can be used with non-movable data.
   9.752 // Global heap is in use.
   9.753 template<class T, class SizePolicy=ArrayDefaultPolicy>
   9.754 class ArrayCPP : public ArrayBase<ArrayData<T, ContainerAllocator_CPP<T>, SizePolicy> >
   9.755 {
   9.756 public:
   9.757     typedef T                                                               ValueType;
   9.758     typedef ContainerAllocator_CPP<T>                                       AllocatorType;
   9.759     typedef SizePolicy                                                      SizePolicyType;
   9.760     typedef ArrayCPP<T, SizePolicy>                                         SelfType;
   9.761     typedef ArrayBase<ArrayData<T, ContainerAllocator_CPP<T>, SizePolicy> > BaseType;
   9.762 
   9.763     ArrayCPP() : BaseType() {}
   9.764     ArrayCPP(int size) : BaseType(size) {}
   9.765     ArrayCPP(const SizePolicyType& p) : BaseType() { SetSizePolicy(p); }
   9.766     ArrayCPP(const SelfType& a) : BaseType(a) {}
   9.767     const SelfType& operator=(const SelfType& a) { BaseType::operator=(a); return *this; }
   9.768 };
   9.769 
   9.770 
   9.771 // ***** ArrayCC
   9.772 //
   9.773 // A modification of the array that uses the given default value to
   9.774 // construct the elements. The constructors and destructors are 
   9.775 // properly called, the objects must be movable.
   9.776 
   9.777 template<class T, class SizePolicy=ArrayDefaultPolicy>
   9.778 class ArrayCC : public ArrayBase<ArrayDataCC<T, ContainerAllocator<T>, SizePolicy> >
   9.779 {
   9.780 public:
   9.781     typedef T                                                               ValueType;
   9.782     typedef ContainerAllocator<T>                                           AllocatorType;
   9.783     typedef SizePolicy                                                      SizePolicyType;
   9.784     typedef ArrayCC<T, SizePolicy>                                          SelfType;
   9.785     typedef ArrayBase<ArrayDataCC<T, ContainerAllocator<T>, SizePolicy> >   BaseType;
   9.786 
   9.787     ArrayCC(const ValueType& defval) : BaseType(defval) {}
   9.788     ArrayCC(const ValueType& defval, int size) : BaseType(defval, size) {}
   9.789     ArrayCC(const ValueType& defval, const SizePolicyType& p) : BaseType(defval) { SetSizePolicy(p); }
   9.790     ArrayCC(const SelfType& a) : BaseType(a) {}
   9.791     const SelfType& operator=(const SelfType& a) { BaseType::operator=(a); return *this; }
   9.792 };
   9.793 
   9.794 } // OVR
   9.795 
   9.796 #endif
   9.797 \ No newline at end of file
    10.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    10.2 +++ b/libovr/Src/Kernel/OVR_Atomic.cpp	Sat Sep 14 16:14:59 2013 +0300
    10.3 @@ -0,0 +1,1 @@
    10.4 +/************************************************************************************
    10.5 
    10.6 Filename    :   OVR_Atomic.cpp
    10.7 Content     :   Contains atomic operations and inline fastest locking
    10.8                 functionality. Will contain #ifdefs for OS efficiency.
    10.9                 Have non-thread-safe implementation if not available.
   10.10 Created     :   September 19, 2012
   10.11 Notes       : 
   10.12 
   10.13 Copyright   :   Copyright 2012 Oculus VR, Inc. All Rights reserved.
   10.14 
   10.15 Use of this software is subject to the terms of the Oculus license
   10.16 agreement provided at the time of installation or download, or which
   10.17 otherwise accompanies this software in either electronic or hard copy form.
   10.18 
   10.19 ************************************************************************************/
   10.20 
   10.21 #include "OVR_Atomic.h"
   10.22 
   10.23 #ifdef OVR_ENABLE_THREADS
   10.24 
   10.25 // Include Windows 8-Metro compatible Synchronization API
   10.26 #if defined(OVR_OS_WIN32) && defined(NTDDI_WIN8) && (NTDDI_VERSION >= NTDDI_WIN8)
   10.27 #include <synchapi.h>
   10.28 #endif
   10.29 
   10.30 
   10.31 namespace OVR {
   10.32 
   10.33 // ***** Windows Lock implementation
   10.34 
   10.35 #if defined(OVR_OS_WIN32)
   10.36 
   10.37 // ***** Standard Win32 Lock implementation
   10.38 
   10.39 // Constructors
   10.40 Lock::Lock(unsigned spinCount)
   10.41 {
   10.42 #if defined(NTDDI_WIN8) && (NTDDI_VERSION >= NTDDI_WIN8)
   10.43    // On Windows 8 we use InitializeCriticalSectionEx due to Metro-Compatibility
   10.44    InitializeCriticalSectionEx(&cs, spinCount,
   10.45                                OVR_DEBUG_SELECT(NULL, CRITICAL_SECTION_NO_DEBUG_INFO));
   10.46 #else
   10.47     // Spin count init critical section function prototype for Window NT
   10.48     typedef BOOL (WINAPI *Function_InitializeCriticalSectionAndSpinCount) 
   10.49                  (LPCRITICAL_SECTION lpCriticalSection, DWORD dwSpinCount);
   10.50 
   10.51 
   10.52     // Try to load function dynamically so that we don't require NT
   10.53     // On Windows NT we will use InitializeCriticalSectionAndSpinCount
   10.54     static  bool initTried = 0;
   10.55     static  Function_InitializeCriticalSectionAndSpinCount pInitFn = 0;
   10.56 
   10.57     if (!initTried)
   10.58     {
   10.59         HMODULE hmodule = ::LoadLibrary(OVR_STR("kernel32.dll"));
   10.60         pInitFn     = (Function_InitializeCriticalSectionAndSpinCount)
   10.61                       ::GetProcAddress(hmodule, "InitializeCriticalSectionAndSpinCount");
   10.62         initTried   = true;
   10.63     }
   10.64 
   10.65     // Initialize the critical section
   10.66     if (pInitFn)
   10.67         pInitFn(&cs, spinCount);
   10.68     else
   10.69         ::InitializeCriticalSection(&cs);
   10.70 #endif
   10.71    
   10.72 }
   10.73 
   10.74 
   10.75 Lock::~Lock()
   10.76 {
   10.77     DeleteCriticalSection(&cs);
   10.78 }
   10.79 
   10.80 
   10.81 #endif
   10.82 
   10.83 } // OVR
   10.84 
   10.85 #endif // OVR_ENABLE_THREADS
   10.86 \ No newline at end of file
    11.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    11.2 +++ b/libovr/Src/Kernel/OVR_Atomic.h	Sat Sep 14 16:14:59 2013 +0300
    11.3 @@ -0,0 +1,1 @@
    11.4 +/************************************************************************************
    11.5 
    11.6 PublicHeader:   OVR.h
    11.7 Filename    :   OVR_Atomic.h
    11.8 Content     :   Contains atomic operations and inline fastest locking
    11.9                 functionality. Will contain #ifdefs for OS efficiency.
   11.10                 Have non-thread-safe implementaion if not available.
   11.11 Created     :   September 19, 2012
   11.12 Notes       : 
   11.13 
   11.14 Copyright   :   Copyright 2012 Oculus VR, Inc. All Rights reserved.
   11.15 
   11.16 Use of this software is subject to the terms of the Oculus license
   11.17 agreement provided at the time of installation or download, or which
   11.18 otherwise accompanies this software in either electronic or hard copy form.
   11.19 
   11.20 ************************************************************************************/
   11.21 #ifndef OVR_Atomic_h
   11.22 #define OVR_Atomic_h
   11.23 
   11.24 #include "OVR_Types.h"
   11.25 
   11.26 // Include System thread functionality.
   11.27 #if defined(OVR_OS_WIN32)
   11.28 #include <windows.h>
   11.29 #else
   11.30 #include <pthread.h>
   11.31 #endif
   11.32 
   11.33 
   11.34 namespace OVR {
   11.35 
   11.36 
   11.37 // ****** Declared classes
   11.38 
   11.39 // If there is NO thread support we implement AtomicOps and
   11.40 // Lock objects as no-ops. The other classes are not defined.
   11.41 template<class C> class AtomicOps;
   11.42 template<class T> class AtomicInt;
   11.43 template<class T> class AtomicPtr;
   11.44 
   11.45 class   Lock;
   11.46 
   11.47 
   11.48 //-----------------------------------------------------------------------------------
   11.49 // ***** AtomicOps
   11.50 
   11.51 // Atomic operations are provided by the AtomicOps templates class,
   11.52 // implemented through system-specific AtomicOpsRaw specializations.
   11.53 // It provides several fundamental operations such as Exchange, ExchangeAdd
   11.54 // CompareAndSet, and Store_Release. Each function includes several memory
   11.55 // synchronization versions, important for multiprocessing CPUs with weak
   11.56 // memory consistency. The following memory fencing strategies are supported:
   11.57 //
   11.58 //  - NoSync.  No memory synchronization is done for atomic op.
   11.59 //  - Release. All other memory writes are completed before atomic op
   11.60 //             writes its results.
   11.61 //  - Acquire. Further memory reads are forced to wait until atomic op
   11.62 //             executes, guaranteeing that the right values will be seen.
   11.63 //  - Sync.    A combination of Release and Acquire.
   11.64 
   11.65 
   11.66 // *** AtomicOpsRaw
   11.67 
   11.68 // AtomicOpsRaw is a specialized template that provides atomic operations 
   11.69 // used by AtomicOps. This class has two fundamental qualities: (1) it
   11.70 // defines a type T of correct size, and (2) provides operations that work
   11.71 // atomically, such as Exchange_Sync and CompareAndSet_Release.
   11.72 
   11.73 // AtomicOpsRawBase class contains shared constants/classes for AtomicOpsRaw.
   11.74 // The primary thing is does is define sync class objects, whose destructor and
   11.75 // constructor provide places to insert appropriate synchronization calls, on 
   11.76 // systems where such calls are necessary. So far, the breakdown is as follows:
   11.77 // 
   11.78 //  - X86 systems don't need custom syncs, since their exchange/atomic
   11.79 //    instructions are implicitly synchronized.
   11.80 //  - PowerPC requires lwsync/isync instructions that can use this mechanism.
   11.81 //  - If some other systems require a mechanism where syncing type is associated
   11.82 //    with a particular instruction, the default implementation (which implements
   11.83 //    all Sync, Acquire, and Release modes in terms of NoSync and fence) may not
   11.84 //    work. Ii that case it will need to be #ifdef-ed conditionally.
   11.85 
   11.86 struct AtomicOpsRawBase
   11.87 {
   11.88 #if !defined(OVR_ENABLE_THREADS) || defined(OVR_CPU_X86) || defined(OVR_OS_WIN32) || defined(OVR_OS_IPHONE)
   11.89     // Need to have empty constructor to avoid class 'unused' variable warning.
   11.90     struct FullSync { inline FullSync() { } };
   11.91     struct AcquireSync { inline AcquireSync() { } };
   11.92     struct ReleaseSync { inline ReleaseSync() { } };
   11.93 
   11.94 #elif defined(OVR_CPU_PPC64) || defined(OVR_CPU_PPC)
   11.95     struct FullSync { inline FullSync() { asm volatile("sync\n"); } ~FullSync() { asm volatile("isync\n"); } };
   11.96     struct AcquireSync { inline AcquireSync() { } ~AcquireSync() { asm volatile("isync\n"); } };
   11.97     struct ReleaseSync { inline ReleaseSync() { asm volatile("sync\n"); } };
   11.98 
   11.99 #elif defined(OVR_CPU_MIPS)
  11.100     struct FullSync { inline FullSync() { asm volatile("sync\n"); } ~FullSync() { asm volatile("sync\n"); } };
  11.101     struct AcquireSync { inline AcquireSync() { } ~AcquireSync() { asm volatile("sync\n"); } };
  11.102     struct ReleaseSync { inline ReleaseSync() { asm volatile("sync\n"); } };
  11.103 
  11.104 #elif defined(OVR_CPU_ARM)
  11.105     struct FullSync { inline FullSync() { asm volatile("dmb\n"); } ~FullSync() { asm volatile("dmb\n"); } };
  11.106     struct AcquireSync { inline AcquireSync() { } ~AcquireSync() { asm volatile("dmb\n"); } };
  11.107     struct ReleaseSync { inline ReleaseSync() { asm volatile("dmb\n"); } };
  11.108 
  11.109 
  11.110 #elif defined(OVR_CC_GNU) && (__GNUC__ >= 4)
  11.111     // __sync functions are already full sync
  11.112     struct FullSync { inline FullSync() { } };
  11.113     struct AcquireSync { inline AcquireSync() { } };
  11.114     struct ReleaseSync { inline ReleaseSync() { } };
  11.115 #endif
  11.116 };
  11.117 
  11.118 
  11.119 // 4-Byte raw data atomic op implementation class.
  11.120 struct AtomicOpsRaw_4ByteImpl : public AtomicOpsRawBase
  11.121 {
  11.122 #if !defined(OVR_ENABLE_THREADS)
  11.123 
  11.124     // Provide a type for no-thread-support cases. Used by AtomicOpsRaw_DefImpl.
  11.125     typedef UInt32 T;   
  11.126 
  11.127     // *** Thread - Safe Atomic Versions.
  11.128 
  11.129 #elif defined(OVR_OS_WIN32)
  11.130 
  11.131     // Use special defined for VC6, where volatile is not used and
  11.132     // InterlockedCompareExchange is declared incorrectly.
  11.133     typedef LONG T;      
  11.134 #if defined(OVR_CC_MSVC) && (OVR_CC_MSVC < 1300)
  11.135     typedef T* InterlockTPtr;
  11.136     typedef LPVOID ET;
  11.137     typedef ET* InterlockETPtr;
  11.138 #else
  11.139     typedef volatile T* InterlockTPtr;
  11.140     typedef T ET;
  11.141     typedef InterlockTPtr InterlockETPtr;
  11.142 #endif
  11.143     inline static T     Exchange_NoSync(volatile T* p, T val)            { return InterlockedExchange((InterlockTPtr)p, val); }
  11.144     inline static T     ExchangeAdd_NoSync(volatile T* p, T val)         { return InterlockedExchangeAdd((InterlockTPtr)p, val); }
  11.145     inline static bool  CompareAndSet_NoSync(volatile T* p, T c, T val)  { return InterlockedCompareExchange((InterlockETPtr)p, (ET)val, (ET)c) == (ET)c; }
  11.146 
  11.147 #elif defined(OVR_CPU_PPC64) || defined(OVR_CPU_PPC)
  11.148     typedef UInt32 T;
  11.149     static inline UInt32   Exchange_NoSync(volatile UInt32 *i, UInt32 j)
  11.150     {
  11.151         UInt32 ret;
  11.152 
  11.153         asm volatile("1:\n\t"
  11.154                      "lwarx  %[r],0,%[i]\n\t"
  11.155                      "stwcx. %[j],0,%[i]\n\t"
  11.156                      "bne-   1b\n"
  11.157                      : "+m" (*i), [r] "=&b" (ret) : [i] "b" (i), [j] "b" (j) : "cc", "memory");
  11.158 
  11.159         return ret;
  11.160     }
  11.161 
  11.162     static inline UInt32   ExchangeAdd_NoSync(volatile UInt32 *i, UInt32 j)
  11.163     {
  11.164         UInt32 dummy, ret;
  11.165 
  11.166         asm volatile("1:\n\t"
  11.167                      "lwarx  %[r],0,%[i]\n\t"
  11.168                      "add    %[o],%[r],%[j]\n\t"
  11.169                      "stwcx. %[o],0,%[i]\n\t"
  11.170                      "bne-   1b\n"
  11.171                      : "+m" (*i), [r] "=&b" (ret), [o] "=&r" (dummy) : [i] "b" (i), [j] "b" (j) : "cc", "memory");
  11.172 
  11.173         return ret;
  11.174     }
  11.175 
  11.176     static inline bool     CompareAndSet_NoSync(volatile UInt32 *i, UInt32 c, UInt32 value)
  11.177     {
  11.178         UInt32 ret;
  11.179 
  11.180         asm volatile("1:\n\t"
  11.181                      "lwarx  %[r],0,%[i]\n\t"
  11.182                      "cmpw   0,%[r],%[cmp]\n\t"
  11.183                      "mfcr   %[r]\n\t"
  11.184                      "bne-   2f\n\t"
  11.185                      "stwcx. %[val],0,%[i]\n\t"
  11.186                      "bne-   1b\n\t"
  11.187                      "2:\n"
  11.188                      : "+m" (*i), [r] "=&b" (ret) : [i] "b" (i), [cmp] "b" (c), [val] "b" (value) : "cc", "memory");
  11.189 
  11.190         return (ret & 0x20000000) ? 1 : 0;
  11.191     }
  11.192 
  11.193 #elif defined(OVR_CPU_MIPS)
  11.194     typedef UInt32 T;
  11.195 
  11.196     static inline UInt32   Exchange_NoSync(volatile UInt32 *i, UInt32 j)
  11.197     {
  11.198         UInt32 ret;
  11.199 
  11.200         asm volatile("1:\n\t"
  11.201                      "ll     %[r],0(%[i])\n\t"
  11.202                      "sc     %[j],0(%[i])\n\t"
  11.203                      "beq    %[j],$0,1b\n\t"
  11.204                      "nop    \n"
  11.205                      : "+m" (*i), [r] "=&d" (ret) : [i] "d" (i), [j] "d" (j) : "cc", "memory");
  11.206 
  11.207         return ret;
  11.208     }
  11.209 
  11.210     static inline UInt32   ExchangeAdd_NoSync(volatile UInt32 *i, UInt32 j)
  11.211     {
  11.212         UInt32 ret;
  11.213 
  11.214         asm volatile("1:\n\t"
  11.215                      "ll     %[r],0(%[i])\n\t"
  11.216                      "addu   %[j],%[r],%[j]\n\t"
  11.217                      "sc     %[j],0(%[i])\n\t"
  11.218                      "beq    %[j],$0,1b\n\t"
  11.219                      "nop    \n"
  11.220                      : "+m" (*i), [r] "=&d" (ret) : [i] "d" (i), [j] "d" (j) : "cc", "memory");
  11.221 
  11.222         return ret;
  11.223     }
  11.224 
  11.225     static inline bool     CompareAndSet_NoSync(volatile UInt32 *i, UInt32 c, UInt32 value)
  11.226     {
  11.227         UInt32 ret, dummy;
  11.228 
  11.229         asm volatile("1:\n\t"
  11.230                      "move   %[r],$0\n\t"
  11.231                      "ll     %[o],0(%[i])\n\t"
  11.232                      "bne    %[o],%[c],2f\n\t"
  11.233                      "move   %[r],%[v]\n\t"
  11.234                      "sc     %[r],0(%[i])\n\t"
  11.235                      "beq    %[r],$0,1b\n\t"
  11.236                      "nop    \n\t"
  11.237                      "2:\n"
  11.238                      : "+m" (*i),[r] "=&d" (ret), [o] "=&d" (dummy) : [i] "d" (i), [c] "d" (c), [v] "d" (value)
  11.239                      : "cc", "memory");
  11.240 
  11.241         return ret;
  11.242     }
  11.243 
  11.244 #elif defined(OVR_CPU_ARM) && defined(OVR_CC_ARM)
  11.245     typedef UInt32 T;
  11.246 
  11.247     static inline UInt32   Exchange_NoSync(volatile UInt32 *i, UInt32 j)
  11.248     {
  11.249         for(;;)
  11.250         {
  11.251             T r = __ldrex(i);
  11.252             if (__strex(j, i) == 0)
  11.253                 return r;
  11.254         }
  11.255     }
  11.256     static inline UInt32   ExchangeAdd_NoSync(volatile UInt32 *i, UInt32 j)
  11.257     {
  11.258         for(;;)
  11.259         {
  11.260             T r = __ldrex(i);
  11.261             if (__strex(r + j, i) == 0)
  11.262                 return r;
  11.263         }
  11.264     }
  11.265 
  11.266     static inline bool     CompareAndSet_NoSync(volatile UInt32 *i, UInt32 c, UInt32 value)
  11.267     {
  11.268         for(;;)
  11.269         {
  11.270             T r = __ldrex(i);
  11.271             if (r != c)
  11.272                 return 0;
  11.273             if (__strex(value, i) == 0)
  11.274                 return 1;
  11.275         }
  11.276     }
  11.277 
  11.278 #elif defined(OVR_CPU_ARM)
  11.279     typedef UInt32 T;
  11.280 
  11.281     static inline UInt32   Exchange_NoSync(volatile UInt32 *i, UInt32 j)
  11.282     {
  11.283         UInt32 ret, dummy;
  11.284 
  11.285         asm volatile("1:\n\t"
  11.286             "ldrex  %[r],[%[i]]\n\t"
  11.287             "strex  %[t],%[j],[%[i]]\n\t"
  11.288             "cmp    %[t],#0\n\t"
  11.289             "bne    1b\n\t"
  11.290             : "+m" (*i), [r] "=&r" (ret), [t] "=&r" (dummy) : [i] "r" (i), [j] "r" (j) : "cc", "memory");
  11.291 
  11.292         return ret;
  11.293     }
  11.294 
  11.295     static inline UInt32   ExchangeAdd_NoSync(volatile UInt32 *i, UInt32 j)
  11.296     {
  11.297         UInt32 ret, dummy, test;
  11.298 
  11.299         asm volatile("1:\n\t"
  11.300             "ldrex  %[r],[%[i]]\n\t"
  11.301             "add    %[o],%[r],%[j]\n\t"
  11.302             "strex  %[t],%[o],[%[i]]\n\t"
  11.303             "cmp    %[t],#0\n\t"
  11.304             "bne    1b\n\t"
  11.305             : "+m" (*i), [r] "=&r" (ret), [o] "=&r" (dummy), [t] "=&r" (test)  : [i] "r" (i), [j] "r" (j) : "cc", "memory");
  11.306 
  11.307         return ret;
  11.308     }
  11.309 
  11.310     static inline bool     CompareAndSet_NoSync(volatile UInt32 *i, UInt32 c, UInt32 value)
  11.311     {
  11.312         UInt32 ret = 1, dummy, test;
  11.313 
  11.314         asm volatile("1:\n\t"
  11.315             "ldrex  %[o],[%[i]]\n\t"
  11.316             "cmp    %[o],%[c]\n\t"
  11.317             "bne    2f\n\t"
  11.318             "strex  %[r],%[v],[%[i]]\n\t"
  11.319             "cmp    %[r],#0\n\t"
  11.320             "bne    1b\n\t"
  11.321             "2:\n"
  11.322             : "+m" (*i),[r] "=&r" (ret), [o] "=&r" (dummy), [t] "=&r" (test) : [i] "r" (i), [c] "r" (c), [v] "r" (value)
  11.323             : "cc", "memory");
  11.324 
  11.325         return !ret;
  11.326     }
  11.327 
  11.328 #elif defined(OVR_CPU_X86)
  11.329     typedef UInt32 T;
  11.330 
  11.331     static inline UInt32   Exchange_NoSync(volatile UInt32 *i, UInt32 j)
  11.332     {
  11.333         asm volatile("xchgl %1,%[i]\n"
  11.334                      : "+m" (*i), "=q" (j) : [i] "m" (*i), "1" (j) : "cc", "memory");
  11.335 
  11.336         return j;
  11.337     }
  11.338 
  11.339     static inline UInt32   ExchangeAdd_NoSync(volatile UInt32 *i, UInt32 j)
  11.340     {
  11.341         asm volatile("lock; xaddl %1,%[i]\n"
  11.342                      : "+m" (*i), "+q" (j) : [i] "m" (*i) : "cc", "memory");
  11.343 
  11.344         return j;
  11.345     }
  11.346 
  11.347     static inline bool     CompareAndSet_NoSync(volatile UInt32 *i, UInt32 c, UInt32 value)
  11.348     {
  11.349         UInt32 ret;
  11.350 
  11.351         asm volatile("lock; cmpxchgl %[v],%[i]\n"
  11.352                      : "+m" (*i), "=a" (ret) : [i] "m" (*i), "1" (c), [v] "q" (value) : "cc", "memory");
  11.353 
  11.354         return (ret == c);
  11.355     }
  11.356 
  11.357 #elif defined(OVR_CC_GNU) && (__GNUC__ >= 4 && __GNUC_MINOR__ >= 1)
  11.358 
  11.359     typedef UInt32 T;
  11.360 
  11.361     static inline T   Exchange_NoSync(volatile T *i, T j)
  11.362     {
  11.363         T v;
  11.364         do {
  11.365             v = *i;
  11.366         } while (!__sync_bool_compare_and_swap(i, v, j));
  11.367         return v;
  11.368     }
  11.369 
  11.370     static inline T   ExchangeAdd_NoSync(volatile T *i, T j)
  11.371     {
  11.372         return __sync_fetch_and_add(i, j);
  11.373     }
  11.374 
  11.375     static inline bool     CompareAndSet_NoSync(volatile T *i, T c, T value)
  11.376     {
  11.377         return __sync_bool_compare_and_swap(i, c, value);
  11.378     }
  11.379 
  11.380 #endif // OS
  11.381 };
  11.382 
  11.383 
  11.384 // 8-Byte raw data data atomic op implementation class.
  11.385 // Currently implementation is provided only on systems with 64-bit pointers.
  11.386 struct AtomicOpsRaw_8ByteImpl : public AtomicOpsRawBase
  11.387 {    
  11.388 #if !defined(OVR_64BIT_POINTERS) || !defined(OVR_ENABLE_THREADS)
  11.389 
  11.390     // Provide a type for no-thread-support cases. Used by AtomicOpsRaw_DefImpl.
  11.391     typedef UInt64 T;
  11.392 
  11.393     // *** Thread - Safe OS specific versions.
  11.394 #elif defined(OVR_OS_WIN32)
  11.395 
  11.396     // This is only for 64-bit systems.
  11.397     typedef LONG64      T;
  11.398     typedef volatile T* InterlockTPtr;    
  11.399     inline static T     Exchange_NoSync(volatile T* p, T val)            { return InterlockedExchange64((InterlockTPtr)p, val); }
  11.400     inline static T     ExchangeAdd_NoSync(volatile T* p, T val)         { return InterlockedExchangeAdd64((InterlockTPtr)p, val); }
  11.401     inline static bool  CompareAndSet_NoSync(volatile T* p, T c, T val)  { return InterlockedCompareExchange64((InterlockTPtr)p, val, c) == c; }
  11.402 
  11.403 #elif defined(OVR_CPU_PPC64)
  11.404  
  11.405     typedef UInt64 T;
  11.406 
  11.407     static inline UInt64   Exchange_NoSync(volatile UInt64 *i, UInt64 j)
  11.408     {
  11.409         UInt64 dummy, ret;
  11.410 
  11.411         asm volatile("1:\n\t"
  11.412                      "ldarx  %[r],0,%[i]\n\t"
  11.413                      "mr     %[o],%[j]\n\t"
  11.414                      "stdcx. %[o],0,%[i]\n\t"
  11.415                      "bne-   1b\n"
  11.416                      : "+m" (*i), [r] "=&b" (ret), [o] "=&r" (dummy) : [i] "b" (i), [j] "b" (j) : "cc");
  11.417 
  11.418         return ret;
  11.419     }
  11.420 
  11.421     static inline UInt64   ExchangeAdd_NoSync(volatile UInt64 *i, UInt64 j)
  11.422     {
  11.423         UInt64 dummy, ret;
  11.424 
  11.425         asm volatile("1:\n\t"
  11.426                      "ldarx  %[r],0,%[i]\n\t"
  11.427                      "add    %[o],%[r],%[j]\n\t"
  11.428                      "stdcx. %[o],0,%[i]\n\t"
  11.429                      "bne-   1b\n"
  11.430                      : "+m" (*i), [r] "=&b" (ret), [o] "=&r" (dummy) : [i] "b" (i), [j] "b" (j) : "cc");
  11.431 
  11.432         return ret;
  11.433     }
  11.434 
  11.435     static inline bool     CompareAndSet_NoSync(volatile UInt64 *i, UInt64 c, UInt64 value)
  11.436     {
  11.437         UInt64 ret, dummy;
  11.438 
  11.439         asm volatile("1:\n\t"
  11.440                      "ldarx  %[r],0,%[i]\n\t"
  11.441                      "cmpw   0,%[r],%[cmp]\n\t"
  11.442                      "mfcr   %[r]\n\t"
  11.443                      "bne-   2f\n\t"
  11.444                      "stdcx. %[val],0,%[i]\n\t"
  11.445                      "bne-   1b\n\t"
  11.446                      "2:\n"
  11.447                      : "+m" (*i), [r] "=&b" (ret), [o] "=&r" (dummy) : [i] "b" (i), [cmp] "b" (c), [val] "b" (value) : "cc");
  11.448 
  11.449         return (ret & 0x20000000) ? 1 : 0;
  11.450     }
  11.451 
  11.452 #elif defined(OVR_CC_GNU) && (__GNUC__ >= 4 && __GNUC_MINOR__ >= 1)
  11.453 
  11.454     typedef UInt64 T;
  11.455 
  11.456     static inline T   Exchange_NoSync(volatile T *i, T j)
  11.457     {
  11.458         T v;
  11.459         do {
  11.460             v = *i;
  11.461         } while (!__sync_bool_compare_and_swap(i, v, j));
  11.462         return v;
  11.463     }
  11.464 
  11.465     static inline T   ExchangeAdd_NoSync(volatile T *i, T j)
  11.466     {
  11.467         return __sync_fetch_and_add(i, j);
  11.468     }
  11.469 
  11.470     static inline bool     CompareAndSet_NoSync(volatile T *i, T c, T value)
  11.471     {
  11.472         return __sync_bool_compare_and_swap(i, c, value);
  11.473     }
  11.474 
  11.475 #endif // OS
  11.476 };
  11.477 
  11.478 
  11.479 // Default implementation for AtomicOpsRaw; provides implementation of mem-fenced
  11.480 // atomic operations where fencing is done with a sync object wrapped around a NoSync
  11.481 // operation implemented in the base class. If such implementation is not possible
  11.482 // on a given platform, #ifdefs can be used to disable it and then op functions can be
  11.483 // implemented individually in the appropriate AtomicOpsRaw<size> class.
  11.484 
  11.485 template<class O>
  11.486 struct AtomicOpsRaw_DefImpl : public O
  11.487 {
  11.488     typedef typename O::T O_T;
  11.489     typedef typename O::FullSync    O_FullSync;
  11.490     typedef typename O::AcquireSync O_AcquireSync;
  11.491     typedef typename O::ReleaseSync O_ReleaseSync;
  11.492 
  11.493     // If there is no thread support, provide the default implementation. In this case,
  11.494     // the base class (0) must still provide the T declaration.
  11.495 #ifndef OVR_ENABLE_THREADS
  11.496 
  11.497     // Atomic exchange of val with argument. Returns old val.
  11.498     inline static O_T   Exchange_NoSync(volatile O_T* p, O_T val)           { O_T old = *p; *p = val; return old; }
  11.499     // Adds a new val to argument; returns its old val.
  11.500     inline static O_T   ExchangeAdd_NoSync(volatile O_T* p, O_T val)        { O_T old = *p; *p += val; return old; }
  11.501     // Compares the argument data with 'c' val.
  11.502     // If succeeded, stores val int '*p' and returns true; otherwise returns false.
  11.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; }
  11.504 
  11.505 #endif
  11.506 
  11.507     // If NoSync wrapped implementation may not be possible, it this block should be
  11.508     //  replaced with per-function implementation in O.
  11.509     // "AtomicOpsRaw_DefImpl<O>::" prefix in calls below.
  11.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); }
  11.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); }
  11.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); }  
  11.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); }
  11.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); }
  11.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); }
  11.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); }
  11.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); }
  11.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); }
  11.519 
  11.520     // Loads and stores with memory fence. These have only the relevant versions.
  11.521 #ifdef OVR_CPU_X86
  11.522     // On X86, Store_Release is implemented as exchange. Note that we can also
  11.523     // consider 'sfence' in the future, although it is not as compatible with older CPUs.
  11.524     inline static void  Store_Release(volatile O_T* p, O_T val)  { Exchange_Release(p, val); }
  11.525 #else
  11.526     inline static void  Store_Release(volatile O_T* p, O_T val)  { O_ReleaseSync sync; OVR_UNUSED(sync); *p = val; }
  11.527 #endif
  11.528     inline static O_T   Load_Acquire(const volatile O_T* p)      { O_AcquireSync sync; OVR_UNUSED(sync); return *p; }
  11.529 };
  11.530 
  11.531 
  11.532 template<int size>
  11.533 struct AtomicOpsRaw : public AtomicOpsRawBase { };
  11.534 
  11.535 template<>
  11.536 struct AtomicOpsRaw<4> : public AtomicOpsRaw_DefImpl<AtomicOpsRaw_4ByteImpl>
  11.537 {   
  11.538     // Ensure that assigned type size is correct.
  11.539     AtomicOpsRaw()
  11.540     { OVR_COMPILER_ASSERT(sizeof(AtomicOpsRaw_DefImpl<AtomicOpsRaw_4ByteImpl>::T) == 4); }
  11.541 };
  11.542 template<>
  11.543 struct AtomicOpsRaw<8> : public AtomicOpsRaw_DefImpl<AtomicOpsRaw_8ByteImpl>
  11.544 {
  11.545     AtomicOpsRaw()
  11.546     { OVR_COMPILER_ASSERT(sizeof(AtomicOpsRaw_DefImpl<AtomicOpsRaw_8ByteImpl>::T) == 8); }
  11.547 };
  11.548 
  11.549 
  11.550 // *** AtomicOps - implementation of atomic Ops for specified class
  11.551 
  11.552 // Implements atomic ops on a class, provided that the object is either
  11.553 // 4 or 8 bytes in size (depending on the AtomicOpsRaw specializations
  11.554 // available). Relies on AtomicOpsRaw for much of implementation.
  11.555 
  11.556 template<class C>
  11.557 class AtomicOps
  11.558 {
  11.559     typedef AtomicOpsRaw<sizeof(C)>       Ops;
  11.560     typedef typename Ops::T               T;
  11.561     typedef volatile typename Ops::T*     PT;
  11.562     // We cast through unions to (1) avoid pointer size compiler warnings
  11.563     // and (2) ensure that there are no problems with strict pointer aliasing.
  11.564     union C2T_union { C c; T t; };
  11.565 
  11.566 public:
  11.567     // General purpose implementation for standard syncs.    
  11.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; }
  11.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; }
  11.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; }
  11.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; }
  11.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; }
  11.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; }
  11.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; }
  11.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; }
  11.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); }
  11.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); }
  11.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); }
  11.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); }
  11.580     // Loads and stores with memory fence. These have only the relevant versions.    
  11.581     inline static void  Store_Release(volatile C* p, C val)             { C2T_union u; u.c = val; Ops::Store_Release((PT)p, u.t); }    
  11.582     inline static C     Load_Acquire(const volatile C* p)               { C2T_union u; u.t = Ops::Load_Acquire((PT)p); return u.c; }
  11.583 };
  11.584 
  11.585 
  11.586 
  11.587 // Atomic value base class - implements operations shared for integers and pointers.
  11.588 template<class T>
  11.589 class AtomicValueBase
  11.590 {
  11.591 protected:
  11.592     typedef AtomicOps<T> Ops;
  11.593 public:
  11.594 
  11.595     volatile T  Value;
  11.596 
  11.597     inline AtomicValueBase()                  { }
  11.598     explicit inline AtomicValueBase(T val)    { Ops::Store_Release(&Value, val); }
  11.599 
  11.600     // Most libraries (TBB and Joshua Scholar's) library do not do Load_Acquire
  11.601     // here, since most algorithms do not require atomic loads. Needs some research.    
  11.602     inline operator T() const { return Value; }
  11.603 
  11.604     // *** Standard Atomic inlines
  11.605     inline T     Exchange_Sync(T val)               { return Ops::Exchange_Sync(&Value,  val); }
  11.606     inline T     Exchange_Release(T val)            { return Ops::Exchange_Release(&Value, val); }
  11.607     inline T     Exchange_Acquire(T val)            { return Ops::Exchange_Acquire(&Value, val); }
  11.608     inline T     Exchange_NoSync(T val)             { return Ops::Exchange_NoSync(&Value, val); }
  11.609     inline bool  CompareAndSet_Sync(T c, T val)     { return Ops::CompareAndSet_Sync(&Value, c, val); }
  11.610     inline bool  CompareAndSet_Release(T c, T val)  { return Ops::CompareAndSet_Release(&Value, c, val); }
  11.611     inline bool  CompareAndSet_Acquire(T c, T val)  { return Ops::CompareAndSet_Relse(&Value, c, val); }
  11.612     inline bool  CompareAndSet_NoSync(T c, T val)   { return Ops::CompareAndSet_NoSync(&Value, c, val); }
  11.613     // Load & Store.
  11.614     inline void  Store_Release(T val)               { Ops::Store_Release(&Value, val); }
  11.615     inline T     Load_Acquire() const               { return Ops::Load_Acquire(&Value);  }
  11.616 };
  11.617 
  11.618 
  11.619 // ***** AtomicPtr - Atomic pointer template
  11.620 
  11.621 // This pointer class supports atomic assignments with release,
  11.622 // increment / decrement operations, and conditional compare + set.
  11.623 
  11.624 template<class T>
  11.625 class AtomicPtr : public AtomicValueBase<T*>
  11.626 {
  11.627     typedef typename AtomicValueBase<T*>::Ops Ops;
  11.628 
  11.629 public:
  11.630     // Initialize pointer value to 0 by default; use Store_Release only with explicit constructor.
  11.631     inline AtomicPtr() : AtomicValueBase<T*>()                     { this->Value = 0; }
  11.632     explicit inline AtomicPtr(T* val) : AtomicValueBase<T*>(val)   { }
  11.633         
  11.634     // Pointer access.
  11.635     inline T* operator -> () const     { return this->Load_Acquire(); }
  11.636 
  11.637     // It looks like it is convenient to have Load_Acquire characteristics
  11.638     // for this, since that is convenient for algorithms such as linked
  11.639     // list traversals that can be added to bu another thread.
  11.640     inline operator T* () const        { return this->Load_Acquire(); }
  11.641 
  11.642 
  11.643     // *** Standard Atomic inlines (applicable to pointers)
  11.644 
  11.645     // ExhangeAdd considers pointer size for pointers.
  11.646     template<class I>
  11.647     inline T*     ExchangeAdd_Sync(I incr)      { return Ops::ExchangeAdd_Sync(&this->Value, ((T*)0) + incr); }
  11.648     template<class I>
  11.649     inline T*     ExchangeAdd_Release(I incr)   { return Ops::ExchangeAdd_Release(&this->Value, ((T*)0) + incr); }
  11.650     template<class I>
  11.651     inline T*     ExchangeAdd_Acquire(I incr)   { return Ops::ExchangeAdd_Acquire(&this->Value, ((T*)0) + incr); }
  11.652     template<class I>
  11.653     inline T*     ExchangeAdd_NoSync(I incr)    { return Ops::ExchangeAdd_NoSync(&this->Value, ((T*)0) + incr); }
  11.654 
  11.655     // *** Atomic Operators
  11.656 
  11.657     inline T* operator = (T* val)  { this->Store_Release(val); return val; }
  11.658 
  11.659     template<class I>
  11.660     inline T* operator += (I val) { return ExchangeAdd_Sync(val) + val; }
  11.661     template<class I>
  11.662     inline T* operator -= (I val) { return operator += (-val); }
  11.663 
  11.664     inline T* operator ++ ()      { return ExchangeAdd_Sync(1) + 1; }
  11.665     inline T* operator -- ()      { return ExchangeAdd_Sync(-1) - 1; }
  11.666     inline T* operator ++ (int)   { return ExchangeAdd_Sync(1); }
  11.667     inline T* operator -- (int)   { return ExchangeAdd_Sync(-1); }
  11.668 };
  11.669 
  11.670 
  11.671 // ***** AtomicInt - Atomic integer template
  11.672 
  11.673 // Implements an atomic integer type; the exact type to use is provided 
  11.674 // as an argument. Supports atomic Acquire / Release semantics, atomic
  11.675 // arithmetic operations, and atomic conditional compare + set.
  11.676 
  11.677 template<class T>
  11.678 class AtomicInt : public AtomicValueBase<T>
  11.679 {
  11.680     typedef typename AtomicValueBase<T>::Ops Ops;
  11.681 
  11.682 public:
  11.683     inline AtomicInt() : AtomicValueBase<T>()                     { }
  11.684     explicit inline AtomicInt(T val) : AtomicValueBase<T>(val)    { }
  11.685 
  11.686 
  11.687     // *** Standard Atomic inlines (applicable to int)   
  11.688     inline T     ExchangeAdd_Sync(T val)            { return Ops::ExchangeAdd_Sync(&this->Value, val); }
  11.689     inline T     ExchangeAdd_Release(T val)         { return Ops::ExchangeAdd_Release(&this->Value, val); }
  11.690     inline T     ExchangeAdd_Acquire(T val)         { return Ops::ExchangeAdd_Acquire(&this->Value, val); }
  11.691     inline T     ExchangeAdd_NoSync(T val)          { return Ops::ExchangeAdd_NoSync(&this->Value, val); }
  11.692     // These increments could be more efficient because they don't return a value.
  11.693     inline void  Increment_Sync()                   { ExchangeAdd_Sync((T)1); }
  11.694     inline void  Increment_Release()                { ExchangeAdd_Release((T)1); }
  11.695     inline void  Increment_Acquire()                { ExchangeAdd_Acquire((T)1); }    
  11.696     inline void  Increment_NoSync()                 { ExchangeAdd_NoSync((T)1); }
  11.697 
  11.698     // *** Atomic Operators
  11.699 
  11.700     inline T operator = (T val)  { this->Store_Release(val); return val; }
  11.701     inline T operator += (T val) { return ExchangeAdd_Sync(val) + val; }
  11.702     inline T operator -= (T val) { return ExchangeAdd_Sync(0 - val) - val; }
  11.703 
  11.704     inline T operator ++ ()      { return ExchangeAdd_Sync((T)1) + 1; }
  11.705     inline T operator -- ()      { return ExchangeAdd_Sync(((T)0)-1) - 1; }
  11.706     inline T operator ++ (int)   { return ExchangeAdd_Sync((T)1); }
  11.707     inline T operator -- (int)   { return ExchangeAdd_Sync(((T)0)-1); }
  11.708 
  11.709     // More complex atomic operations. Leave it to compiler whether to optimize them or not.
  11.710     T operator &= (T arg)
  11.711     {
  11.712         T comp, newVal;
  11.713         do {
  11.714             comp   = this->Value;
  11.715             newVal = comp & arg;
  11.716         } while(!this->CompareAndSet_Sync(comp, newVal));
  11.717         return newVal;
  11.718     }
  11.719 
  11.720     T operator |= (T arg)
  11.721     {
  11.722         T comp, newVal;
  11.723         do {
  11.724             comp   = this->Value;
  11.725             newVal = comp | arg;
  11.726         } while(!this->CompareAndSet_Sync(comp, newVal));
  11.727         return newVal;
  11.728     }
  11.729 
  11.730     T operator ^= (T arg)
  11.731     {
  11.732         T comp, newVal;
  11.733         do {
  11.734             comp   = this->Value;
  11.735             newVal = comp ^ arg;
  11.736         } while(!this->CompareAndSet_Sync(comp, newVal));
  11.737         return newVal;
  11.738     }
  11.739 
  11.740     T operator *= (T arg)
  11.741     {
  11.742         T comp, newVal;
  11.743         do {
  11.744             comp   = this->Value;
  11.745             newVal = comp * arg;
  11.746         } while(!this->CompareAndSet_Sync(comp, newVal));
  11.747         return newVal;
  11.748     }
  11.749 
  11.750     T operator /= (T arg)
  11.751     {
  11.752         T comp, newVal;
  11.753         do {
  11.754             comp   = this->Value;
  11.755             newVal = comp / arg;
  11.756         } while(!CompareAndSet_Sync(comp, newVal));
  11.757         return newVal;
  11.758     }
  11.759 
  11.760     T operator >>= (unsigned bits)
  11.761     {
  11.762         T comp, newVal;
  11.763         do {
  11.764             comp   = this->Value;
  11.765             newVal = comp >> bits;
  11.766         } while(!CompareAndSet_Sync(comp, newVal));
  11.767         return newVal;
  11.768     }
  11.769 
  11.770     T operator <<= (unsigned bits)
  11.771     {
  11.772         T comp, newVal;
  11.773         do {
  11.774             comp   = this->Value;
  11.775             newVal = comp << bits;
  11.776         } while(!this->CompareAndSet_Sync(comp, newVal));
  11.777         return newVal;
  11.778     }
  11.779 };
  11.780 
  11.781 
  11.782 
  11.783 //-----------------------------------------------------------------------------------
  11.784 // ***** Lock
  11.785 
  11.786 // Lock is a simplest and most efficient mutual-exclusion lock class.
  11.787 // Unlike Mutex, it cannot be waited on.
  11.788 
  11.789 class Lock
  11.790 {
  11.791     // NOTE: Locks are not allocatable and they themselves should not allocate 
  11.792     // memory by standard means. This is the case because StandardAllocator
  11.793     // relies on this class.
  11.794     // Make 'delete' private. Don't do this for 'new' since it can be redefined.  
  11.795     void    operator delete(void*) {}
  11.796 
  11.797 
  11.798     // *** Lock implementation for various platforms.
  11.799     
  11.800 #if !defined(OVR_ENABLE_THREADS)
  11.801 
  11.802 public:
  11.803     // With no thread support, lock does nothing.
  11.804     inline Lock() { }
  11.805     inline Lock(unsigned) { }
  11.806     inline ~Lock() { }    
  11.807     inline void DoLock() { }
  11.808     inline void Unlock() { }
  11.809 
  11.810    // Windows.   
  11.811 #elif defined(OVR_OS_WIN32)
  11.812 
  11.813     CRITICAL_SECTION cs;
  11.814 public:   
  11.815     Lock(unsigned spinCount = 0);      
  11.816     ~Lock();
  11.817     // Locking functions.
  11.818     inline void DoLock()    { ::EnterCriticalSection(&cs); }
  11.819     inline void Unlock()    { ::LeaveCriticalSection(&cs); }
  11.820 
  11.821 #else
  11.822     pthread_mutex_t mutex;
  11.823 
  11.824 public:
  11.825     static pthread_mutexattr_t RecursiveAttr;
  11.826     static bool                RecursiveAttrInit;
  11.827 
  11.828     Lock (unsigned dummy = 0)
  11.829     {
  11.830         if (!RecursiveAttrInit)
  11.831         {
  11.832             pthread_mutexattr_init(&RecursiveAttr);
  11.833             pthread_mutexattr_settype(&RecursiveAttr, PTHREAD_MUTEX_RECURSIVE);
  11.834             RecursiveAttrInit = 1;
  11.835         }
  11.836         pthread_mutex_init(&mutex,&RecursiveAttr);
  11.837     }
  11.838     ~Lock ()                { pthread_mutex_destroy(&mutex); }
  11.839     inline void DoLock()    { pthread_mutex_lock(&mutex); }
  11.840     inline void Unlock()    { pthread_mutex_unlock(&mutex); }
  11.841 
  11.842 #endif // OVR_ENABLE_THREDS
  11.843 
  11.844 
  11.845 public:
  11.846     // Locker class, used for automatic locking
  11.847     class Locker
  11.848     {
  11.849     public:     
  11.850         Lock *pLock;
  11.851         inline Locker(Lock *plock)
  11.852         { pLock = plock; pLock->DoLock(); }
  11.853         inline ~Locker()
  11.854         { pLock->Unlock();  }
  11.855     };
  11.856 };
  11.857 
  11.858 
  11.859 
  11.860 } // OVR
  11.861 
  11.862 #endif
  11.863 \ No newline at end of file
    12.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    12.2 +++ b/libovr/Src/Kernel/OVR_Color.h	Sat Sep 14 16:14:59 2013 +0300
    12.3 @@ -0,0 +1,1 @@
    12.4 +/************************************************************************************
    12.5 
    12.6 PublicHeader:   OVR.h
    12.7 Filename    :   OVR_Color.h
    12.8 Content     :   Contains color struct.
    12.9 Created     :   February 7, 2013
   12.10 Notes       : 
   12.11 
   12.12 Copyright   :   Copyright 2013 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 #ifndef OVR_Color_h
   12.20 #define OVR_Color_h
   12.21 
   12.22 #include "OVR_Types.h"
   12.23 
   12.24 namespace OVR {
   12.25 
   12.26 struct Color
   12.27 {
   12.28     UByte R,G,B,A;
   12.29 
   12.30     Color() {}
   12.31 
   12.32     // Constructs color by channel. Alpha is set to 0xFF (fully visible)
   12.33     // if not specified.
   12.34     Color(unsigned char r,unsigned char g,unsigned char b, unsigned char a = 0xFF)
   12.35         : R(r), G(g), B(b), A(a) { }
   12.36 
   12.37     // 0xAARRGGBB - Common HTML color Hex layout
   12.38     Color(unsigned c)
   12.39         : R((unsigned char)(c>>16)), G((unsigned char)(c>>8)),
   12.40         B((unsigned char)c), A((unsigned char)(c>>24)) { }
   12.41 
   12.42     bool operator==(const Color& b) const
   12.43     {
   12.44         return R == b.R && G == b.G && B == b.B && A == b.A;
   12.45     }
   12.46 
   12.47     void  GetRGBA(float *r, float *g, float *b, float* a) const
   12.48     {
   12.49         *r = R / 255.0f;
   12.50         *g = G / 255.0f;
   12.51         *b = B / 255.0f;
   12.52         *a = A / 255.0f;
   12.53     }
   12.54 };
   12.55 
   12.56 }
   12.57 
   12.58 #endif
   12.59 \ No newline at end of file
    13.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    13.2 +++ b/libovr/Src/Kernel/OVR_ContainerAllocator.h	Sat Sep 14 16:14:59 2013 +0300
    13.3 @@ -0,0 +1,1 @@
    13.4 +/************************************************************************************
    13.5 
    13.6 PublicHeader:   OVR.h
    13.7 Filename    :   OVR_ContainerAllocator.h
    13.8 Content     :   Template allocators and constructors for containers.
    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_ContainerAllocator_h
   13.21 #define OVR_ContainerAllocator_h
   13.22 
   13.23 #include "OVR_Allocator.h"
   13.24 #include <string.h>
   13.25 
   13.26 
   13.27 namespace OVR {
   13.28 
   13.29 
   13.30 //-----------------------------------------------------------------------------------
   13.31 // ***** Container Allocator
   13.32 
   13.33 // ContainerAllocator serves as a template argument for allocations done by
   13.34 // containers, such as Array and Hash; replacing it could allow allocator
   13.35 // substitution in containers.
   13.36 
   13.37 class ContainerAllocatorBase
   13.38 {
   13.39 public:
   13.40     static void* Alloc(UPInt size)                { return OVR_ALLOC(size); }
   13.41     static void* Realloc(void* p, UPInt newSize)  { return OVR_REALLOC(p, newSize); }
   13.42     static void  Free(void *p)                    { OVR_FREE(p); }
   13.43 };
   13.44 
   13.45 
   13.46 
   13.47 //-----------------------------------------------------------------------------------
   13.48 // ***** Constructors, Destructors, Copiers
   13.49 
   13.50 // Plain Old Data - movable, no special constructors/destructor.
   13.51 template<class T> 
   13.52 class ConstructorPOD
   13.53 {
   13.54 public:
   13.55     static void Construct(void *) {}
   13.56     static void Construct(void *p, const T& source) 
   13.57     { 
   13.58         *(T*)p = source;
   13.59     }
   13.60 
   13.61     // Same as above, but allows for a different type of constructor.
   13.62     template <class S> 
   13.63     static void ConstructAlt(void *p, const S& source)
   13.64     {
   13.65         *(T*)p = source;
   13.66     }
   13.67 
   13.68     static void ConstructArray(void*, UPInt) {}
   13.69 
   13.70     static void ConstructArray(void* p, UPInt count, const T& source)
   13.71     {
   13.72         UByte *pdata = (UByte*)p;
   13.73         for (UPInt i=0; i< count; ++i, pdata += sizeof(T))
   13.74             *(T*)pdata = source;
   13.75     }
   13.76 
   13.77     static void ConstructArray(void* p, UPInt count, const T* psource)
   13.78     {
   13.79         memcpy(p, psource, sizeof(T) * count);
   13.80     }
   13.81 
   13.82     static void Destruct(T*) {}
   13.83     static void DestructArray(T*, UPInt) {}
   13.84 
   13.85     static void CopyArrayForward(T* dst, const T* src, UPInt count)
   13.86     {
   13.87         memmove(dst, src, count * sizeof(T));
   13.88     }
   13.89 
   13.90     static void CopyArrayBackward(T* dst, const T* src, UPInt count)
   13.91     {
   13.92         memmove(dst, src, count * sizeof(T));
   13.93     }
   13.94 
   13.95     static bool IsMovable() { return true; }
   13.96 };
   13.97 
   13.98 
   13.99 //-----------------------------------------------------------------------------------
  13.100 // ***** ConstructorMov
  13.101 //
  13.102 // Correct C++ construction and destruction for movable objects
  13.103 template<class T> 
  13.104 class ConstructorMov
  13.105 {
  13.106 public:
  13.107     static void Construct(void* p) 
  13.108     { 
  13.109         OVR::Construct<T>(p);
  13.110     }
  13.111 
  13.112     static void Construct(void* p, const T& source) 
  13.113     { 
  13.114         OVR::Construct<T>(p, source);
  13.115     }
  13.116 
  13.117     // Same as above, but allows for a different type of constructor.
  13.118     template <class S> 
  13.119     static void ConstructAlt(void* p, const S& source)
  13.120     {
  13.121         OVR::ConstructAlt<T,S>(p, source);
  13.122     }
  13.123 
  13.124     static void ConstructArray(void* p, UPInt count)
  13.125     {
  13.126         UByte* pdata = (UByte*)p;
  13.127         for (UPInt i=0; i< count; ++i, pdata += sizeof(T))
  13.128             Construct(pdata);
  13.129     }
  13.130 
  13.131     static void ConstructArray(void* p, UPInt count, const T& source)
  13.132     {
  13.133         UByte* pdata = (UByte*)p;
  13.134         for (UPInt i=0; i< count; ++i, pdata += sizeof(T))
  13.135             Construct(pdata, source);
  13.136     }
  13.137 
  13.138     static void ConstructArray(void* p, UPInt count, const T* psource)
  13.139     {
  13.140         UByte* pdata = (UByte*)p;
  13.141         for (UPInt i=0; i< count; ++i, pdata += sizeof(T))
  13.142             Construct(pdata, *psource++);
  13.143     }
  13.144 
  13.145     static void Destruct(T* p)
  13.146     {
  13.147         p->~T();
  13.148         OVR_UNUSED(p); // Suppress silly MSVC warning
  13.149     }
  13.150 
  13.151     static void DestructArray(T* p, UPInt count)
  13.152     {   
  13.153         p += count - 1;
  13.154         for (UPInt i=0; i<count; ++i, --p)
  13.155             p->~T();
  13.156     }
  13.157 
  13.158     static void CopyArrayForward(T* dst, const T* src, UPInt count)
  13.159     {
  13.160         memmove(dst, src, count * sizeof(T));
  13.161     }
  13.162 
  13.163     static void CopyArrayBackward(T* dst, const T* src, UPInt count)
  13.164     {
  13.165         memmove(dst, src, count * sizeof(T));
  13.166     }
  13.167 
  13.168     static bool IsMovable() { return true; }
  13.169 };
  13.170 
  13.171 
  13.172 //-----------------------------------------------------------------------------------
  13.173 // ***** ConstructorCPP
  13.174 //
  13.175 // Correct C++ construction and destruction for movable objects
  13.176 template<class T> 
  13.177 class ConstructorCPP
  13.178 {
  13.179 public:
  13.180     static void Construct(void* p) 
  13.181     { 
  13.182         OVR::Construct<T>(p);        
  13.183     }
  13.184 
  13.185     static void Construct(void* p, const T& source) 
  13.186     { 
  13.187         OVR::Construct<T>(p, source);        
  13.188     }
  13.189 
  13.190     // Same as above, but allows for a different type of constructor.
  13.191     template <class S> 
  13.192     static void ConstructAlt(void* p, const S& source)
  13.193     {
  13.194         OVR::ConstructAlt<T,S>(p, source);        
  13.195     }
  13.196 
  13.197     static void ConstructArray(void* p, UPInt count)
  13.198     {
  13.199         UByte* pdata = (UByte*)p;
  13.200         for (UPInt i=0; i< count; ++i, pdata += sizeof(T))
  13.201             Construct(pdata);
  13.202     }
  13.203 
  13.204     static void ConstructArray(void* p, UPInt count, const T& source)
  13.205     {
  13.206         UByte* pdata = (UByte*)p;
  13.207         for (UPInt i=0; i< count; ++i, pdata += sizeof(T))
  13.208             Construct(pdata, source);
  13.209     }
  13.210 
  13.211     static void ConstructArray(void* p, UPInt count, const T* psource)
  13.212     {
  13.213         UByte* pdata = (UByte*)p;
  13.214         for (UPInt i=0; i< count; ++i, pdata += sizeof(T))
  13.215             Construct(pdata, *psource++);
  13.216     }
  13.217 
  13.218     static void Destruct(T* p)
  13.219     {
  13.220         p->~T();
  13.221         OVR_UNUSED(p); // Suppress silly MSVC warning
  13.222     }
  13.223 
  13.224     static void DestructArray(T* p, UPInt count)
  13.225     {   
  13.226         p += count - 1;
  13.227         for (UPInt i=0; i<count; ++i, --p)
  13.228             p->~T();
  13.229     }
  13.230 
  13.231     static void CopyArrayForward(T* dst, const T* src, UPInt count)
  13.232     {
  13.233         for(UPInt i = 0; i < count; ++i)
  13.234             dst[i] = src[i];
  13.235     }
  13.236 
  13.237     static void CopyArrayBackward(T* dst, const T* src, UPInt count)
  13.238     {
  13.239         for(UPInt i = count; i; --i)
  13.240             dst[i-1] = src[i-1];
  13.241     }
  13.242 
  13.243     static bool IsMovable() { return false; }
  13.244 };
  13.245 
  13.246 
  13.247 //-----------------------------------------------------------------------------------
  13.248 // ***** Container Allocator with movement policy
  13.249 //
  13.250 // Simple wraps as specialized allocators
  13.251 template<class T> struct ContainerAllocator_POD : ContainerAllocatorBase, ConstructorPOD<T> {};
  13.252 template<class T> struct ContainerAllocator     : ContainerAllocatorBase, ConstructorMov<T> {};
  13.253 template<class T> struct ContainerAllocator_CPP : ContainerAllocatorBase, ConstructorCPP<T> {};
  13.254 
  13.255 
  13.256 } // OVR
  13.257 
  13.258 
  13.259 #endif
  13.260 \ No newline at end of file
    14.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    14.2 +++ b/libovr/Src/Kernel/OVR_File.cpp	Sat Sep 14 16:14:59 2013 +0300
    14.3 @@ -0,0 +1,1 @@
    14.4 +/**************************************************************************
    14.5 
    14.6 Filename    :   OVR_File.cpp
    14.7 Content     :   File wrapper class implementation (Win32)
    14.8 
    14.9 Created     :   April 5, 1999
   14.10 Authors     :   Michael Antonov
   14.11 
   14.12 Copyright   :   Copyright 2012 Oculus VR, Inc. All Rights reserved.
   14.13 
   14.14 Use of this software is subject to the terms of the Oculus license
   14.15 agreement provided at the time of installation or download, or which
   14.16 otherwise accompanies this software in either electronic or hard copy form.
   14.17 
   14.18 **************************************************************************/
   14.19 
   14.20 #define  GFILE_CXX
   14.21 
   14.22 // Standard C library (Captain Obvious guarantees!)
   14.23 #include <stdio.h>
   14.24 
   14.25 #include "OVR_File.h"
   14.26 
   14.27 namespace OVR {
   14.28 
   14.29 // Buffered file adds buffering to an existing file
   14.30 // FILEBUFFER_SIZE defines the size of internal buffer, while
   14.31 // FILEBUFFER_TOLERANCE controls the amount of data we'll effectively try to buffer
   14.32 #define FILEBUFFER_SIZE         (8192-8)
   14.33 #define FILEBUFFER_TOLERANCE    4096
   14.34 
   14.35 // ** Constructor/Destructor
   14.36 
   14.37 // Hidden constructor
   14.38 // Not supposed to be used
   14.39 BufferedFile::BufferedFile() : DelegatedFile(0)
   14.40 {
   14.41     pBuffer     = (UByte*)OVR_ALLOC(FILEBUFFER_SIZE);
   14.42     BufferMode  = NoBuffer;
   14.43     FilePos     = 0;
   14.44     Pos         = 0;
   14.45     DataSize    = 0;
   14.46 }
   14.47 
   14.48 // Takes another file as source
   14.49 BufferedFile::BufferedFile(File *pfile) : DelegatedFile(pfile)
   14.50 {
   14.51     pBuffer     = (UByte*)OVR_ALLOC(FILEBUFFER_SIZE);
   14.52     BufferMode  = NoBuffer;
   14.53     FilePos     = pfile->LTell();
   14.54     Pos         = 0;
   14.55     DataSize    = 0;
   14.56 }
   14.57 
   14.58 
   14.59 // Destructor
   14.60 BufferedFile::~BufferedFile()
   14.61 {
   14.62     // Flush in case there's data
   14.63     if (pFile)
   14.64         FlushBuffer();
   14.65     // Get rid of buffer
   14.66     if (pBuffer)
   14.67         OVR_FREE(pBuffer);
   14.68 }
   14.69 
   14.70 /*
   14.71 bool    BufferedFile::VCopy(const Object &source)
   14.72 {
   14.73     if (!DelegatedFile::VCopy(source))
   14.74         return 0;
   14.75 
   14.76     // Data members
   14.77     BufferedFile *psource = (BufferedFile*)&source;
   14.78 
   14.79     // Buffer & the mode it's in
   14.80     pBuffer         = psource->pBuffer;
   14.81     BufferMode      = psource->BufferMode;
   14.82     Pos             = psource->Pos;
   14.83     DataSize        = psource->DataSize;
   14.84     return 1;
   14.85 }
   14.86 */
   14.87 
   14.88 // Initializes buffering to a certain mode
   14.89 bool    BufferedFile::SetBufferMode(BufferModeType mode)
   14.90 {
   14.91     if (!pBuffer)
   14.92         return false;
   14.93     if (mode == BufferMode)
   14.94         return true;
   14.95      
   14.96     FlushBuffer();
   14.97 
   14.98     // Can't set write mode if we can't write
   14.99     if ((mode==WriteBuffer) && (!pFile || !pFile->IsWritable()) )
  14.100         return 0;
  14.101 
  14.102     // And SetMode
  14.103     BufferMode = mode;
  14.104     Pos        = 0;
  14.105     DataSize   = 0;
  14.106     return 1;
  14.107 }
  14.108 
  14.109 // Flushes buffer
  14.110 void    BufferedFile::FlushBuffer()
  14.111 {
  14.112     switch(BufferMode)
  14.113     {
  14.114         case WriteBuffer:
  14.115             // Write data in buffer
  14.116             FilePos += pFile->Write(pBuffer,Pos);
  14.117             Pos = 0;
  14.118             break;
  14.119 
  14.120         case ReadBuffer:
  14.121             // Seek back & reset buffer data
  14.122             if ((DataSize-Pos)>0)
  14.123                 FilePos = pFile->LSeek(-(int)(DataSize-Pos), Seek_Cur);
  14.124             DataSize = 0;
  14.125             Pos      = 0;
  14.126             break;
  14.127         default:
  14.128             // not handled!
  14.129             break;
  14.130     }
  14.131 }
  14.132 
  14.133 // Reloads data for ReadBuffer
  14.134 void    BufferedFile::LoadBuffer()
  14.135 {
  14.136     if (BufferMode == ReadBuffer)
  14.137     {
  14.138         // We should only reload once all of pre-loaded buffer is consumed.
  14.139         OVR_ASSERT(Pos == DataSize);
  14.140 
  14.141         // WARNING: Right now LoadBuffer() assumes the buffer's empty
  14.142         int sz   = pFile->Read(pBuffer,FILEBUFFER_SIZE);
  14.143         DataSize = sz<0 ? 0 : (unsigned)sz;
  14.144         Pos      = 0;
  14.145         FilePos  += DataSize;
  14.146     }
  14.147 }
  14.148 
  14.149 
  14.150 // ** Overridden functions
  14.151 
  14.152 // We override all the functions that can possibly
  14.153 // require buffer mode switch, flush, or extra calculations
  14.154 
  14.155 // Tell() requires buffer adjustment
  14.156 int     BufferedFile::Tell()
  14.157 {
  14.158     if (BufferMode == ReadBuffer)
  14.159         return int (FilePos - DataSize + Pos);
  14.160 
  14.161     int pos = pFile->Tell();
  14.162     // Adjust position based on buffer mode & data
  14.163     if (pos!=-1)
  14.164     {
  14.165         OVR_ASSERT(BufferMode != ReadBuffer);
  14.166         if (BufferMode == WriteBuffer)
  14.167             pos += Pos;
  14.168     }
  14.169     return pos;
  14.170 }
  14.171 
  14.172 SInt64  BufferedFile::LTell()
  14.173 {
  14.174     if (BufferMode == ReadBuffer)
  14.175         return FilePos - DataSize + Pos;
  14.176 
  14.177     SInt64 pos = pFile->LTell();
  14.178     if (pos!=-1)
  14.179     {
  14.180         OVR_ASSERT(BufferMode != ReadBuffer);
  14.181         if (BufferMode == WriteBuffer)
  14.182             pos += Pos;
  14.183     }
  14.184     return pos;
  14.185 }
  14.186 
  14.187 int     BufferedFile::GetLength()
  14.188 {
  14.189     int len = pFile->GetLength();
  14.190     // If writing through buffer, file length may actually be bigger
  14.191     if ((len!=-1) && (BufferMode==WriteBuffer))
  14.192     {
  14.193         int currPos = pFile->Tell() + Pos;
  14.194         if (currPos>len)
  14.195             len = currPos;
  14.196     }
  14.197     return len;
  14.198 }
  14.199 SInt64  BufferedFile::LGetLength()
  14.200 {
  14.201     SInt64 len = pFile->LGetLength();
  14.202     // If writing through buffer, file length may actually be bigger
  14.203     if ((len!=-1) && (BufferMode==WriteBuffer))
  14.204     {
  14.205         SInt64 currPos = pFile->LTell() + Pos;
  14.206         if (currPos>len)
  14.207             len = currPos;
  14.208     }
  14.209     return len;
  14.210 }
  14.211 
  14.212 /*
  14.213 bool    BufferedFile::Stat(FileStats *pfs)
  14.214 {
  14.215     // Have to fix up length is stat
  14.216     if (pFile->Stat(pfs))
  14.217     {
  14.218         if (BufferMode==WriteBuffer)
  14.219         {
  14.220             SInt64 currPos = pFile->LTell() + Pos;
  14.221             if (currPos > pfs->Size)
  14.222             {
  14.223                 pfs->Size   = currPos;
  14.224                 // ??
  14.225                 pfs->Blocks = (pfs->Size+511) >> 9;
  14.226             }
  14.227         }
  14.228         return 1;
  14.229     }
  14.230     return 0;
  14.231 }
  14.232 */
  14.233 
  14.234 int     BufferedFile::Write(const UByte *psourceBuffer, int numBytes)
  14.235 {
  14.236     if ( (BufferMode==WriteBuffer) || SetBufferMode(WriteBuffer))
  14.237     {
  14.238         // If not data space in buffer, flush
  14.239         if ((FILEBUFFER_SIZE-(int)Pos)<numBytes)
  14.240         {
  14.241             FlushBuffer();
  14.242             // If bigger then tolerance, just write directly
  14.243             if (numBytes>FILEBUFFER_TOLERANCE)
  14.244             {
  14.245                 int sz = pFile->Write(psourceBuffer,numBytes);
  14.246                 if (sz > 0)
  14.247                     FilePos += sz;
  14.248                 return sz;
  14.249             }
  14.250         }
  14.251 
  14.252         // Enough space in buffer.. so copy to it
  14.253         memcpy(pBuffer+Pos, psourceBuffer, numBytes);
  14.254         Pos += numBytes;
  14.255         return numBytes;
  14.256     }
  14.257     int sz = pFile->Write(psourceBuffer,numBytes);
  14.258     if (sz > 0)
  14.259         FilePos += sz;
  14.260     return sz;
  14.261 }
  14.262 
  14.263 int     BufferedFile::Read(UByte *pdestBuffer, int numBytes)
  14.264 {
  14.265     if ( (BufferMode==ReadBuffer) || SetBufferMode(ReadBuffer))
  14.266     {
  14.267         // Data in buffer... copy it
  14.268         if ((int)(DataSize-Pos) >= numBytes)
  14.269         {
  14.270             memcpy(pdestBuffer, pBuffer+Pos, numBytes);
  14.271             Pos += numBytes;
  14.272             return numBytes;
  14.273         }
  14.274 
  14.275         // Not enough data in buffer, copy buffer
  14.276         int     readBytes = DataSize-Pos;
  14.277         memcpy(pdestBuffer, pBuffer+Pos, readBytes);
  14.278         numBytes    -= readBytes;
  14.279         pdestBuffer += readBytes;
  14.280         Pos = DataSize;
  14.281 
  14.282         // Don't reload buffer if more then tolerance
  14.283         // (No major advantage, and we don't want to write a loop)
  14.284         if (numBytes>FILEBUFFER_TOLERANCE)
  14.285         {
  14.286             numBytes = pFile->Read(pdestBuffer,numBytes);
  14.287             if (numBytes > 0)
  14.288             {
  14.289                 FilePos += numBytes;
  14.290                 Pos = DataSize = 0;
  14.291             }
  14.292             return readBytes + ((numBytes==-1) ? 0 : numBytes);
  14.293         }
  14.294 
  14.295         // Reload the buffer
  14.296         // WARNING: Right now LoadBuffer() assumes the buffer's empty
  14.297         LoadBuffer();
  14.298         if ((int)(DataSize-Pos) < numBytes)
  14.299             numBytes = (int)DataSize-Pos;
  14.300 
  14.301         memcpy(pdestBuffer, pBuffer+Pos, numBytes);
  14.302         Pos += numBytes;
  14.303         return numBytes + readBytes;
  14.304         
  14.305         /*
  14.306         // Alternative Read implementation. The one above is probably better
  14.307         // due to FILEBUFFER_TOLERANCE.
  14.308         int     total = 0;
  14.309 
  14.310         do {
  14.311             int     bufferBytes = (int)(DataSize-Pos);
  14.312             int     copyBytes = (bufferBytes > numBytes) ? numBytes : bufferBytes;
  14.313 
  14.314             memcpy(pdestBuffer, pBuffer+Pos, copyBytes);
  14.315             numBytes    -= copyBytes;
  14.316             pdestBuffer += copyBytes;
  14.317             Pos         += copyBytes;
  14.318             total       += copyBytes;
  14.319 
  14.320             if (numBytes == 0)
  14.321                 break;
  14.322             LoadBuffer();
  14.323 
  14.324         } while (DataSize > 0);
  14.325 
  14.326         return total;
  14.327         */     
  14.328     }
  14.329     int sz = pFile->Read(pdestBuffer,numBytes);
  14.330     if (sz > 0)
  14.331         FilePos += sz;
  14.332     return sz;
  14.333 }
  14.334 
  14.335 
  14.336 int     BufferedFile::SkipBytes(int numBytes)
  14.337 {
  14.338     int skippedBytes = 0;
  14.339 
  14.340     // Special case for skipping a little data in read buffer
  14.341     if (BufferMode==ReadBuffer)
  14.342     {
  14.343         skippedBytes = (((int)DataSize-(int)Pos) >= numBytes) ? numBytes : (DataSize-Pos);
  14.344         Pos          += skippedBytes;
  14.345         numBytes     -= skippedBytes;
  14.346     }
  14.347 
  14.348     if (numBytes)
  14.349     {
  14.350         numBytes = pFile->SkipBytes(numBytes);
  14.351         // Make sure we return the actual number skipped, or error
  14.352         if (numBytes!=-1)
  14.353         {
  14.354             skippedBytes += numBytes;
  14.355             FilePos += numBytes;
  14.356             Pos = DataSize = 0;
  14.357         }
  14.358         else if (skippedBytes <= 0)
  14.359             skippedBytes = -1;
  14.360     }
  14.361     return skippedBytes;
  14.362 }
  14.363 
  14.364 int     BufferedFile::BytesAvailable()
  14.365 {
  14.366     int available = pFile->BytesAvailable();
  14.367     // Adjust available size based on buffers
  14.368     switch(BufferMode)
  14.369     {
  14.370         case ReadBuffer:
  14.371             available += DataSize-Pos;
  14.372             break;
  14.373         case WriteBuffer:
  14.374             available -= Pos;
  14.375             if (available<0)
  14.376                 available= 0;
  14.377             break;
  14.378         default:
  14.379             break;
  14.380     }
  14.381     return available;
  14.382 }
  14.383 
  14.384 bool    BufferedFile::Flush()
  14.385 {
  14.386     FlushBuffer();
  14.387     return pFile->Flush();
  14.388 }
  14.389 
  14.390 // Seeking could be optimized better..
  14.391 int     BufferedFile::Seek(int offset, int origin)
  14.392 {    
  14.393     if (BufferMode == ReadBuffer)
  14.394     {
  14.395         if (origin == Seek_Cur)
  14.396         {
  14.397             // Seek can fall either before or after Pos in the buffer,
  14.398             // but it must be within bounds.
  14.399             if (((unsigned(offset) + Pos)) <= DataSize)
  14.400             {
  14.401                 Pos += offset;
  14.402                 return int (FilePos - DataSize + Pos);
  14.403             }
  14.404 
  14.405             // Lightweight buffer "Flush". We do this to avoid an extra seek
  14.406             // back operation which would take place if we called FlushBuffer directly.
  14.407             origin = Seek_Set;
  14.408             OVR_ASSERT(((FilePos - DataSize + Pos) + (UInt64)offset) < ~(UInt64)0);
  14.409             offset = (int)(FilePos - DataSize + Pos) + offset;
  14.410             Pos = DataSize = 0;
  14.411         }
  14.412         else if (origin == Seek_Set)
  14.413         {
  14.414             if (((unsigned)offset - (FilePos-DataSize)) <= DataSize)
  14.415             {
  14.416                 OVR_ASSERT((FilePos-DataSize) < ~(UInt64)0);
  14.417                 Pos = (unsigned)offset - (unsigned)(FilePos-DataSize);
  14.418                 return offset;
  14.419             }
  14.420             Pos = DataSize = 0;
  14.421         }
  14.422         else
  14.423         {
  14.424             FlushBuffer();
  14.425         }
  14.426     }
  14.427     else
  14.428     {
  14.429         FlushBuffer();
  14.430     }    
  14.431 
  14.432     /*
  14.433     // Old Seek Logic
  14.434     if (origin == Seek_Cur && offset + Pos < DataSize)
  14.435     {
  14.436         //OVR_ASSERT((FilePos - DataSize) >= (FilePos - DataSize + Pos + offset));
  14.437         Pos += offset;
  14.438         OVR_ASSERT(int (Pos) >= 0);
  14.439         return int (FilePos - DataSize + Pos);
  14.440     }
  14.441     else if (origin == Seek_Set && unsigned(offset) >= FilePos - DataSize && unsigned(offset) < FilePos)
  14.442     {
  14.443         Pos = unsigned(offset - FilePos + DataSize);
  14.444         OVR_ASSERT(int (Pos) >= 0);
  14.445         return int (FilePos - DataSize + Pos);
  14.446     }   
  14.447     
  14.448     FlushBuffer();
  14.449     */
  14.450 
  14.451 
  14.452     FilePos = pFile->Seek(offset,origin);
  14.453     return int (FilePos);
  14.454 }
  14.455 
  14.456 SInt64  BufferedFile::LSeek(SInt64 offset, int origin)
  14.457 {
  14.458     if (BufferMode == ReadBuffer)
  14.459     {
  14.460         if (origin == Seek_Cur)
  14.461         {
  14.462             // Seek can fall either before or after Pos in the buffer,
  14.463             // but it must be within bounds.
  14.464             if (((unsigned(offset) + Pos)) <= DataSize)
  14.465             {
  14.466                 Pos += (unsigned)offset;
  14.467                 return SInt64(FilePos - DataSize + Pos);
  14.468             }
  14.469 
  14.470             // Lightweight buffer "Flush". We do this to avoid an extra seek
  14.471             // back operation which would take place if we called FlushBuffer directly.
  14.472             origin = Seek_Set;            
  14.473             offset = (SInt64)(FilePos - DataSize + Pos) + offset;
  14.474             Pos = DataSize = 0;
  14.475         }
  14.476         else if (origin == Seek_Set)
  14.477         {
  14.478             if (((UInt64)offset - (FilePos-DataSize)) <= DataSize)
  14.479             {                
  14.480                 Pos = (unsigned)((UInt64)offset - (FilePos-DataSize));
  14.481                 return offset;
  14.482             }
  14.483             Pos = DataSize = 0;
  14.484         }
  14.485         else
  14.486         {
  14.487             FlushBuffer();
  14.488         }
  14.489     }
  14.490     else
  14.491     {
  14.492         FlushBuffer();
  14.493     }
  14.494 
  14.495 /*
  14.496     OVR_ASSERT(BufferMode != NoBuffer);
  14.497 
  14.498     if (origin == Seek_Cur && offset + Pos < DataSize)
  14.499     {
  14.500         Pos += int (offset);
  14.501         return FilePos - DataSize + Pos;
  14.502     }
  14.503     else if (origin == Seek_Set && offset >= SInt64(FilePos - DataSize) && offset < SInt64(FilePos))
  14.504     {
  14.505         Pos = unsigned(offset - FilePos + DataSize);
  14.506         return FilePos - DataSize + Pos;
  14.507     }
  14.508 
  14.509     FlushBuffer();
  14.510     */
  14.511 
  14.512     FilePos = pFile->LSeek(offset,origin);
  14.513     return FilePos;
  14.514 }
  14.515 
  14.516 int     BufferedFile::CopyFromStream(File *pstream, int byteSize)
  14.517 {
  14.518     // We can't rely on overridden Write()
  14.519     // because delegation doesn't override virtual pointers
  14.520     // So, just re-implement
  14.521     UByte   buff[0x4000];
  14.522     int     count = 0;
  14.523     int     szRequest, szRead, szWritten;
  14.524 
  14.525     while(byteSize)
  14.526     {
  14.527         szRequest = (byteSize > int(sizeof(buff))) ? int(sizeof(buff)) : byteSize;
  14.528 
  14.529         szRead    = pstream->Read(buff,szRequest);
  14.530         szWritten = 0;
  14.531         if (szRead > 0)
  14.532             szWritten = Write(buff,szRead);
  14.533 
  14.534         count   +=szWritten;
  14.535         byteSize-=szWritten;
  14.536         if (szWritten < szRequest)
  14.537             break;
  14.538     }
  14.539     return count;
  14.540 }
  14.541 
  14.542 // Closing files
  14.543 bool    BufferedFile::Close()
  14.544 {
  14.545     switch(BufferMode)
  14.546     {
  14.547         case WriteBuffer:
  14.548             FlushBuffer();
  14.549             break;
  14.550         case ReadBuffer:
  14.551             // No need to seek back on close
  14.552             BufferMode = NoBuffer;
  14.553             break;
  14.554         default:
  14.555             break;
  14.556     }
  14.557     return pFile->Close();
  14.558 }
  14.559 
  14.560 
  14.561 // ***** Global path helpers
  14.562 
  14.563 // Find trailing short filename in a path.
  14.564 const char* OVR_CDECL GetShortFilename(const char* purl)
  14.565 {    
  14.566     UPInt len = OVR_strlen(purl);
  14.567     for (UPInt i=len; i>0; i--) 
  14.568         if (purl[i]=='\\' || purl[i]=='/')
  14.569             return purl+i+1;
  14.570     return purl;
  14.571 }
  14.572 
  14.573 } // OVR
  14.574 
  14.575 \ No newline at end of file
    15.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    15.2 +++ b/libovr/Src/Kernel/OVR_File.h	Sat Sep 14 16:14:59 2013 +0300
    15.3 @@ -0,0 +1,1 @@
    15.4 +/************************************************************************************
    15.5 
    15.6 PublicHeader:   Kernel
    15.7 Filename    :   OVR_File.h
    15.8 Content     :   Header for all internal file management - functions and structures
    15.9                 to be inherited by OS specific subclasses.
   15.10 Created     :   September 19, 2012
   15.11 Notes       : 
   15.12 
   15.13 Notes       :   errno may not be preserved across use of BaseFile member functions
   15.14             :   Directories cannot be deleted while files opened from them are in use
   15.15                 (For the GetFullName function)
   15.16 
   15.17 Copyright   :   Copyright 2012 Oculus VR, Inc. All Rights reserved.
   15.18 
   15.19 Use of this software is subject to the terms of the Oculus license
   15.20 agreement provided at the time of installation or download, or which
   15.21 otherwise accompanies this software in either electronic or hard copy form.
   15.22 
   15.23 ************************************************************************************/
   15.24 
   15.25 #ifndef OVR_File_h
   15.26 #define OVR_File_h
   15.27 
   15.28 #include "OVR_RefCount.h"
   15.29 #include "OVR_Std.h"
   15.30 #include "OVR_Alg.h"
   15.31 
   15.32 #include <stdio.h>
   15.33 #include "OVR_String.h"
   15.34 
   15.35 namespace OVR {
   15.36 
   15.37 // ***** Declared classes
   15.38 class   FileConstants;
   15.39 class   File;
   15.40 class   DelegatedFile;
   15.41 class   BufferedFile;
   15.42 
   15.43 
   15.44 // ***** Flags for File & Directory accesses
   15.45 
   15.46 class FileConstants
   15.47 {
   15.48 public:
   15.49 
   15.50     // *** File open flags
   15.51     enum OpenFlags
   15.52     {
   15.53         Open_Read       = 1,
   15.54         Open_Write      = 2,
   15.55         Open_ReadWrite  = 3,
   15.56 
   15.57         // Opens file and truncates it to zero length
   15.58         // - file must have write permission
   15.59         // - when used with Create, it opens an existing 
   15.60         //   file and empties it or creates a new file
   15.61         Open_Truncate   = 4,
   15.62 
   15.63         // Creates and opens new file 
   15.64         // - does not erase contents if file already
   15.65         //   exists unless combined with Truncate
   15.66         Open_Create     = 8,
   15.67 
   15.68          // Returns an error value if the file already exists
   15.69         Open_CreateOnly = 24,
   15.70 
   15.71         // Open file with buffering
   15.72         Open_Buffered    = 32
   15.73     };
   15.74 
   15.75     // *** File Mode flags
   15.76     enum Modes
   15.77     {
   15.78         Mode_Read       = 0444,
   15.79         Mode_Write      = 0222,
   15.80         Mode_Execute    = 0111,
   15.81 
   15.82         Mode_ReadWrite  = 0666
   15.83     };
   15.84 
   15.85     // *** Seek operations
   15.86     enum SeekOps
   15.87     {
   15.88         Seek_Set        = 0,
   15.89         Seek_Cur        = 1,
   15.90         Seek_End        = 2
   15.91     };
   15.92 
   15.93     // *** Errors
   15.94     enum Errors
   15.95     {
   15.96         Error_FileNotFound  = 0x1001,
   15.97         Error_Access        = 0x1002,
   15.98         Error_IOError       = 0x1003,
   15.99         Error_DiskFull      = 0x1004
  15.100     };
  15.101 };
  15.102 
  15.103 
  15.104 //-----------------------------------------------------------------------------------
  15.105 // ***** File Class
  15.106 
  15.107 // The pure virtual base random-access file
  15.108 // This is a base class to all files
  15.109 
  15.110 class File : public RefCountBase<File>, public FileConstants
  15.111 {   
  15.112 public:
  15.113     File() { }
  15.114     // ** Location Information
  15.115 
  15.116     // Returns a file name path relative to the 'reference' directory
  15.117     // This is often a path that was used to create a file
  15.118     // (this is not a global path, global path can be obtained with help of directory)
  15.119     virtual const char* GetFilePath() = 0;
  15.120                                                                                         
  15.121 
  15.122     // ** File Information
  15.123 
  15.124     // Return 1 if file's usable (open)
  15.125     virtual bool        IsValid() = 0;
  15.126     // Return 1 if file's writable, otherwise 0                                         
  15.127     virtual bool        IsWritable() = 0;
  15.128                                                                                         
  15.129     // Return position
  15.130     virtual int         Tell() = 0;
  15.131     virtual SInt64      LTell() = 0;
  15.132     
  15.133     // File size                                                                        
  15.134     virtual int         GetLength() = 0;
  15.135     virtual SInt64      LGetLength() = 0;
  15.136                                                                                         
  15.137     // Returns file stats                                                               
  15.138     // 0 for failure                                                                    
  15.139     //virtual bool      Stat(FileStats *pfs) = 0;
  15.140                                                                                         
  15.141     // Return errno-based error code                                                    
  15.142     // Useful if any other function failed                                              
  15.143     virtual int         GetErrorCode() = 0;
  15.144                                                                                         
  15.145                                                                                         
  15.146     // ** Stream implementation & I/O
  15.147 
  15.148     // Blocking write, will write in the given number of bytes to the stream
  15.149     // Returns : -1 for error
  15.150     //           Otherwise number of bytes read 
  15.151     virtual int         Write(const UByte *pbufer, int numBytes) = 0;
  15.152     // Blocking read, will read in the given number of bytes or less from the stream
  15.153     // Returns : -1 for error
  15.154     //           Otherwise number of bytes read,
  15.155     //           if 0 or < numBytes, no more bytes available; end of file or the other side of stream is closed
  15.156     virtual int         Read(UByte *pbufer, int numBytes) = 0;
  15.157 
  15.158     // Skips (ignores) a given # of bytes
  15.159     // Same return values as Read
  15.160     virtual int         SkipBytes(int numBytes) = 0;
  15.161         
  15.162     // Returns the number of bytes available to read from a stream without blocking
  15.163     // For a file, this should generally be number of bytes to the end
  15.164     virtual int         BytesAvailable() = 0;
  15.165 
  15.166     // Causes any implementation's buffered data to be delivered to destination
  15.167     // Return 0 for error
  15.168     virtual bool        Flush() = 0;
  15.169                                                                                             
  15.170 
  15.171     // Need to provide a more optimized implementation that doe snot necessarily involve a lot of seeking
  15.172     inline bool         IsEOF() { return !BytesAvailable(); }
  15.173     
  15.174 
  15.175     // Seeking                                                                              
  15.176     // Returns new position, -1 for error                                                   
  15.177     virtual int         Seek(int offset, int origin=Seek_Set) = 0;
  15.178     virtual SInt64      LSeek(SInt64 offset, int origin=Seek_Set) = 0;
  15.179     // Seek simplification
  15.180     int                 SeekToBegin()           {return Seek(0); }
  15.181     int                 SeekToEnd()             {return Seek(0,Seek_End); }
  15.182     int                 Skip(int numBytes)     {return Seek(numBytes,Seek_Cur); }
  15.183                         
  15.184 
  15.185     // Appends other file data from a stream
  15.186     // Return -1 for error, else # of bytes written
  15.187     virtual int         CopyFromStream(File *pstream, int byteSize) = 0;
  15.188 
  15.189     // Closes the file
  15.190     // After close, file cannot be accessed 
  15.191     virtual bool        Close() = 0;
  15.192 
  15.193 
  15.194     // ***** Inlines for convenient primitive type serialization
  15.195 
  15.196     // Read/Write helpers
  15.197 private:
  15.198     UInt64  PRead64()           { UInt64 v = 0; Read((UByte*)&v, 8); return v; }
  15.199     UInt32  PRead32()           { UInt32 v = 0; Read((UByte*)&v, 4); return v; }
  15.200     UInt16  PRead16()           { UInt16 v = 0; Read((UByte*)&v, 2); return v; }
  15.201     UByte   PRead8()            { UByte  v = 0; Read((UByte*)&v, 1); return v; }
  15.202     void    PWrite64(UInt64 v)  { Write((UByte*)&v, 8); }
  15.203     void    PWrite32(UInt32 v)  { Write((UByte*)&v, 4); }
  15.204     void    PWrite16(UInt16 v)  { Write((UByte*)&v, 2); }
  15.205     void    PWrite8(UByte v)    { Write((UByte*)&v, 1); }
  15.206 
  15.207 public:
  15.208 
  15.209     // Writing primitive types - Little Endian
  15.210     inline void    WriteUByte(UByte v)         { PWrite8((UByte)Alg::ByteUtil::SystemToLE(v));     }
  15.211     inline void    WriteSByte(SByte v)         { PWrite8((UByte)Alg::ByteUtil::SystemToLE(v));     }
  15.212     inline void    WriteUInt8(UByte v)         { PWrite8((UByte)Alg::ByteUtil::SystemToLE(v));     }
  15.213     inline void    WriteSInt8(SByte v)         { PWrite8((UByte)Alg::ByteUtil::SystemToLE(v));     }
  15.214     inline void    WriteUInt16(UInt16 v)       { PWrite16((UInt16)Alg::ByteUtil::SystemToLE(v));   }
  15.215     inline void    WriteSInt16(SInt16 v)       { PWrite16((UInt16)Alg::ByteUtil::SystemToLE(v));   }
  15.216     inline void    WriteUInt32(UInt32 v)       { PWrite32((UInt32)Alg::ByteUtil::SystemToLE(v));   }
  15.217     inline void    WriteSInt32(SInt32 v)       { PWrite32((UInt32)Alg::ByteUtil::SystemToLE(v));   }
  15.218     inline void    WriteUInt64(UInt64 v)       { PWrite64((UInt64)Alg::ByteUtil::SystemToLE(v));   }
  15.219     inline void    WriteSInt64(SInt64 v)       { PWrite64((UInt64)Alg::ByteUtil::SystemToLE(v));   }
  15.220     inline void    WriteFloat(float v)         { v = Alg::ByteUtil::SystemToLE(v); Write((UByte*)&v, 4); } 
  15.221     inline void    WriteDouble(double v)       { v = Alg::ByteUtil::SystemToLE(v); Write((UByte*)&v, 8); }
  15.222     // Writing primitive types - Big Endian
  15.223     inline void    WriteUByteBE(UByte v)       { PWrite8((UByte)Alg::ByteUtil::SystemToBE(v));     }
  15.224     inline void    WriteSByteBE(SByte v)       { PWrite8((UByte)Alg::ByteUtil::SystemToBE(v));     }
  15.225     inline void    WriteUInt8BE(UInt16 v)      { PWrite8((UByte)Alg::ByteUtil::SystemToBE(v));     }
  15.226     inline void    WriteSInt8BE(SInt16 v)      { PWrite8((UByte)Alg::ByteUtil::SystemToBE(v));     }
  15.227     inline void    WriteUInt16BE(UInt16 v)     { PWrite16((UInt16)Alg::ByteUtil::SystemToBE(v));   }
  15.228     inline void    WriteSInt16BE(UInt16 v)     { PWrite16((UInt16)Alg::ByteUtil::SystemToBE(v));   }
  15.229     inline void    WriteUInt32BE(UInt32 v)     { PWrite32((UInt32)Alg::ByteUtil::SystemToBE(v));   }
  15.230     inline void    WriteSInt32BE(UInt32 v)     { PWrite32((UInt32)Alg::ByteUtil::SystemToBE(v));   }
  15.231     inline void    WriteUInt64BE(UInt64 v)     { PWrite64((UInt64)Alg::ByteUtil::SystemToBE(v));   }
  15.232     inline void    WriteSInt64BE(UInt64 v)     { PWrite64((UInt64)Alg::ByteUtil::SystemToBE(v));   }
  15.233     inline void    WriteFloatBE(float v)       { v = Alg::ByteUtil::SystemToBE(v); Write((UByte*)&v, 4); }
  15.234     inline void    WriteDoubleBE(double v)     { v = Alg::ByteUtil::SystemToBE(v); Write((UByte*)&v, 8); }
  15.235         
  15.236     // Reading primitive types - Little Endian
  15.237     inline UByte   ReadUByte()                 { return (UByte)Alg::ByteUtil::LEToSystem(PRead8());    }
  15.238     inline SByte   ReadSByte()                 { return (SByte)Alg::ByteUtil::LEToSystem(PRead8());    }
  15.239     inline UByte   ReadUInt8()                 { return (UByte)Alg::ByteUtil::LEToSystem(PRead8());    }
  15.240     inline SByte   ReadSInt8()                 { return (SByte)Alg::ByteUtil::LEToSystem(PRead8());    }
  15.241     inline UInt16  ReadUInt16()                { return (UInt16)Alg::ByteUtil::LEToSystem(PRead16());  }
  15.242     inline SInt16  ReadSInt16()                { return (SInt16)Alg::ByteUtil::LEToSystem(PRead16());  }
  15.243     inline UInt32  ReadUInt32()                { return (UInt32)Alg::ByteUtil::LEToSystem(PRead32());  }
  15.244     inline SInt32  ReadSInt32()                { return (SInt32)Alg::ByteUtil::LEToSystem(PRead32());  }
  15.245     inline UInt64  ReadUInt64()                { return (UInt64)Alg::ByteUtil::LEToSystem(PRead64());  }
  15.246     inline SInt64  ReadSInt64()                { return (SInt64)Alg::ByteUtil::LEToSystem(PRead64());  }
  15.247     inline float   ReadFloat()                 { float v = 0.0f; Read((UByte*)&v, 4); return Alg::ByteUtil::LEToSystem(v); }
  15.248     inline double  ReadDouble()                { double v = 0.0; Read((UByte*)&v, 8); return Alg::ByteUtil::LEToSystem(v); }
  15.249     // Reading primitive types - Big Endian
  15.250     inline UByte   ReadUByteBE()               { return (UByte)Alg::ByteUtil::BEToSystem(PRead8());    }
  15.251     inline SByte   ReadSByteBE()               { return (SByte)Alg::ByteUtil::BEToSystem(PRead8());    }
  15.252     inline UByte   ReadUInt8BE()               { return (UByte)Alg::ByteUtil::BEToSystem(PRead8());    }
  15.253     inline SByte   ReadSInt8BE()               { return (SByte)Alg::ByteUtil::BEToSystem(PRead8());    }
  15.254     inline UInt16  ReadUInt16BE()              { return (UInt16)Alg::ByteUtil::BEToSystem(PRead16());  }
  15.255     inline SInt16  ReadSInt16BE()              { return (SInt16)Alg::ByteUtil::BEToSystem(PRead16());  }
  15.256     inline UInt32  ReadUInt32BE()              { return (UInt32)Alg::ByteUtil::BEToSystem(PRead32());  }
  15.257     inline SInt32  ReadSInt32BE()              { return (SInt32)Alg::ByteUtil::BEToSystem(PRead32());  }
  15.258     inline UInt64  ReadUInt64BE()              { return (UInt64)Alg::ByteUtil::BEToSystem(PRead64());  }
  15.259     inline SInt64  ReadSInt64BE()              { return (SInt64)Alg::ByteUtil::BEToSystem(PRead64());  }
  15.260     inline float   ReadFloatBE()               { float v = 0.0f; Read((UByte*)&v, 4); return Alg::ByteUtil::BEToSystem(v); }
  15.261     inline double  ReadDoubleBE()              { double v = 0.0; Read((UByte*)&v, 8); return Alg::ByteUtil::BEToSystem(v); }
  15.262 };
  15.263 
  15.264 
  15.265 // *** Delegated File
  15.266 
  15.267 class DelegatedFile : public File
  15.268 {
  15.269 protected:
  15.270     // Delegating file pointer
  15.271     Ptr<File>     pFile;
  15.272 
  15.273     // Hidden default constructor
  15.274     DelegatedFile() : pFile(0)                             { }
  15.275     DelegatedFile(const DelegatedFile &source) : File()    { OVR_UNUSED(source); }
  15.276 public:
  15.277     // Constructors
  15.278     DelegatedFile(File *pfile) : pFile(pfile)     { }
  15.279 
  15.280     // ** Location Information  
  15.281     virtual const char* GetFilePath()                               { return pFile->GetFilePath(); }    
  15.282 
  15.283     // ** File Information                                                      
  15.284     virtual bool        IsValid()                                   { return pFile && pFile->IsValid(); }   
  15.285     virtual bool        IsWritable()                                { return pFile->IsWritable(); }
  15.286 //  virtual bool        IsRecoverable()                             { return pFile->IsRecoverable(); }          
  15.287                                                                     
  15.288     virtual int         Tell()                                      { return pFile->Tell(); }
  15.289     virtual SInt64      LTell()                                     { return pFile->LTell(); }
  15.290     
  15.291     virtual int         GetLength()                                 { return pFile->GetLength(); }
  15.292     virtual SInt64      LGetLength()                                { return pFile->LGetLength(); }
  15.293     
  15.294     //virtual bool      Stat(FileStats *pfs)                        { return pFile->Stat(pfs); }
  15.295     
  15.296     virtual int         GetErrorCode()                              { return pFile->GetErrorCode(); }
  15.297     
  15.298     // ** Stream implementation & I/O
  15.299     virtual int         Write(const UByte *pbuffer, int numBytes)   { return pFile->Write(pbuffer,numBytes); }  
  15.300     virtual int         Read(UByte *pbuffer, int numBytes)          { return pFile->Read(pbuffer,numBytes); }   
  15.301     
  15.302     virtual int         SkipBytes(int numBytes)                     { return pFile->SkipBytes(numBytes); }      
  15.303     
  15.304     virtual int         BytesAvailable()                            { return pFile->BytesAvailable(); } 
  15.305     
  15.306     virtual bool        Flush()                                     { return pFile->Flush(); }
  15.307                                                                     
  15.308     // Seeking                                                      
  15.309     virtual int         Seek(int offset, int origin=Seek_Set)       { return pFile->Seek(offset,origin); }
  15.310     virtual SInt64      LSeek(SInt64 offset, int origin=Seek_Set)   { return pFile->LSeek(offset,origin); }
  15.311 
  15.312     virtual int         CopyFromStream(File *pstream, int byteSize) { return pFile->CopyFromStream(pstream,byteSize); }
  15.313                         
  15.314     // Closing the file 
  15.315     virtual bool        Close()                                     { return pFile->Close(); }    
  15.316 };
  15.317 
  15.318 
  15.319 //-----------------------------------------------------------------------------------
  15.320 // ***** Buffered File
  15.321 
  15.322 // This file class adds buffering to an existing file
  15.323 // Buffered file never fails by itself; if there's not
  15.324 // enough memory for buffer, no buffer's used
  15.325 
  15.326 class BufferedFile : public DelegatedFile
  15.327 {   
  15.328 protected:  
  15.329     enum BufferModeType
  15.330     {
  15.331         NoBuffer,
  15.332         ReadBuffer,
  15.333         WriteBuffer
  15.334     };
  15.335 
  15.336     // Buffer & the mode it's in
  15.337     UByte*          pBuffer;
  15.338     BufferModeType  BufferMode;
  15.339     // Position in buffer
  15.340     unsigned        Pos;
  15.341     // Data in buffer if reading
  15.342     unsigned        DataSize;
  15.343     // Underlying file position 
  15.344     UInt64          FilePos;
  15.345 
  15.346     // Initializes buffering to a certain mode
  15.347     bool    SetBufferMode(BufferModeType mode);
  15.348     // Flushes buffer
  15.349     // WriteBuffer - write data to disk, ReadBuffer - reset buffer & fix file position  
  15.350     void    FlushBuffer();
  15.351     // Loads data into ReadBuffer
  15.352     // WARNING: Right now LoadBuffer() assumes the buffer's empty
  15.353     void    LoadBuffer();
  15.354 
  15.355     // Hidden constructor
  15.356     BufferedFile();
  15.357     inline BufferedFile(const BufferedFile &source) : DelegatedFile() { OVR_UNUSED(source); }
  15.358 public:
  15.359 
  15.360     // Constructor
  15.361     // - takes another file as source
  15.362     BufferedFile(File *pfile);
  15.363     ~BufferedFile();
  15.364     
  15.365     
  15.366     // ** Overridden functions
  15.367 
  15.368     // We override all the functions that can possibly
  15.369     // require buffer mode switch, flush, or extra calculations
  15.370     virtual int         Tell();
  15.371     virtual SInt64      LTell();
  15.372 
  15.373     virtual int         GetLength();
  15.374     virtual SInt64      LGetLength();
  15.375 
  15.376 //  virtual bool        Stat(GFileStats *pfs);  
  15.377 
  15.378     virtual int         Write(const UByte *pbufer, int numBytes);
  15.379     virtual int         Read(UByte *pbufer, int numBytes);
  15.380 
  15.381     virtual int         SkipBytes(int numBytes);
  15.382 
  15.383     virtual int         BytesAvailable();
  15.384 
  15.385     virtual bool        Flush();
  15.386 
  15.387     virtual int         Seek(int offset, int origin=Seek_Set);
  15.388     virtual SInt64      LSeek(SInt64 offset, int origin=Seek_Set);
  15.389 
  15.390     virtual int         CopyFromStream(File *pstream, int byteSize);
  15.391     
  15.392     virtual bool        Close();    
  15.393 };                          
  15.394 
  15.395 
  15.396 //-----------------------------------------------------------------------------------
  15.397 // ***** Memory File
  15.398 
  15.399 class MemoryFile : public File
  15.400 {
  15.401 public:
  15.402 
  15.403     const char* GetFilePath()       { return FilePath.ToCStr(); }
  15.404 
  15.405     bool        IsValid()           { return Valid; }
  15.406     bool        IsWritable()        { return false; }
  15.407 
  15.408     bool        Flush()             { return true; }
  15.409     int         GetErrorCode()      { return 0; }
  15.410 
  15.411     int         Tell()              { return FileIndex; }
  15.412     SInt64      LTell()             { return (SInt64) FileIndex; }
  15.413 
  15.414     int         GetLength()         { return FileSize; }
  15.415     SInt64      LGetLength()        { return (SInt64) FileSize; }
  15.416 
  15.417     bool        Close()
  15.418     {
  15.419         Valid = false;
  15.420         return false;
  15.421     }
  15.422 
  15.423     int         CopyFromStream(File *pstream, int byteSize)
  15.424     {   OVR_UNUSED2(pstream, byteSize);
  15.425         return 0;
  15.426     }
  15.427 
  15.428     int         Write(const UByte *pbuffer, int numBytes)
  15.429     {   OVR_UNUSED2(pbuffer, numBytes);
  15.430         return 0;
  15.431     }
  15.432 
  15.433     int         Read(UByte *pbufer, int numBytes)
  15.434     {
  15.435         if (FileIndex + numBytes > FileSize)
  15.436         {
  15.437             numBytes = FileSize - FileIndex;
  15.438         }
  15.439 
  15.440         if (numBytes > 0)
  15.441         {
  15.442             ::memcpy (pbufer, &FileData [FileIndex], numBytes);
  15.443 
  15.444             FileIndex += numBytes;
  15.445         }
  15.446 
  15.447         return numBytes;
  15.448     }
  15.449 
  15.450     int         SkipBytes(int numBytes)
  15.451     {
  15.452         if (FileIndex + numBytes > FileSize)
  15.453         {
  15.454             numBytes = FileSize - FileIndex;
  15.455         }
  15.456 
  15.457         FileIndex += numBytes;
  15.458 
  15.459         return numBytes;
  15.460     }
  15.461 
  15.462     int         BytesAvailable()
  15.463     {
  15.464         return (FileSize - FileIndex);
  15.465     }
  15.466 
  15.467     int         Seek(int offset, int origin = Seek_Set)
  15.468     {
  15.469         switch (origin)
  15.470         {
  15.471         case Seek_Set : FileIndex  = offset;               break;
  15.472         case Seek_Cur : FileIndex += offset;               break;
  15.473         case Seek_End : FileIndex  = FileSize - offset;  break;
  15.474         }
  15.475 
  15.476         return FileIndex;
  15.477     }
  15.478 
  15.479     SInt64      LSeek(SInt64 offset, int origin = Seek_Set)
  15.480     {
  15.481         return (SInt64) Seek((int) offset, origin);
  15.482     }
  15.483 
  15.484 public:
  15.485 
  15.486     MemoryFile (const String& fileName, const UByte *pBuffer, int buffSize)
  15.487         : FilePath(fileName)
  15.488     {
  15.489         FileData  = pBuffer;
  15.490         FileSize  = buffSize;
  15.491         FileIndex = 0;
  15.492         Valid     = (!fileName.IsEmpty() && pBuffer && buffSize > 0) ? true : false;
  15.493     }
  15.494 
  15.495     // pfileName should be encoded as UTF-8 to support international file names.
  15.496     MemoryFile (const char* pfileName, const UByte *pBuffer, int buffSize)
  15.497         : FilePath(pfileName)
  15.498     {
  15.499         FileData  = pBuffer;
  15.500         FileSize  = buffSize;
  15.501         FileIndex = 0;
  15.502         Valid     = (pfileName && pBuffer && buffSize > 0) ? true : false;
  15.503     }
  15.504 private:
  15.505 
  15.506     String       FilePath;
  15.507     const UByte *FileData;
  15.508     int          FileSize;
  15.509     int          FileIndex;
  15.510     bool         Valid;
  15.511 };
  15.512 
  15.513 
  15.514 // ***** Global path helpers
  15.515 
  15.516 // Find trailing short filename in a path.
  15.517 const char* OVR_CDECL GetShortFilename(const char* purl);
  15.518 
  15.519 } // OVR
  15.520 
  15.521 #endif
  15.522 \ No newline at end of file
    16.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    16.2 +++ b/libovr/Src/Kernel/OVR_FileFILE.cpp	Sat Sep 14 16:14:59 2013 +0300
    16.3 @@ -0,0 +1,1 @@
    16.4 +/**************************************************************************
    16.5 
    16.6 Filename    :   OVR_FileFILE.cpp
    16.7 Content     :   File wrapper class implementation (Win32)
    16.8 
    16.9 Created     :   April 5, 1999
   16.10 Authors     :   Michael Antonov
   16.11 
   16.12 Copyright   :   Copyright 2012 Oculus VR, Inc. All Rights reserved.
   16.13 
   16.14 Use of this software is subject to the terms of the Oculus license
   16.15 agreement provided at the time of installation or download, or which
   16.16 otherwise accompanies this software in either electronic or hard copy form.
   16.17 
   16.18 **************************************************************************/
   16.19 
   16.20 #define  GFILE_CXX
   16.21 
   16.22 #include "OVR_Types.h"
   16.23 #include "OVR_Log.h"
   16.24 
   16.25 // Standard C library (Captain Obvious guarantees!)
   16.26 #include <stdio.h>
   16.27 #ifndef OVR_OS_WINCE
   16.28 #include <sys/stat.h>
   16.29 #endif
   16.30 
   16.31 #include "OVR_SysFile.h"
   16.32 
   16.33 #ifndef OVR_OS_WINCE
   16.34 #include <errno.h>
   16.35 #endif
   16.36 
   16.37 namespace OVR {
   16.38 
   16.39 // ***** File interface
   16.40 
   16.41 // ***** FILEFile - C streams file
   16.42 
   16.43 static int SFerror ()
   16.44 {
   16.45     if (errno == ENOENT)
   16.46         return FileConstants::Error_FileNotFound;
   16.47     else if (errno == EACCES || errno == EPERM)
   16.48         return FileConstants::Error_Access;
   16.49     else if (errno == ENOSPC)
   16.50         return FileConstants::Error_DiskFull;
   16.51     else
   16.52         return FileConstants::Error_IOError;
   16.53 };
   16.54 
   16.55 #ifdef OVR_OS_WIN32
   16.56 #include "windows.h"
   16.57 // A simple helper class to disable/enable system error mode, if necessary
   16.58 // Disabling happens conditionally only if a drive name is involved
   16.59 class SysErrorModeDisabler
   16.60 {
   16.61     BOOL    Disabled;
   16.62     UINT    OldMode;
   16.63 public:
   16.64     SysErrorModeDisabler(const char* pfileName)
   16.65     {
   16.66         if (pfileName && (pfileName[0]!=0) && pfileName[1]==':')
   16.67         {
   16.68             Disabled = 1;
   16.69             OldMode = ::SetErrorMode(SEM_FAILCRITICALERRORS);
   16.70         }
   16.71         else
   16.72             Disabled = 0;
   16.73     }
   16.74 
   16.75     ~SysErrorModeDisabler()
   16.76     {
   16.77         if (Disabled) ::SetErrorMode(OldMode);
   16.78     }
   16.79 };
   16.80 #else
   16.81 class SysErrorModeDisabler
   16.82 {
   16.83 public:
   16.84     SysErrorModeDisabler(const char* pfileName) { }
   16.85 };
   16.86 #endif // OVR_OS_WIN32
   16.87 
   16.88 
   16.89 // This macro enables verification of I/O results after seeks against a pre-loaded
   16.90 // full file buffer copy. This is generally not necessary, but can been used to debug
   16.91 // memory corruptions; we've seen this fail due to EAX2/DirectSound corrupting memory
   16.92 // under FMOD with XP64 (32-bit) and Realtek HA Audio driver.
   16.93 //#define GFILE_VERIFY_SEEK_ERRORS
   16.94 
   16.95 
   16.96 // This is the simplest possible file implementation, it wraps around the descriptor
   16.97 // This file is delegated to by SysFile.
   16.98 
   16.99 class FILEFile : public File
  16.100 {
  16.101 protected:
  16.102 
  16.103     // Allocated filename
  16.104     String      FileName;
  16.105 
  16.106     // File handle & open mode
  16.107     bool        Opened;
  16.108     FILE*       fs;
  16.109     int         OpenFlags;
  16.110     // Error code for last request
  16.111     int         ErrorCode;
  16.112 
  16.113     int         LastOp;
  16.114 
  16.115 #ifdef OVR_FILE_VERIFY_SEEK_ERRORS
  16.116     UByte*      pFileTestBuffer;
  16.117     unsigned    FileTestLength;
  16.118     unsigned    TestPos; // File pointer position during tests.
  16.119 #endif
  16.120 
  16.121 public:
  16.122 
  16.123     FILEFile()
  16.124     {
  16.125         Opened = 0; FileName = "";
  16.126 
  16.127 #ifdef OVR_FILE_VERIFY_SEEK_ERRORS
  16.128         pFileTestBuffer =0;
  16.129         FileTestLength  =0;
  16.130         TestPos         =0;
  16.131 #endif
  16.132     }
  16.133     // Initialize file by opening it
  16.134     FILEFile(const String& fileName, int flags, int Mode);
  16.135     // The 'pfileName' should be encoded as UTF-8 to support international file names.
  16.136     FILEFile(const char* pfileName, int flags, int Mode);
  16.137 
  16.138     ~FILEFile()
  16.139     {
  16.140         if (Opened)
  16.141             Close();
  16.142     }
  16.143 
  16.144     virtual const char* GetFilePath();
  16.145 
  16.146     // ** File Information
  16.147     virtual bool        IsValid();
  16.148     virtual bool        IsWritable();
  16.149 
  16.150     // Return position / file size
  16.151     virtual int         Tell();
  16.152     virtual SInt64      LTell();
  16.153     virtual int         GetLength();
  16.154     virtual SInt64      LGetLength();
  16.155 
  16.156 //  virtual bool        Stat(FileStats *pfs);
  16.157     virtual int         GetErrorCode();
  16.158 
  16.159     // ** Stream implementation & I/O
  16.160     virtual int         Write(const UByte *pbuffer, int numBytes);
  16.161     virtual int         Read(UByte *pbuffer, int numBytes);
  16.162     virtual int         SkipBytes(int numBytes);
  16.163     virtual int         BytesAvailable();
  16.164     virtual bool        Flush();
  16.165     virtual int         Seek(int offset, int origin);
  16.166     virtual SInt64      LSeek(SInt64 offset, int origin);
  16.167     
  16.168     virtual int         CopyFromStream(File *pStream, int byteSize);
  16.169     virtual bool        Close();    
  16.170 private:
  16.171     void                init();
  16.172 };
  16.173 
  16.174 
  16.175 // Initialize file by opening it
  16.176 FILEFile::FILEFile(const String& fileName, int flags, int mode)
  16.177   : FileName(fileName), OpenFlags(flags)
  16.178 {
  16.179     OVR_UNUSED(mode);
  16.180     init();
  16.181 }
  16.182 
  16.183 // The 'pfileName' should be encoded as UTF-8 to support international file names.
  16.184 FILEFile::FILEFile(const char* pfileName, int flags, int mode)
  16.185   : FileName(pfileName), OpenFlags(flags)
  16.186 {
  16.187     OVR_UNUSED(mode);
  16.188     init();
  16.189 }
  16.190 
  16.191 void FILEFile::init()
  16.192 {
  16.193     // Open mode for file's open
  16.194     const char *omode = "rb";
  16.195 
  16.196     if (OpenFlags & Open_Truncate)
  16.197     {
  16.198         if (OpenFlags & Open_Read)
  16.199             omode = "w+b";
  16.200         else
  16.201             omode = "wb";
  16.202     }
  16.203     else if (OpenFlags & Open_Create)
  16.204     {
  16.205         if (OpenFlags & Open_Read)
  16.206             omode = "a+b";
  16.207         else
  16.208             omode = "ab";
  16.209     }
  16.210     else if (OpenFlags & Open_Write)
  16.211         omode = "r+b";
  16.212 
  16.213 #ifdef OVR_OS_WIN32
  16.214     SysErrorModeDisabler disabler(FileName.ToCStr());
  16.215 #endif
  16.216 
  16.217 #if defined(OVR_CC_MSVC) && (OVR_CC_MSVC >= 1400)
  16.218     wchar_t womode[16];
  16.219     wchar_t *pwFileName = (wchar_t*)OVR_ALLOC((UTF8Util::GetLength(FileName.ToCStr())+1) * sizeof(wchar_t));
  16.220     UTF8Util::DecodeString(pwFileName, FileName.ToCStr());
  16.221     OVR_ASSERT(strlen(omode) < sizeof(womode)/sizeof(womode[0]));
  16.222     UTF8Util::DecodeString(womode, omode);
  16.223     _wfopen_s(&fs, pwFileName, womode);
  16.224     OVR_FREE(pwFileName);
  16.225 #else
  16.226     fs = fopen(FileName.ToCStr(), omode);
  16.227 #endif
  16.228     if (fs)
  16.229         rewind (fs);
  16.230     Opened = (fs != NULL);
  16.231     // Set error code
  16.232     if (!Opened)
  16.233         ErrorCode = SFerror();
  16.234     else
  16.235     {
  16.236         // If we are testing file seek correctness, pre-load the entire file so
  16.237         // that we can do comparison tests later.
  16.238 #ifdef OVR_FILE_VERIFY_SEEK_ERRORS        
  16.239         TestPos         = 0;
  16.240         fseek(fs, 0, SEEK_END);
  16.241         FileTestLength  = ftell(fs);
  16.242         fseek(fs, 0, SEEK_SET);
  16.243         pFileTestBuffer = (UByte*)OVR_ALLOC(FileTestLength);
  16.244         if (pFileTestBuffer)
  16.245         {
  16.246             OVR_ASSERT(FileTestLength == (unsigned)Read(pFileTestBuffer, FileTestLength));
  16.247             Seek(0, Seek_Set);
  16.248         }        
  16.249 #endif
  16.250 
  16.251         ErrorCode = 0;
  16.252     }
  16.253     LastOp = 0;
  16.254 }
  16.255 
  16.256 
  16.257 const char* FILEFile::GetFilePath()
  16.258 {
  16.259     return FileName.ToCStr();
  16.260 }
  16.261 
  16.262 
  16.263 // ** File Information
  16.264 bool    FILEFile::IsValid()
  16.265 {
  16.266     return Opened;
  16.267 }
  16.268 bool    FILEFile::IsWritable()
  16.269 {
  16.270     return IsValid() && (OpenFlags&Open_Write);
  16.271 }
  16.272 /*
  16.273 bool    FILEFile::IsRecoverable()
  16.274 {
  16.275     return IsValid() && ((OpenFlags&OVR_FO_SAFETRUNC) == OVR_FO_SAFETRUNC);
  16.276 }
  16.277 */
  16.278 
  16.279 // Return position / file size
  16.280 int     FILEFile::Tell()
  16.281 {
  16.282     int pos = (int)ftell (fs);
  16.283     if (pos < 0)
  16.284         ErrorCode = SFerror();
  16.285     return pos;
  16.286 }
  16.287 
  16.288 SInt64  FILEFile::LTell()
  16.289 {
  16.290     SInt64 pos = ftell(fs);
  16.291     if (pos < 0)
  16.292         ErrorCode = SFerror();
  16.293     return pos;
  16.294 }
  16.295 
  16.296 int     FILEFile::GetLength()
  16.297 {
  16.298     int pos = Tell();
  16.299     if (pos >= 0)
  16.300     {
  16.301         Seek (0, Seek_End);
  16.302         int size = Tell();
  16.303         Seek (pos, Seek_Set);
  16.304         return size;
  16.305     }
  16.306     return -1;
  16.307 }
  16.308 SInt64  FILEFile::LGetLength()
  16.309 {
  16.310     SInt64 pos = LTell();
  16.311     if (pos >= 0)
  16.312     {
  16.313         LSeek (0, Seek_End);
  16.314         SInt64 size = LTell();
  16.315         LSeek (pos, Seek_Set);
  16.316         return size;
  16.317     }
  16.318     return -1;
  16.319 }
  16.320 
  16.321 int     FILEFile::GetErrorCode()
  16.322 {
  16.323     return ErrorCode;
  16.324 }
  16.325 
  16.326 // ** Stream implementation & I/O
  16.327 int     FILEFile::Write(const UByte *pbuffer, int numBytes)
  16.328 {
  16.329     if (LastOp && LastOp != Open_Write)
  16.330         fflush(fs);
  16.331     LastOp = Open_Write;
  16.332     int written = (int) fwrite(pbuffer, 1, numBytes, fs);
  16.333     if (written < numBytes)
  16.334         ErrorCode = SFerror();
  16.335 
  16.336 #ifdef OVR_FILE_VERIFY_SEEK_ERRORS
  16.337     if (written > 0)
  16.338         TestPos += written;
  16.339 #endif
  16.340 
  16.341     return written;
  16.342 }
  16.343 
  16.344 int     FILEFile::Read(UByte *pbuffer, int numBytes)
  16.345 {
  16.346     if (LastOp && LastOp != Open_Read)
  16.347         fflush(fs);
  16.348     LastOp = Open_Read;
  16.349     int read = (int) fread(pbuffer, 1, numBytes, fs);
  16.350     if (read < numBytes)
  16.351         ErrorCode = SFerror();
  16.352 
  16.353 #ifdef OVR_FILE_VERIFY_SEEK_ERRORS
  16.354     if (read > 0)
  16.355     {
  16.356         // Read-in data must match our pre-loaded buffer data!
  16.357         UByte* pcompareBuffer = pFileTestBuffer + TestPos;
  16.358         for (int i=0; i< read; i++)
  16.359         {
  16.360             OVR_ASSERT(pcompareBuffer[i] == pbuffer[i]);
  16.361         }
  16.362 
  16.363         //OVR_ASSERT(!memcmp(pFileTestBuffer + TestPos, pbuffer, read));
  16.364         TestPos += read;
  16.365         OVR_ASSERT(ftell(fs) == (int)TestPos);
  16.366     }
  16.367 #endif
  16.368 
  16.369     return read;
  16.370 }
  16.371 
  16.372 // Seeks ahead to skip bytes
  16.373 int     FILEFile::SkipBytes(int numBytes)
  16.374 {
  16.375     SInt64 pos    = LTell();
  16.376     SInt64 newPos = LSeek(numBytes, Seek_Cur);
  16.377 
  16.378     // Return -1 for major error
  16.379     if ((pos==-1) || (newPos==-1))
  16.380     {
  16.381         return -1;
  16.382     }
  16.383     //ErrorCode = ((NewPos-Pos)<numBytes) ? errno : 0;
  16.384 
  16.385     return int (newPos-(int)pos);
  16.386 }
  16.387 
  16.388 // Return # of bytes till EOF
  16.389 int     FILEFile::BytesAvailable()
  16.390 {
  16.391     SInt64 pos    = LTell();
  16.392     SInt64 endPos = LGetLength();
  16.393 
  16.394     // Return -1 for major error
  16.395     if ((pos==-1) || (endPos==-1))
  16.396     {
  16.397         ErrorCode = SFerror();
  16.398         return 0;
  16.399     }
  16.400     else
  16.401         ErrorCode = 0;
  16.402 
  16.403     return int (endPos-(int)pos);
  16.404 }
  16.405 
  16.406 // Flush file contents
  16.407 bool    FILEFile::Flush()
  16.408 {
  16.409     return !fflush(fs);
  16.410 }
  16.411 
  16.412 int     FILEFile::Seek(int offset, int origin)
  16.413 {
  16.414     int newOrigin = 0;
  16.415     switch(origin)
  16.416     {
  16.417     case Seek_Set: newOrigin = SEEK_SET; break;
  16.418     case Seek_Cur: newOrigin = SEEK_CUR; break;
  16.419     case Seek_End: newOrigin = SEEK_END; break;
  16.420     }
  16.421 
  16.422     if (newOrigin == SEEK_SET && offset == Tell())
  16.423         return Tell();
  16.424 
  16.425     if (fseek (fs, offset, newOrigin))
  16.426     {
  16.427 #ifdef OVR_FILE_VERIFY_SEEK_ERRORS
  16.428         OVR_ASSERT(0);
  16.429 #endif
  16.430         return -1;
  16.431     }
  16.432     
  16.433 #ifdef OVR_FILE_VERIFY_SEEK_ERRORS
  16.434     // Track file position after seeks for read verification later.
  16.435     switch(origin)
  16.436     {
  16.437     case Seek_Set:  TestPos = offset;       break;
  16.438     case Seek_Cur:  TestPos += offset;      break;    
  16.439     case Seek_End:  TestPos = FileTestLength + offset; break;
  16.440     }
  16.441     OVR_ASSERT((int)TestPos == Tell());
  16.442 #endif
  16.443 
  16.444     return (int)Tell();
  16.445 }
  16.446 
  16.447 SInt64  FILEFile::LSeek(SInt64 offset, int origin)
  16.448 {
  16.449     return Seek((int)offset,origin);
  16.450 }
  16.451 
  16.452 int FILEFile::CopyFromStream(File *pstream, int byteSize)
  16.453 {
  16.454     UByte   buff[0x4000];
  16.455     int     count = 0;
  16.456     int     szRequest, szRead, szWritten;
  16.457 
  16.458     while (byteSize)
  16.459     {
  16.460         szRequest = (byteSize > int(sizeof(buff))) ? int(sizeof(buff)) : byteSize;
  16.461 
  16.462         szRead    = pstream->Read(buff, szRequest);
  16.463         szWritten = 0;
  16.464         if (szRead > 0)
  16.465             szWritten = Write(buff, szRead);
  16.466 
  16.467         count    += szWritten;
  16.468         byteSize -= szWritten;
  16.469         if (szWritten < szRequest)
  16.470             break;
  16.471     }
  16.472     return count;
  16.473 }
  16.474 
  16.475 
  16.476 bool FILEFile::Close()
  16.477 {
  16.478 #ifdef OVR_FILE_VERIFY_SEEK_ERRORS
  16.479     if (pFileTestBuffer)
  16.480     {
  16.481         OVR_FREE(pFileTestBuffer);
  16.482         pFileTestBuffer = 0;
  16.483         FileTestLength  = 0;
  16.484     }
  16.485 #endif
  16.486 
  16.487     bool closeRet = !fclose(fs);
  16.488 
  16.489     if (!closeRet)
  16.490     {
  16.491         ErrorCode = SFerror();
  16.492         return 0;
  16.493     }
  16.494     else
  16.495     {
  16.496         Opened    = 0;
  16.497         fs        = 0;
  16.498         ErrorCode = 0;
  16.499     }
  16.500 
  16.501     // Handle safe truncate
  16.502     /*
  16.503     if ((OpenFlags & OVR_FO_SAFETRUNC) == OVR_FO_SAFETRUNC)
  16.504     {
  16.505         // Delete original file (if it existed)
  16.506         DWORD oldAttributes = FileUtilWin32::GetFileAttributes(FileName);
  16.507         if (oldAttributes!=0xFFFFFFFF)
  16.508             if (!FileUtilWin32::DeleteFile(FileName))
  16.509             {
  16.510                 // Try to remove the readonly attribute
  16.511                 FileUtilWin32::SetFileAttributes(FileName, oldAttributes & (~FILE_ATTRIBUTE_READONLY) );
  16.512                 // And delete the file again
  16.513                 if (!FileUtilWin32::DeleteFile(FileName))
  16.514                     return 0;
  16.515             }
  16.516 
  16.517         // Rename temp file to real filename
  16.518         if (!FileUtilWin32::MoveFile(TempName, FileName))
  16.519         {
  16.520             //ErrorCode = errno;
  16.521             return 0;
  16.522         }
  16.523     }
  16.524     */
  16.525     return 1;
  16.526 }
  16.527 
  16.528 /*
  16.529 bool    FILEFile::CloseCancel()
  16.530 {
  16.531     bool closeRet = (bool)::CloseHandle(fd);
  16.532 
  16.533     if (!closeRet)
  16.534     {
  16.535         //ErrorCode = errno;
  16.536         return 0;
  16.537     }
  16.538     else
  16.539     {
  16.540         Opened    = 0;
  16.541         fd        = INVALID_HANDLE_VALUE;
  16.542         ErrorCode = 0;
  16.543     }
  16.544 
  16.545     // Handle safe truncate (delete tmp file, leave original unchanged)
  16.546     if ((OpenFlags&OVR_FO_SAFETRUNC) == OVR_FO_SAFETRUNC)
  16.547         if (!FileUtilWin32::DeleteFile(TempName))
  16.548         {
  16.549             //ErrorCode = errno;
  16.550             return 0;
  16.551         }
  16.552     return 1;
  16.553 }
  16.554 */
  16.555 
  16.556 File *FileFILEOpen(const String& path, int flags, int mode)
  16.557 {
  16.558     return new FILEFile(path, flags, mode);
  16.559 }
  16.560 
  16.561 // Helper function: obtain file information time.
  16.562 bool    SysFile::GetFileStat(FileStat* pfileStat, const String& path)
  16.563 {
  16.564 #if defined(OVR_OS_WIN32)
  16.565     // 64-bit implementation on Windows.
  16.566     struct __stat64 fileStat;
  16.567     // Stat returns 0 for success.
  16.568     wchar_t *pwpath = (wchar_t*)OVR_ALLOC((UTF8Util::GetLength(path.ToCStr())+1)*sizeof(wchar_t));
  16.569     UTF8Util::DecodeString(pwpath, path.ToCStr());
  16.570 
  16.571     int ret = _wstat64(pwpath, &fileStat);
  16.572     OVR_FREE(pwpath);
  16.573     if (ret) return false;
  16.574 #else
  16.575     struct stat fileStat;
  16.576     // Stat returns 0 for success.
  16.577     if (stat(path, &fileStat) != 0)
  16.578         return false;
  16.579 #endif
  16.580     pfileStat->AccessTime = fileStat.st_atime;
  16.581     pfileStat->ModifyTime = fileStat.st_mtime;
  16.582     pfileStat->FileSize   = fileStat.st_size;
  16.583     return true;
  16.584 }
  16.585 
  16.586 } // Scaleform
  16.587 \ No newline at end of file
    17.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    17.2 +++ b/libovr/Src/Kernel/OVR_Hash.h	Sat Sep 14 16:14:59 2013 +0300
    17.3 @@ -0,0 +1,1 @@
    17.4 +/************************************************************************************
    17.5 
    17.6 PublicHeader:   None
    17.7 Filename    :   OVR_Hash.h
    17.8 Content     :   Template hash-table/set implementation
    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_Hash_h
   17.21 #define OVR_Hash_h
   17.22 
   17.23 #include "OVR_ContainerAllocator.h"
   17.24 #include "OVR_Alg.h"
   17.25 
   17.26 // 'new' operator is redefined/used in this file.
   17.27 #undef new
   17.28 
   17.29 namespace OVR {
   17.30 
   17.31 //-----------------------------------------------------------------------------------
   17.32 // ***** Hash Table Implementation
   17.33 
   17.34 // HastSet and Hash.
   17.35 //
   17.36 // Hash table, linear probing, internal chaining.  One  interesting/nice thing
   17.37 // about this implementation is that the table itself is a flat chunk of memory
   17.38 // containing no pointers, only relative indices. If the key and value types
   17.39 // of the Hash contain no pointers, then the Hash can be serialized using raw IO.
   17.40 //
   17.41 // Never shrinks, unless you explicitly Clear() it.  Expands on
   17.42 // demand, though.  For best results, if you know roughly how big your
   17.43 // table will be, default it to that size when you create it.
   17.44 //
   17.45 // Key usability feature:
   17.46 //
   17.47 //   1. Allows node hash values to either be cached or not.
   17.48 //
   17.49 //   2. Allows for alternative keys with methods such as GetAlt(). Handy
   17.50 //      if you need to search nodes by their components; no need to create
   17.51 //      temporary nodes.
   17.52 //
   17.53 
   17.54 
   17.55 // *** Hash functors:
   17.56 //
   17.57 //  IdentityHash  - use when the key is already a good hash
   17.58 //  HFixedSizeHash - general hash based on object's in-memory representation.
   17.59 
   17.60 
   17.61 // Hash is just the input value; can use this for integer-indexed hash tables.
   17.62 template<class C>
   17.63 class IdentityHash
   17.64 {
   17.65 public:
   17.66     UPInt operator()(const C& data) const
   17.67     { return (UPInt) data; }
   17.68 };
   17.69 
   17.70 // Computes a hash of an object's representation.
   17.71 template<class C>
   17.72 class FixedSizeHash
   17.73 {
   17.74 public:
   17.75     // Alternative: "sdbm" hash function, suggested at same web page
   17.76     // above, http::/www.cs.yorku.ca/~oz/hash.html
   17.77     // This is somewhat slower then Bernstein, but it works way better than the above
   17.78     // hash function for hashing large numbers of 32-bit ints.
   17.79     static OVR_FORCE_INLINE UPInt SDBM_Hash(const void* data_in, UPInt size, UPInt seed = 5381)     
   17.80     {
   17.81         const UByte* data = (const UByte*) data_in;
   17.82         UPInt        h = seed;
   17.83         while (size > 0)
   17.84         {
   17.85             size--;
   17.86             h = (h << 16) + (h << 6) - h + (UPInt)data[size];
   17.87         }   
   17.88         return h;
   17.89     }
   17.90 
   17.91     UPInt operator()(const C& data) const
   17.92     {
   17.93         unsigned char*  p = (unsigned char*) &data;
   17.94         int size = sizeof(C);
   17.95 
   17.96         return SDBM_Hash(p, size);
   17.97     }
   17.98 };
   17.99 
  17.100 
  17.101 
  17.102 // *** HashsetEntry Entry types. 
  17.103 
  17.104 // Compact hash table Entry type that re-computes hash keys during hash traversal.
  17.105 // Good to use if the hash function is cheap or the hash value is already cached in C.
  17.106 template<class C, class HashF>
  17.107 class HashsetEntry
  17.108 {
  17.109 public:
  17.110     // Internal chaining for collisions.
  17.111     SPInt       NextInChain;
  17.112     C           Value;
  17.113 
  17.114     HashsetEntry()
  17.115         : NextInChain(-2) { }
  17.116     HashsetEntry(const HashsetEntry& e)
  17.117         : NextInChain(e.NextInChain), Value(e.Value) { }
  17.118     HashsetEntry(const C& key, SPInt next)
  17.119         : NextInChain(next), Value(key) { }
  17.120 
  17.121     bool    IsEmpty() const          { return NextInChain == -2;  }
  17.122     bool    IsEndOfChain() const     { return NextInChain == -1;  }
  17.123 
  17.124     // Cached hash value access - can be optimized bu storing hash locally.
  17.125     // Mask value only needs to be used if SetCachedHash is not implemented.
  17.126     UPInt   GetCachedHash(UPInt maskValue) const  { return HashF()(Value) & maskValue; }
  17.127     void    SetCachedHash(UPInt)                  {}
  17.128 
  17.129     void    Clear()
  17.130     {        
  17.131         Value.~C(); // placement delete
  17.132         NextInChain = -2;
  17.133     }
  17.134     // Free is only used from dtor of hash; Clear is used during regular operations:
  17.135     // assignment, hash reallocations, value reassignments, so on.
  17.136     void    Free() { Clear(); }
  17.137 };
  17.138 
  17.139 // Hash table Entry type that caches the Entry hash value for nodes, so that it
  17.140 // does not need to be re-computed during access.
  17.141 template<class C, class HashF>
  17.142 class HashsetCachedEntry
  17.143 {
  17.144 public:
  17.145     // Internal chaining for collisions.
  17.146     SPInt       NextInChain;
  17.147     UPInt       HashValue;
  17.148     C           Value;
  17.149 
  17.150     HashsetCachedEntry()
  17.151         : NextInChain(-2) { }
  17.152     HashsetCachedEntry(const HashsetCachedEntry& e)
  17.153         : NextInChain(e.NextInChain), HashValue(e.HashValue), Value(e.Value) { }
  17.154     HashsetCachedEntry(const C& key, SPInt next)
  17.155         : NextInChain(next), Value(key) { }
  17.156 
  17.157     bool    IsEmpty() const          { return NextInChain == -2;  }
  17.158     bool    IsEndOfChain() const     { return NextInChain == -1;  }
  17.159 
  17.160     // Cached hash value access - can be optimized bu storing hash locally.
  17.161     // Mask value only needs to be used if SetCachedHash is not implemented.
  17.162     UPInt   GetCachedHash(UPInt maskValue) const  { OVR_UNUSED(maskValue); return HashValue; }
  17.163     void    SetCachedHash(UPInt hashValue)        { HashValue = hashValue; }
  17.164 
  17.165     void    Clear()
  17.166     {
  17.167         Value.~C();
  17.168         NextInChain = -2;
  17.169     }
  17.170     // Free is only used from dtor of hash; Clear is used during regular operations:
  17.171     // assignment, hash reallocations, value reassignments, so on.
  17.172     void    Free() { Clear(); }
  17.173 };
  17.174 
  17.175 
  17.176 //-----------------------------------------------------------------------------------
  17.177 // *** HashSet implementation - relies on either cached or regular entries.
  17.178 //
  17.179 // Use: Entry = HashsetCachedEntry<C, HashF> if hashes are expensive to
  17.180 //              compute and thus need caching in entries.
  17.181 //      Entry = HashsetEntry<C, HashF> if hashes are already externally cached.
  17.182 //
  17.183 template<class C, class HashF = FixedSizeHash<C>,
  17.184          class AltHashF = HashF, 
  17.185          class Allocator = ContainerAllocator<C>,
  17.186          class Entry = HashsetCachedEntry<C, HashF> >
  17.187 class HashSetBase
  17.188 {
  17.189     enum { HashMinSize = 8 };
  17.190 
  17.191 public:
  17.192     OVR_MEMORY_REDEFINE_NEW(HashSetBase)
  17.193 
  17.194     typedef HashSetBase<C, HashF, AltHashF, Allocator, Entry>    SelfType;
  17.195 
  17.196     HashSetBase() : pTable(NULL)                       {   }
  17.197     HashSetBase(int sizeHint) : pTable(NULL)           { SetCapacity(this, sizeHint);  }
  17.198     HashSetBase(const SelfType& src) : pTable(NULL)    { Assign(this, src); }
  17.199 
  17.200     ~HashSetBase()                                     
  17.201     { 
  17.202         if (pTable)
  17.203         {
  17.204             // Delete the entries.
  17.205             for (UPInt i = 0, n = pTable->SizeMask; i <= n; i++)
  17.206             {
  17.207                 Entry*  e = &E(i);
  17.208                 if (!e->IsEmpty())             
  17.209                     e->Free();
  17.210             }            
  17.211 
  17.212             Allocator::Free(pTable);
  17.213             pTable = NULL;
  17.214         }
  17.215     }
  17.216 
  17.217 
  17.218     void Assign(const SelfType& src)
  17.219     {
  17.220         Clear();
  17.221         if (src.IsEmpty() == false)
  17.222         {
  17.223             SetCapacity(src.GetSize());
  17.224 
  17.225             for (ConstIterator it = src.Begin(); it != src.End(); ++it)
  17.226             {
  17.227                 Add(*it);
  17.228             }
  17.229         }
  17.230     }
  17.231 
  17.232 
  17.233     // Remove all entries from the HashSet table.
  17.234     void Clear() 
  17.235     {
  17.236         if (pTable)
  17.237         {
  17.238             // Delete the entries.
  17.239             for (UPInt i = 0, n = pTable->SizeMask; i <= n; i++)
  17.240             {
  17.241                 Entry*  e = &E(i);
  17.242                 if (!e->IsEmpty())             
  17.243                     e->Clear();
  17.244             }            
  17.245                 
  17.246             Allocator::Free(pTable);
  17.247             pTable = NULL;
  17.248         }
  17.249     }
  17.250 
  17.251     // Returns true if the HashSet is empty.
  17.252     bool IsEmpty() const
  17.253     {
  17.254         return pTable == NULL || pTable->EntryCount == 0;
  17.255     }
  17.256 
  17.257 
  17.258     // Set a new or existing value under the key, to the value.
  17.259     // Pass a different class of 'key' so that assignment reference object
  17.260     // can be passed instead of the actual object.
  17.261     template<class CRef>
  17.262     void Set(const CRef& key)
  17.263     {
  17.264         UPInt  hashValue = HashF()(key);
  17.265         SPInt  index     = (SPInt)-1;
  17.266 
  17.267         if (pTable != NULL)
  17.268             index = findIndexCore(key, hashValue & pTable->SizeMask);
  17.269 
  17.270         if (index >= 0)
  17.271         {            
  17.272             E(index).Value = key;
  17.273         }
  17.274         else
  17.275         {
  17.276             // Entry under key doesn't exist.
  17.277             add(key, hashValue);
  17.278         }
  17.279     }
  17.280 
  17.281     template<class CRef>
  17.282     inline void Add(const CRef& key)
  17.283     {
  17.284         UPInt hashValue = HashF()(key);
  17.285         add(key, hashValue);
  17.286     }
  17.287 
  17.288     // Remove by alternative key.
  17.289     template<class K>
  17.290     void RemoveAlt(const K& key)
  17.291     {   
  17.292         if (pTable == NULL)
  17.293             return;
  17.294 
  17.295         UPInt   hashValue = AltHashF()(key);
  17.296         SPInt   index     = hashValue & pTable->SizeMask;
  17.297 
  17.298         Entry*  e = &E(index);
  17.299 
  17.300         // If empty node or occupied by collider, we have nothing to remove.
  17.301         if (e->IsEmpty() || (e->GetCachedHash(pTable->SizeMask) != (UPInt)index))
  17.302             return;        
  17.303 
  17.304         // Save index
  17.305         SPInt   naturalIndex = index;
  17.306         SPInt   prevIndex    = -1;
  17.307 
  17.308         while ((e->GetCachedHash(pTable->SizeMask) != (UPInt)naturalIndex) || !(e->Value == key))
  17.309         {
  17.310             // Keep looking through the chain.
  17.311             prevIndex   = index;
  17.312             index       = e->NextInChain;
  17.313             if (index == -1)
  17.314                 return; // End of chain, item not found
  17.315             e = &E(index);
  17.316         }
  17.317 
  17.318         // Found it - our item is at index
  17.319         if (naturalIndex == index)
  17.320         {
  17.321             // If we have a follower, move it to us
  17.322             if (!e->IsEndOfChain())
  17.323             {               
  17.324                 Entry*  enext = &E(e->NextInChain);
  17.325                 e->Clear();
  17.326                 new (e) Entry(*enext);
  17.327                 // Point us to the follower's cell that will be cleared
  17.328                 e = enext;
  17.329             }
  17.330         }
  17.331         else
  17.332         {
  17.333             // We are not at natural index, so deal with the prev items next index
  17.334             E(prevIndex).NextInChain = e->NextInChain;
  17.335         }
  17.336 
  17.337         // Clear us, of the follower cell that was moved.
  17.338         e->Clear();
  17.339         pTable->EntryCount --;
  17.340         // Should we check the size to condense hash? ...
  17.341     }
  17.342 
  17.343     // Remove by main key.
  17.344     template<class CRef>
  17.345     void Remove(const CRef& key)
  17.346     {
  17.347         RemoveAlt(key);
  17.348     }
  17.349 
  17.350     // Retrieve the pointer to a value under the given key.
  17.351     //  - If there's no value under the key, then return NULL.    
  17.352     //  - If there is a value, return the pointer.    
  17.353     template<class K>
  17.354     C* Get(const K& key)
  17.355     {
  17.356         SPInt   index = findIndex(key);
  17.357         if (index >= 0)        
  17.358             return &E(index).Value;        
  17.359         return 0;
  17.360     }   
  17.361 
  17.362     template<class K>
  17.363     const C* Get(const K& key) const
  17.364     {
  17.365         SPInt   index = findIndex(key);
  17.366         if (index >= 0)        
  17.367             return &E(index).Value;        
  17.368         return 0;
  17.369     }
  17.370 
  17.371     // Alternative key versions of Get. Used by Hash.
  17.372     template<class K>
  17.373     const C* GetAlt(const K& key) const
  17.374     {
  17.375         SPInt   index = findIndexAlt(key);
  17.376         if (index >= 0)        
  17.377             return &E(index).Value;
  17.378         return 0;
  17.379     }
  17.380 
  17.381     template<class K>
  17.382     C* GetAlt(const K& key)
  17.383     {
  17.384         SPInt   index = findIndexAlt(key);
  17.385         if (index >= 0)        
  17.386             return &E(index).Value;
  17.387         return 0;
  17.388     }   
  17.389 
  17.390     template<class K>
  17.391     bool GetAlt(const K& key, C* pval) const
  17.392     {
  17.393         SPInt   index = findIndexAlt(key);
  17.394         if (index >= 0)
  17.395         {
  17.396             if (pval)
  17.397                 *pval = E(index).Value;
  17.398             return true;
  17.399         }
  17.400         return false;
  17.401     }
  17.402 
  17.403 
  17.404     UPInt GetSize() const
  17.405     {
  17.406         return pTable == NULL ? 0 : (UPInt)pTable->EntryCount;
  17.407     }
  17.408 
  17.409 
  17.410     // Resize the HashSet table to fit one more Entry.  Often this
  17.411     // doesn't involve any action.
  17.412     void CheckExpand()
  17.413     {
  17.414         if (pTable == NULL)
  17.415         {
  17.416             // Initial creation of table.  Make a minimum-sized table.
  17.417             setRawCapacity(HashMinSize);
  17.418         }
  17.419         else if (pTable->EntryCount * 5 > (pTable->SizeMask + 1) * 4)
  17.420         {
  17.421             // pTable is more than 5/4 ths full.  Expand.
  17.422             setRawCapacity((pTable->SizeMask + 1) * 2);
  17.423         }
  17.424     }
  17.425 
  17.426     // Hint the bucket count to >= n.
  17.427     void Resize(UPInt n)    
  17.428     {
  17.429         // Not really sure what this means in relation to
  17.430         // STLport's hash_map... they say they "increase the
  17.431         // bucket count to at least n" -- but does that mean
  17.432         // their real capacity after Resize(n) is more like
  17.433         // n*2 (since they do linked-list chaining within
  17.434         // buckets?).
  17.435         SetCapacity(n);
  17.436     }
  17.437 
  17.438     // Size the HashSet so that it can comfortably contain the given
  17.439     // number of elements.  If the HashSet already contains more
  17.440     // elements than newSize, then this may be a no-op.
  17.441     void SetCapacity(UPInt newSize)
  17.442     {
  17.443         UPInt newRawSize = (newSize * 5) / 4;
  17.444         if (newRawSize <= GetSize())
  17.445             return;
  17.446         setRawCapacity(newRawSize);
  17.447     }
  17.448 
  17.449     // Disable inappropriate 'operator ->' warning on MSVC6.
  17.450 #ifdef OVR_CC_MSVC
  17.451 #if (OVR_CC_MSVC < 1300)
  17.452 # pragma warning(disable : 4284)
  17.453 #endif
  17.454 #endif
  17.455 
  17.456     // Iterator API, like STL.
  17.457     struct ConstIterator
  17.458     {   
  17.459         const C&    operator * () const
  17.460         {            
  17.461             OVR_ASSERT(Index >= 0 && Index <= (SPInt)pHash->pTable->SizeMask);
  17.462             return pHash->E(Index).Value;
  17.463         }
  17.464 
  17.465         const C*    operator -> () const
  17.466         {
  17.467             OVR_ASSERT(Index >= 0 && Index <= (SPInt)pHash->pTable->SizeMask);
  17.468             return &pHash->E(Index).Value;
  17.469         }
  17.470 
  17.471         void    operator ++ ()
  17.472         {
  17.473             // Find next non-empty Entry.
  17.474             if (Index <= (SPInt)pHash->pTable->SizeMask)
  17.475             {
  17.476                 Index++;
  17.477                 while ((UPInt)Index <= pHash->pTable->SizeMask &&
  17.478                     pHash->E(Index).IsEmpty())
  17.479                 {
  17.480                     Index++;
  17.481                 }
  17.482             }
  17.483         }
  17.484 
  17.485         bool    operator == (const ConstIterator& it) const
  17.486         {
  17.487             if (IsEnd() && it.IsEnd())
  17.488             {
  17.489                 return true;
  17.490             }
  17.491             else
  17.492             {
  17.493                 return (pHash == it.pHash) && (Index == it.Index);
  17.494             }
  17.495         }
  17.496 
  17.497         bool    operator != (const ConstIterator& it) const
  17.498         {
  17.499             return ! (*this == it);
  17.500         }
  17.501 
  17.502 
  17.503         bool    IsEnd() const
  17.504         {
  17.505             return (pHash == NULL) || 
  17.506                 (pHash->pTable == NULL) || 
  17.507                 (Index > (SPInt)pHash->pTable->SizeMask);
  17.508         }
  17.509 
  17.510         ConstIterator()
  17.511             : pHash(NULL), Index(0)
  17.512         { }
  17.513 
  17.514     public:
  17.515         // Constructor was intentionally made public to allow create
  17.516         // iterator with arbitrary index.
  17.517         ConstIterator(const SelfType* h, SPInt index)
  17.518             : pHash(h), Index(index)
  17.519         { }
  17.520 
  17.521         const SelfType* GetContainer() const
  17.522         {
  17.523             return pHash;
  17.524         }
  17.525         SPInt GetIndex() const
  17.526         {
  17.527             return Index;
  17.528         }
  17.529 
  17.530     protected:
  17.531         friend class HashSetBase<C, HashF, AltHashF, Allocator, Entry>;
  17.532 
  17.533         const SelfType* pHash;
  17.534         SPInt           Index;
  17.535     };
  17.536 
  17.537     friend struct ConstIterator;
  17.538 
  17.539 
  17.540     // Non-const Iterator; Get most of it from ConstIterator.
  17.541     struct Iterator : public ConstIterator
  17.542     {      
  17.543         // Allow non-const access to entries.
  17.544         C&  operator*() const
  17.545         {            
  17.546             OVR_ASSERT(ConstIterator::Index >= 0 && ConstIterator::Index <= (SPInt)ConstIterator::pHash->pTable->SizeMask);
  17.547             return const_cast<SelfType*>(ConstIterator::pHash)->E(ConstIterator::Index).Value;
  17.548         }    
  17.549 
  17.550         C*  operator->() const 
  17.551         {
  17.552             return &(operator*());
  17.553         }
  17.554 
  17.555         Iterator()
  17.556             : ConstIterator(NULL, 0)
  17.557         { }
  17.558 
  17.559         // Removes current element from Hash
  17.560         void Remove()
  17.561         {
  17.562             RemoveAlt(operator*());
  17.563         }
  17.564 
  17.565         template <class K>
  17.566         void RemoveAlt(const K& key)
  17.567         {
  17.568             SelfType*   phash = const_cast<SelfType*>(ConstIterator::pHash);
  17.569             //Entry*      ee = &phash->E(ConstIterator::Index);
  17.570             //const C&    key = ee->Value;
  17.571 
  17.572             UPInt       hashValue = AltHashF()(key);
  17.573             SPInt       index     = hashValue & phash->pTable->SizeMask;
  17.574 
  17.575             Entry*      e = &phash->E(index);
  17.576 
  17.577             // If empty node or occupied by collider, we have nothing to remove.
  17.578             if (e->IsEmpty() || (e->GetCachedHash(phash->pTable->SizeMask) != (UPInt)index))
  17.579                 return;        
  17.580 
  17.581             // Save index
  17.582             SPInt   naturalIndex = index;
  17.583             SPInt   prevIndex    = -1;
  17.584 
  17.585             while ((e->GetCachedHash(phash->pTable->SizeMask) != (UPInt)naturalIndex) || !(e->Value == key))
  17.586             {
  17.587                 // Keep looking through the chain.
  17.588                 prevIndex   = index;
  17.589                 index       = e->NextInChain;
  17.590                 if (index == -1)
  17.591                     return; // End of chain, item not found
  17.592                 e = &phash->E(index);
  17.593             }
  17.594 
  17.595             if (index == (SPInt)ConstIterator::Index)
  17.596             {
  17.597                 // Found it - our item is at index
  17.598                 if (naturalIndex == index)
  17.599                 {
  17.600                     // If we have a follower, move it to us
  17.601                     if (!e->IsEndOfChain())
  17.602                     {               
  17.603                         Entry*  enext = &phash->E(e->NextInChain);
  17.604                         e->Clear();
  17.605                         new (e) Entry(*enext);
  17.606                         // Point us to the follower's cell that will be cleared
  17.607                         e = enext;
  17.608                         --ConstIterator::Index;
  17.609                     }
  17.610                 }
  17.611                 else
  17.612                 {
  17.613                     // We are not at natural index, so deal with the prev items next index
  17.614                     phash->E(prevIndex).NextInChain = e->NextInChain;
  17.615                 }
  17.616 
  17.617                 // Clear us, of the follower cell that was moved.
  17.618                 e->Clear();
  17.619                 phash->pTable->EntryCount --;
  17.620             }
  17.621             else 
  17.622                 OVR_ASSERT(0); //?
  17.623         }
  17.624 
  17.625     private:
  17.626         friend class HashSetBase<C, HashF, AltHashF, Allocator, Entry>;
  17.627 
  17.628         Iterator(SelfType* h, SPInt i0)
  17.629             : ConstIterator(h, i0)
  17.630         { }
  17.631     };
  17.632 
  17.633     friend struct Iterator;
  17.634 
  17.635     Iterator    Begin()
  17.636     {
  17.637         if (pTable == 0)
  17.638             return Iterator(NULL, 0);
  17.639 
  17.640         // Scan till we hit the First valid Entry.
  17.641         UPInt  i0 = 0;
  17.642         while (i0 <= pTable->SizeMask && E(i0).IsEmpty())
  17.643         {
  17.644             i0++;
  17.645         }
  17.646         return Iterator(this, i0);
  17.647     }
  17.648     Iterator        End()           { return Iterator(NULL, 0); }
  17.649 
  17.650     ConstIterator   Begin() const   { return const_cast<SelfType*>(this)->Begin();     }
  17.651     ConstIterator   End() const     { return const_cast<SelfType*>(this)->End();   }
  17.652 
  17.653     template<class K>
  17.654     Iterator Find(const K& key)
  17.655     {
  17.656         SPInt index = findIndex(key);
  17.657         if (index >= 0)        
  17.658             return Iterator(this, index);        
  17.659         return Iterator(NULL, 0);
  17.660     }
  17.661 
  17.662     template<class K>
  17.663     Iterator FindAlt(const K& key)
  17.664     {
  17.665         SPInt index = findIndexAlt(key);
  17.666         if (index >= 0)        
  17.667             return Iterator(this, index);        
  17.668         return Iterator(NULL, 0);
  17.669     }
  17.670 
  17.671     template<class K>
  17.672     ConstIterator Find(const K& key) const       { return const_cast<SelfType*>(this)->Find(key); }
  17.673 
  17.674     template<class K>
  17.675     ConstIterator FindAlt(const K& key) const    { return const_cast<SelfType*>(this)->FindAlt(key); }
  17.676 
  17.677 private:
  17.678     // Find the index of the matching Entry.  If no match, then return -1.
  17.679     template<class K>
  17.680     SPInt findIndex(const K& key) const
  17.681     {
  17.682         if (pTable == NULL)
  17.683             return -1;
  17.684         UPInt hashValue = HashF()(key) & pTable->SizeMask;
  17.685         return findIndexCore(key, hashValue);
  17.686     }
  17.687 
  17.688     template<class K>
  17.689     SPInt findIndexAlt(const K& key) const
  17.690     {
  17.691         if (pTable == NULL)
  17.692             return -1;
  17.693         UPInt hashValue = AltHashF()(key) & pTable->SizeMask;
  17.694         return findIndexCore(key, hashValue);
  17.695     }
  17.696 
  17.697     // Find the index of the matching Entry.  If no match, then return -1.
  17.698     template<class K>
  17.699     SPInt findIndexCore(const K& key, UPInt hashValue) const
  17.700     {
  17.701         // Table must exist.
  17.702         OVR_ASSERT(pTable != 0);
  17.703         // Hash key must be 'and-ed' by the caller.
  17.704         OVR_ASSERT((hashValue & ~pTable->SizeMask) == 0);
  17.705 
  17.706         UPInt           index = hashValue;
  17.707         const Entry*    e     = &E(index);
  17.708 
  17.709         // If empty or occupied by a collider, not found.
  17.710         if (e->IsEmpty() || (e->GetCachedHash(pTable->SizeMask) != index))
  17.711             return -1;
  17.712 
  17.713         while(1)
  17.714         {
  17.715             OVR_ASSERT(e->GetCachedHash(pTable->SizeMask) == hashValue);
  17.716 
  17.717             if (e->GetCachedHash(pTable->SizeMask) == hashValue && e->Value == key)
  17.718             {
  17.719                 // Found it.
  17.720                 return index;
  17.721             }
  17.722             // Values can not be equal at this point.
  17.723             // That would mean that the hash key for the same value differs.
  17.724             OVR_ASSERT(!(e->Value == key));
  17.725 
  17.726             // Keep looking through the chain.
  17.727             index = e->NextInChain;
  17.728             if (index == (UPInt)-1)
  17.729                 break; // end of chain
  17.730 
  17.731             e = &E(index);
  17.732             OVR_ASSERT(!e->IsEmpty());
  17.733         }
  17.734         return -1;
  17.735     }
  17.736 
  17.737 
  17.738     // Add a new value to the HashSet table, under the specified key.
  17.739     template<class CRef>
  17.740     void add(const CRef& key, UPInt hashValue)
  17.741     {
  17.742         CheckExpand();
  17.743         hashValue &= pTable->SizeMask;
  17.744 
  17.745         pTable->EntryCount++;
  17.746 
  17.747         SPInt   index        = hashValue;
  17.748         Entry*  naturalEntry = &(E(index));
  17.749 
  17.750         if (naturalEntry->IsEmpty())
  17.751         {
  17.752             // Put the new Entry in.
  17.753             new (naturalEntry) Entry(key, -1);
  17.754         }
  17.755         else
  17.756         {
  17.757             // Find a blank spot.
  17.758             SPInt blankIndex = index;
  17.759             do {
  17.760                 blankIndex = (blankIndex + 1) & pTable->SizeMask;
  17.761             } while(!E(blankIndex).IsEmpty());
  17.762 
  17.763             Entry*  blankEntry = &E(blankIndex);
  17.764 
  17.765             if (naturalEntry->GetCachedHash(pTable->SizeMask) == (UPInt)index)
  17.766             {
  17.767                 // Collision.  Link into this chain.
  17.768 
  17.769                 // Move existing list head.
  17.770                 new (blankEntry) Entry(*naturalEntry);    // placement new, copy ctor
  17.771 
  17.772                 // Put the new info in the natural Entry.
  17.773                 naturalEntry->Value       = key;
  17.774                 naturalEntry->NextInChain = blankIndex;
  17.775             }
  17.776             else
  17.777             {
  17.778                 // Existing Entry does not naturally
  17.779                 // belong in this slot.  Existing
  17.780                 // Entry must be moved.
  17.781 
  17.782                 // Find natural location of collided element (i.e. root of chain)
  17.783                 SPInt collidedIndex = naturalEntry->GetCachedHash(pTable->SizeMask);
  17.784                 OVR_ASSERT(collidedIndex >= 0 && collidedIndex <= (SPInt)pTable->SizeMask);
  17.785                 for (;;)
  17.786                 {
  17.787                     Entry*  e = &E(collidedIndex);
  17.788                     if (e->NextInChain == index)
  17.789                     {
  17.790                         // Here's where we need to splice.
  17.791                         new (blankEntry) Entry(*naturalEntry);
  17.792                         e->NextInChain = blankIndex;
  17.793                         break;
  17.794                     }
  17.795                     collidedIndex = e->NextInChain;
  17.796                     OVR_ASSERT(collidedIndex >= 0 && collidedIndex <= (SPInt)pTable->SizeMask);
  17.797                 }
  17.798 
  17.799                 // Put the new data in the natural Entry.
  17.800                 naturalEntry->Value       = key;
  17.801                 naturalEntry->NextInChain = -1;                
  17.802             }            
  17.803         }
  17.804 
  17.805         // Record hash value: has effect only if cached node is used.
  17.806         naturalEntry->SetCachedHash(hashValue);
  17.807     }
  17.808 
  17.809     // Index access helpers.
  17.810     Entry& E(UPInt index)
  17.811     {
  17.812         // Must have pTable and access needs to be within bounds.
  17.813         OVR_ASSERT(index <= pTable->SizeMask);
  17.814         return *(((Entry*) (pTable + 1)) + index);
  17.815     }
  17.816     const Entry& E(UPInt index) const
  17.817     {        
  17.818         OVR_ASSERT(index <= pTable->SizeMask);
  17.819         return *(((Entry*) (pTable + 1)) + index);
  17.820     }
  17.821 
  17.822 
  17.823     // Resize the HashSet table to the given size (Rehash the
  17.824     // contents of the current table).  The arg is the number of
  17.825     // HashSet table entries, not the number of elements we should
  17.826     // actually contain (which will be less than this).
  17.827     void    setRawCapacity(UPInt newSize)    
  17.828     {
  17.829         if (newSize == 0)
  17.830         {
  17.831             // Special case.
  17.832             Clear();
  17.833             return;
  17.834         }
  17.835 
  17.836         // Minimum size; don't incur rehashing cost when expanding
  17.837         // very small tables. Not that we perform this check before 
  17.838         // 'log2f' call to avoid fp exception with newSize == 1.
  17.839         if (newSize < HashMinSize)        
  17.840             newSize = HashMinSize;       
  17.841         else
  17.842         {
  17.843             // Force newSize to be a power of two.
  17.844             int bits = Alg::UpperBit(newSize-1) + 1; // Chop( Log2f((float)(newSize-1)) + 1);
  17.845             OVR_ASSERT((UPInt(1) << bits) >= newSize);
  17.846             newSize = UPInt(1) << bits;
  17.847         }
  17.848 
  17.849         SelfType  newHash;
  17.850         newHash.pTable = (TableType*)
  17.851             Allocator::Alloc(                
  17.852                 sizeof(TableType) + sizeof(Entry) * newSize);
  17.853         // Need to do something on alloc failure!
  17.854         OVR_ASSERT(newHash.pTable);
  17.855 
  17.856         newHash.pTable->EntryCount = 0;
  17.857         newHash.pTable->SizeMask = newSize - 1;
  17.858         UPInt i, n;
  17.859 
  17.860         // Mark all entries as empty.
  17.861         for (i = 0; i < newSize; i++)
  17.862             newHash.E(i).NextInChain = -2;
  17.863 
  17.864         // Copy stuff to newHash
  17.865         if (pTable)
  17.866         {            
  17.867             for (i = 0, n = pTable->SizeMask; i <= n; i++)
  17.868             {
  17.869                 Entry*  e = &E(i);
  17.870                 if (e->IsEmpty() == false)
  17.871                 {
  17.872                     // Insert old Entry into new HashSet.
  17.873                     newHash.Add(e->Value);
  17.874                     // placement delete of old element
  17.875                     e->Clear();
  17.876                 }
  17.877             }
  17.878 
  17.879             // Delete our old data buffer.
  17.880             Allocator::Free(pTable);
  17.881         }
  17.882 
  17.883         // Steal newHash's data.
  17.884         pTable = newHash.pTable;
  17.885         newHash.pTable = NULL;
  17.886     }
  17.887 
  17.888     struct TableType
  17.889     {
  17.890         UPInt EntryCount;
  17.891         UPInt SizeMask;
  17.892         // Entry array follows this structure
  17.893         // in memory.
  17.894     };
  17.895     TableType*  pTable;
  17.896 };
  17.897 
  17.898 
  17.899 
  17.900 //-----------------------------------------------------------------------------------
  17.901 template<class C, class HashF = FixedSizeHash<C>,
  17.902          class AltHashF = HashF, 
  17.903          class Allocator = ContainerAllocator<C>,
  17.904          class Entry = HashsetCachedEntry<C, HashF> >
  17.905 class HashSet : public HashSetBase<C, HashF, AltHashF, Allocator, Entry>
  17.906 {
  17.907 public:
  17.908     typedef HashSetBase<C, HashF, AltHashF, Allocator, Entry> BaseType;
  17.909     typedef HashSet<C, HashF, AltHashF, Allocator, Entry>     SelfType;
  17.910 
  17.911     HashSet()                                      {   }
  17.912     HashSet(int sizeHint) : BaseType(sizeHint)     {   }
  17.913     HashSet(const SelfType& src) : BaseType(src)   {   }
  17.914     ~HashSet()                                     {   }
  17.915 
  17.916     void operator = (const SelfType& src)   { BaseType::Assign(src); }
  17.917 
  17.918     // Set a new or existing value under the key, to the value.
  17.919     // Pass a different class of 'key' so that assignment reference object
  17.920     // can be passed instead of the actual object.
  17.921     template<class CRef>
  17.922     void Set(const CRef& key)
  17.923     {
  17.924         BaseType::Set(key);
  17.925     }
  17.926 
  17.927     template<class CRef>
  17.928     inline void Add(const CRef& key)
  17.929     {
  17.930         BaseType::Add(key);
  17.931     }
  17.932 
  17.933     // Hint the bucket count to >= n.
  17.934     void Resize(UPInt n)    
  17.935     {
  17.936         BaseType::SetCapacity(n);
  17.937     }
  17.938 
  17.939     // Size the HashSet so that it can comfortably contain the given
  17.940     // number of elements.  If the HashSet already contains more
  17.941     // elements than newSize, then this may be a no-op.
  17.942     void SetCapacity(UPInt newSize)
  17.943     {
  17.944         BaseType::SetCapacity(newSize);
  17.945     }
  17.946 
  17.947 };
  17.948 
  17.949 // HashSet with uncached hash code; declared for convenience.
  17.950 template<class C, class HashF = FixedSizeHash<C>,
  17.951                   class AltHashF = HashF,
  17.952                   class Allocator = ContainerAllocator<C> >
  17.953 class HashSetUncached : public HashSet<C, HashF, AltHashF, Allocator, HashsetEntry<C, HashF> >
  17.954 {
  17.955 public:
  17.956     
  17.957     typedef HashSetUncached<C, HashF, AltHashF, Allocator>                  SelfType;
  17.958     typedef HashSet<C, HashF, AltHashF, Allocator, HashsetEntry<C, HashF> > BaseType;
  17.959 
  17.960     // Delegated constructors.
  17.961     HashSetUncached()                                        { }
  17.962     HashSetUncached(int sizeHint) : BaseType(sizeHint)       { }
  17.963     HashSetUncached(const SelfType& src) : BaseType(src)     { }
  17.964     ~HashSetUncached()                                       { }
  17.965     
  17.966     void    operator = (const SelfType& src)
  17.967     {
  17.968         BaseType::operator = (src);
  17.969     }
  17.970 };
  17.971 
  17.972 
  17.973 //-----------------------------------------------------------------------------------
  17.974 // ***** Hash hash table implementation
  17.975 
  17.976 // Node for Hash - necessary so that Hash can delegate its implementation
  17.977 // to HashSet.
  17.978 template<class C, class U, class HashF>
  17.979 struct HashNode
  17.980 {
  17.981     typedef HashNode<C, U, HashF>   SelfType;
  17.982     typedef C                       FirstType;
  17.983     typedef U                       SecondType;
  17.984 
  17.985     C   First;
  17.986     U   Second;
  17.987 
  17.988     // NodeRef is used to allow passing of elements into HashSet
  17.989     // without using a temporary object.
  17.990     struct NodeRef
  17.991     {
  17.992         const C*   pFirst;
  17.993         const U*   pSecond;
  17.994 
  17.995         NodeRef(const C& f, const U& s) : pFirst(&f), pSecond(&s) { }
  17.996         NodeRef(const NodeRef& src)     : pFirst(src.pFirst), pSecond(src.pSecond) { }
  17.997 
  17.998         // Enable computation of ghash_node_hashf.
  17.999         inline UPInt GetHash() const            { return HashF()(*pFirst); } 
 17.1000         // Necessary conversion to allow HashNode::operator == to work.
 17.1001         operator const C& () const              { return *pFirst; }
 17.1002     };
 17.1003 
 17.1004     // Note: No default constructor is necessary.
 17.1005      HashNode(const HashNode& src) : First(src.First), Second(src.Second)    { }
 17.1006      HashNode(const NodeRef& src) : First(*src.pFirst), Second(*src.pSecond)  { }
 17.1007     void operator = (const NodeRef& src)  { First  = *src.pFirst; Second = *src.pSecond; }
 17.1008 
 17.1009     template<class K>
 17.1010     bool operator == (const K& src) const   { return (First == src); }
 17.1011 
 17.1012     template<class K>
 17.1013     static UPInt CalcHash(const K& data)   { return HashF()(data); }
 17.1014     inline UPInt GetHash() const           { return HashF()(First); }
 17.1015 
 17.1016     // Hash functors used with this node. A separate functor is used for alternative
 17.1017     // key lookup so that it does not need to access the '.First' element.    
 17.1018     struct NodeHashF
 17.1019     {    
 17.1020         template<class K>
 17.1021         UPInt operator()(const K& data) const { return data.GetHash(); } 
 17.1022     };    
 17.1023     struct NodeAltHashF
 17.1024     {
 17.1025         template<class K>
 17.1026         UPInt operator()(const K& data) const { return HashNode<C,U,HashF>::CalcHash(data); }
 17.1027     };
 17.1028 };
 17.1029 
 17.1030 
 17.1031 
 17.1032 // **** Extra hashset_entry types to allow NodeRef construction.
 17.1033 
 17.1034 // The big difference between the below types and the ones used in hash_set is that
 17.1035 // these allow initializing the node with 'typename C::NodeRef& keyRef', which
 17.1036 // is critical to avoid temporary node allocation on stack when using placement new.
 17.1037 
 17.1038 // Compact hash table Entry type that re-computes hash keys during hash traversal.
 17.1039 // Good to use if the hash function is cheap or the hash value is already cached in C.
 17.1040 template<class C, class HashF>
 17.1041 class HashsetNodeEntry
 17.1042 {
 17.1043 public:
 17.1044     // Internal chaining for collisions.
 17.1045     SPInt NextInChain;
 17.1046     C     Value;
 17.1047 
 17.1048     HashsetNodeEntry()
 17.1049         : NextInChain(-2) { }
 17.1050     HashsetNodeEntry(const HashsetNodeEntry& e)
 17.1051         : NextInChain(e.NextInChain), Value(e.Value) { }
 17.1052     HashsetNodeEntry(const C& key, SPInt next)
 17.1053         : NextInChain(next), Value(key) { }    
 17.1054     HashsetNodeEntry(const typename C::NodeRef& keyRef, SPInt next)
 17.1055         : NextInChain(next), Value(keyRef) { }
 17.1056 
 17.1057     bool    IsEmpty() const             { return NextInChain == -2;  }
 17.1058     bool    IsEndOfChain() const        { return NextInChain == -1;  }
 17.1059     UPInt   GetCachedHash(UPInt maskValue) const  { return HashF()(Value) & maskValue; }
 17.1060     void    SetCachedHash(UPInt hashValue)        { OVR_UNUSED(hashValue); }
 17.1061 
 17.1062     void    Clear()
 17.1063     {        
 17.1064         Value.~C(); // placement delete
 17.1065         NextInChain = -2;
 17.1066     }
 17.1067     // Free is only used from dtor of hash; Clear is used during regular operations:
 17.1068     // assignment, hash reallocations, value reassignments, so on.
 17.1069     void    Free() { Clear(); }
 17.1070 };
 17.1071 
 17.1072 // Hash table Entry type that caches the Entry hash value for nodes, so that it
 17.1073 // does not need to be re-computed during access.
 17.1074 template<class C, class HashF>
 17.1075 class HashsetCachedNodeEntry
 17.1076 {
 17.1077 public:
 17.1078     // Internal chaining for collisions.
 17.1079     SPInt NextInChain;
 17.1080     UPInt HashValue;
 17.1081     C     Value;
 17.1082 
 17.1083     HashsetCachedNodeEntry()
 17.1084         : NextInChain(-2) { }
 17.1085     HashsetCachedNodeEntry(const HashsetCachedNodeEntry& e)
 17.1086         : NextInChain(e.NextInChain), HashValue(e.HashValue), Value(e.Value) { }
 17.1087     HashsetCachedNodeEntry(const C& key, SPInt next)
 17.1088         : NextInChain(next), Value(key) { }
 17.1089     HashsetCachedNodeEntry(const typename C::NodeRef& keyRef, SPInt next)
 17.1090         : NextInChain(next), Value(keyRef) { }
 17.1091 
 17.1092     bool    IsEmpty() const            { return NextInChain == -2;  }
 17.1093     bool    IsEndOfChain() const       { return NextInChain == -1;  }
 17.1094     UPInt   GetCachedHash(UPInt maskValue) const  { OVR_UNUSED(maskValue); return HashValue; }
 17.1095     void    SetCachedHash(UPInt hashValue)        { HashValue = hashValue; }
 17.1096 
 17.1097     void    Clear()
 17.1098     {
 17.1099         Value.~C();
 17.1100         NextInChain = -2;
 17.1101     }
 17.1102     // Free is only used from dtor of hash; Clear is used during regular operations:
 17.1103     // assignment, hash reallocations, value reassignments, so on.
 17.1104     void    Free() { Clear(); }
 17.1105 };
 17.1106 
 17.1107 
 17.1108 //-----------------------------------------------------------------------------------
 17.1109 template<class C, class U,
 17.1110          class HashF = FixedSizeHash<C>,
 17.1111          class Allocator = ContainerAllocator<C>,
 17.1112          class HashNode = OVR::HashNode<C,U,HashF>,
 17.1113          class Entry = HashsetCachedNodeEntry<HashNode, typename HashNode::NodeHashF>,
 17.1114          class Container =  HashSet<HashNode, typename HashNode::NodeHashF,
 17.1115              typename HashNode::NodeAltHashF, Allocator,
 17.1116              Entry> >
 17.1117 class Hash
 17.1118 {
 17.1119 public:
 17.1120     OVR_MEMORY_REDEFINE_NEW(Hash)
 17.1121 
 17.1122     // Types used for hash_set.
 17.1123     typedef U                                                           ValueType;
 17.1124     typedef Hash<C, U, HashF, Allocator, HashNode, Entry, Container>    SelfType;
 17.1125 
 17.1126     // Actual hash table itself, implemented as hash_set.
 17.1127     Container   mHash;
 17.1128 
 17.1129 public:
 17.1130     Hash()     {  }
 17.1131     Hash(int sizeHint) : mHash(sizeHint)                        { }
 17.1132     Hash(const SelfType& src) : mHash(src.mHash)                { }
 17.1133     ~Hash()                                                     { }
 17.1134 
 17.1135     void    operator = (const SelfType& src)    { mHash = src.mHash; }
 17.1136 
 17.1137     // Remove all entries from the Hash table.
 17.1138     inline void    Clear() { mHash.Clear(); }
 17.1139     // Returns true if the Hash is empty.
 17.1140     inline bool    IsEmpty() const { return mHash.IsEmpty(); }
 17.1141 
 17.1142     // Access (set).
 17.1143     inline void    Set(const C& key, const U& value)
 17.1144     {
 17.1145         typename HashNode::NodeRef e(key, value);
 17.1146         mHash.Set(e);
 17.1147     }
 17.1148     inline void    Add(const C& key, const U& value)
 17.1149     {
 17.1150         typename HashNode::NodeRef e(key, value);
 17.1151         mHash.Add(e);
 17.1152     }
 17.1153 
 17.1154     // Removes an element by clearing its Entry.
 17.1155     inline void     Remove(const C& key)
 17.1156     {   
 17.1157         mHash.RemoveAlt(key);
 17.1158     }
 17.1159     template<class K>
 17.1160     inline void     RemoveAlt(const K& key)
 17.1161     {   
 17.1162         mHash.RemoveAlt(key);
 17.1163     }
 17.1164 
 17.1165     // Retrieve the value under the given key.    
 17.1166     //  - If there's no value under the key, then return false and leave *pvalue alone.
 17.1167     //  - If there is a value, return true, and Set *Pvalue to the Entry's value.
 17.1168     //  - If value == NULL, return true or false according to the presence of the key.    
 17.1169     bool    Get(const C& key, U* pvalue) const   
 17.1170     {
 17.1171         const HashNode* p = mHash.GetAlt(key);
 17.1172         if (p)
 17.1173         {
 17.1174             if (pvalue)
 17.1175                 *pvalue = p->Second;
 17.1176             return true;
 17.1177         }
 17.1178         return false;
 17.1179     }
 17.1180 
 17.1181     template<class K>
 17.1182     bool    GetAlt(const K& key, U* pvalue) const   
 17.1183     {
 17.1184         const HashNode* p = mHash.GetAlt(key);
 17.1185         if (p)
 17.1186         {
 17.1187             if (pvalue)
 17.1188                 *pvalue = p->Second;
 17.1189             return true;
 17.1190         }
 17.1191         return false;
 17.1192     }
 17.1193 
 17.1194     // Retrieve the pointer to a value under the given key.    
 17.1195     //  - If there's no value under the key, then return NULL.    
 17.1196     //  - If there is a value, return the pointer.    
 17.1197     inline U*  Get(const C& key)
 17.1198     {
 17.1199         HashNode* p = mHash.GetAlt(key);
 17.1200         return p ? &p->Second : 0;
 17.1201     }
 17.1202     inline const U* Get(const C& key) const
 17.1203     {
 17.1204         const HashNode* p = mHash.GetAlt(key);
 17.1205         return p ? &p->Second : 0;
 17.1206     }
 17.1207 
 17.1208     template<class K>
 17.1209     inline U*  GetAlt(const K& key)
 17.1210     {
 17.1211         HashNode* p = mHash.GetAlt(key);
 17.1212         return p ? &p->Second : 0;
 17.1213     }
 17.1214     template<class K>
 17.1215     inline const U* GetAlt(const K& key) const
 17.1216     {
 17.1217         const HashNode* p = mHash.GetAlt(key);
 17.1218         return p ? &p->Second : 0;
 17.1219     }
 17.1220 
 17.1221     // Sizing methods - delegate to Hash.
 17.1222     inline UPInt   GetSize() const              { return mHash.GetSize(); }    
 17.1223     inline void    Resize(UPInt n)              { mHash.Resize(n); }
 17.1224     inline void    SetCapacity(UPInt newSize)   { mHash.SetCapacity(newSize); }
 17.1225 
 17.1226     // Iterator API, like STL.
 17.1227     typedef typename Container::ConstIterator   ConstIterator;
 17.1228     typedef typename Container::Iterator        Iterator;
 17.1229 
 17.1230     inline Iterator        Begin()              { return mHash.Begin(); }
 17.1231     inline Iterator        End()                { return mHash.End(); }
 17.1232     inline ConstIterator   Begin() const        { return mHash.Begin(); }
 17.1233     inline ConstIterator   End() const          { return mHash.End();   }
 17.1234 
 17.1235     Iterator        Find(const C& key)          { return mHash.FindAlt(key);  }
 17.1236     ConstIterator   Find(const C& key) const    { return mHash.FindAlt(key);  }
 17.1237 
 17.1238     template<class K>
 17.1239     Iterator        FindAlt(const K& key)       { return mHash.FindAlt(key);  }
 17.1240     template<class K>
 17.1241     ConstIterator   FindAlt(const K& key) const { return mHash.FindAlt(key);  }
 17.1242 };
 17.1243 
 17.1244 
 17.1245 
 17.1246 // Hash with uncached hash code; declared for convenience.
 17.1247 template<class C, class U, class HashF = FixedSizeHash<C>, class Allocator = ContainerAllocator<C> >
 17.1248 class HashUncached
 17.1249     : public Hash<C, U, HashF, Allocator, HashNode<C,U,HashF>,
 17.1250                    HashsetNodeEntry<HashNode<C,U,HashF>, typename HashNode<C,U,HashF>::NodeHashF> >
 17.1251 {
 17.1252 public:
 17.1253     typedef HashUncached<C, U, HashF, Allocator>                SelfType;
 17.1254     typedef Hash<C, U, HashF, Allocator, HashNode<C,U,HashF>,
 17.1255                  HashsetNodeEntry<HashNode<C,U,HashF>,
 17.1256                  typename HashNode<C,U,HashF>::NodeHashF> >     BaseType;
 17.1257 
 17.1258     // Delegated constructors.
 17.1259     HashUncached()                                        { }
 17.1260     HashUncached(int sizeHint) : BaseType(sizeHint)       { }
 17.1261     HashUncached(const SelfType& src) : BaseType(src)     { }
 17.1262     ~HashUncached()                                       { }
 17.1263     void operator = (const SelfType& src)                 { BaseType::operator = (src); }
 17.1264 };
 17.1265 
 17.1266 
 17.1267 
 17.1268 // And identity hash in which keys serve as hash value. Can be uncached,
 17.1269 // since hash computation is assumed cheap.
 17.1270 template<class C, class U, class Allocator = ContainerAllocator<C>, class HashF = IdentityHash<C> >
 17.1271 class HashIdentity
 17.1272     : public HashUncached<C, U, HashF, Allocator>
 17.1273 {
 17.1274 public:
 17.1275     typedef HashIdentity<C, U, Allocator, HashF> SelfType;
 17.1276     typedef HashUncached<C, U, HashF, Allocator> BaseType;
 17.1277 
 17.1278     // Delegated constructors.
 17.1279     HashIdentity()                                        { }
 17.1280     HashIdentity(int sizeHint) : BaseType(sizeHint)       { }
 17.1281     HashIdentity(const SelfType& src) : BaseType(src)     { }
 17.1282     ~HashIdentity()                                       { }
 17.1283     void operator = (const SelfType& src)                 { BaseType::operator = (src); }
 17.1284 };
 17.1285 
 17.1286 
 17.1287 } // OVR
 17.1288 
 17.1289 
 17.1290 #ifdef OVR_DEFINE_NEW
 17.1291 #define new OVR_DEFINE_NEW
 17.1292 #endif
 17.1293 
 17.1294 #endif
 17.1295 \ No newline at end of file
    18.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    18.2 +++ b/libovr/Src/Kernel/OVR_KeyCodes.h	Sat Sep 14 16:14:59 2013 +0300
    18.3 @@ -0,0 +1,1 @@
    18.4 +/************************************************************************************
    18.5 
    18.6 PublicHeader:   OVR.h
    18.7 Filename    :   OVR_KeyCodes.h
    18.8 Content     :   Common keyboard constants
    18.9 Created     :   September 19, 2012
   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 #ifndef OVR_KeyCodes_h
   18.20 #define OVR_KeyCodes_h
   18.21 
   18.22 namespace OVR {
   18.23 
   18.24 //-----------------------------------------------------------------------------------
   18.25 // ***** KeyCode
   18.26 
   18.27 // KeyCode enumeration defines platform-independent keyboard key constants.
   18.28 // Note that Key_A through Key_Z are mapped to capital ascii constants.
   18.29 
   18.30 enum KeyCode
   18.31 {
   18.32     // Key_None indicates that no key was specified.
   18.33     Key_None            = 0, 
   18.34 
   18.35     // A through Z and numbers 0 through 9.
   18.36     Key_A               = 65,
   18.37     Key_B,
   18.38     Key_C,
   18.39     Key_D,
   18.40     Key_E,
   18.41     Key_F,
   18.42     Key_G,
   18.43     Key_H,
   18.44     Key_I,
   18.45     Key_J,
   18.46     Key_K,
   18.47     Key_L,
   18.48     Key_M,
   18.49     Key_N,
   18.50     Key_O,
   18.51     Key_P,
   18.52     Key_Q,
   18.53     Key_R,
   18.54     Key_S,
   18.55     Key_T,
   18.56     Key_U,
   18.57     Key_V,
   18.58     Key_W,
   18.59     Key_X,
   18.60     Key_Y,
   18.61     Key_Z,
   18.62     Key_Num0            = 48,
   18.63     Key_Num1,
   18.64     Key_Num2,
   18.65     Key_Num3,
   18.66     Key_Num4,
   18.67     Key_Num5,
   18.68     Key_Num6,
   18.69     Key_Num7,
   18.70     Key_Num8,
   18.71     Key_Num9,
   18.72 
   18.73     // Numeric keypad.
   18.74     Key_KP_0            = 0xa0,
   18.75     Key_KP_1,
   18.76     Key_KP_2,
   18.77     Key_KP_3,
   18.78     Key_KP_4,
   18.79     Key_KP_5,
   18.80     Key_KP_6,
   18.81     Key_KP_7,
   18.82     Key_KP_8,
   18.83     Key_KP_9,
   18.84     Key_KP_Multiply,
   18.85     Key_KP_Add,
   18.86     Key_KP_Enter,
   18.87     Key_KP_Subtract,
   18.88     Key_KP_Decimal,
   18.89     Key_KP_Divide,
   18.90     
   18.91     // Function keys.
   18.92     Key_F1              = 0xb0,
   18.93     Key_F2,
   18.94     Key_F3,
   18.95     Key_F4,
   18.96     Key_F5,
   18.97     Key_F6,
   18.98     Key_F7,
   18.99     Key_F8,
  18.100     Key_F9,
  18.101     Key_F10,
  18.102     Key_F11,
  18.103     Key_F12,
  18.104     Key_F13,
  18.105     Key_F14,
  18.106     Key_F15,
  18.107     
  18.108     // Other keys.
  18.109     Key_Backspace       = 8,
  18.110     Key_Tab,
  18.111     Key_Clear           = 12,
  18.112     Key_Return,
  18.113     Key_Shift           = 16,
  18.114     Key_Control,
  18.115     Key_Alt,
  18.116     Key_Pause,
  18.117     Key_CapsLock        = 20, // Toggle
  18.118     Key_Escape          = 27,
  18.119     Key_Space           = 32,
  18.120     Key_Quote           = 39,
  18.121     Key_PageUp          = 0xc0,
  18.122     Key_PageDown,
  18.123     Key_End,
  18.124     Key_Home,
  18.125     Key_Left,
  18.126     Key_Up,
  18.127     Key_Right,
  18.128     Key_Down,
  18.129     Key_Insert,
  18.130     Key_Delete,
  18.131     Key_Help,
  18.132     
  18.133     Key_Comma           = 44,
  18.134     Key_Minus,
  18.135     Key_Slash           = 47,
  18.136     Key_Period,
  18.137     Key_NumLock         = 144, // Toggle
  18.138     Key_ScrollLock      = 145, // Toggle
  18.139     
  18.140     Key_Semicolon       = 59,
  18.141     Key_Equal           = 61,
  18.142     Key_Bar             = 192,
  18.143     Key_BracketLeft     = 91,
  18.144     Key_Backslash,
  18.145     Key_BracketRight,
  18.146 
  18.147     Key_OEM_AX          = 0xE1,  //  'AX' key on Japanese AX keyboard
  18.148     Key_OEM_102         = 0xE2,  //  "<>" or "\|" on RT 102-key keyboard.
  18.149     Key_ICO_HELP        = 0xE3,  //  Help key on ICO
  18.150     Key_ICO_00          = 0xE4,  //  00 key on ICO
  18.151 
  18.152     Key_Meta,
  18.153 
  18.154     // Total number of keys.
  18.155     Key_CodeCount
  18.156 };
  18.157 
  18.158 
  18.159 //-----------------------------------------------------------------------------------
  18.160 
  18.161 class KeyModifiers 
  18.162 {
  18.163 public:
  18.164     enum
  18.165     {
  18.166         Key_ShiftPressed    = 0x01,
  18.167         Key_CtrlPressed     = 0x02,
  18.168         Key_AltPressed      = 0x04,
  18.169         Key_MetaPressed     = 0x08,
  18.170         Key_CapsToggled     = 0x10,
  18.171         Key_NumToggled      = 0x20,
  18.172         Key_ScrollToggled   = 0x40,
  18.173 
  18.174         Initialized_Bit     = 0x80,
  18.175         Initialized_Mask    = 0xFF
  18.176     };
  18.177     unsigned char States;
  18.178 
  18.179     KeyModifiers() : States(0) { }
  18.180         KeyModifiers(unsigned char st) : States((unsigned char)(st | Initialized_Bit)) { }
  18.181 
  18.182     void Reset() { States = 0; }
  18.183 
  18.184     bool IsShiftPressed() const { return (States & Key_ShiftPressed) != 0; }
  18.185     bool IsCtrlPressed() const  { return (States & Key_CtrlPressed) != 0; }
  18.186     bool IsAltPressed() const   { return (States & Key_AltPressed) != 0; }
  18.187     bool IsMetaPressed() const  { return (States & Key_MetaPressed) != 0; }
  18.188     bool IsCapsToggled() const  { return (States & Key_CapsToggled) != 0; }
  18.189     bool IsNumToggled() const   { return (States & Key_NumToggled) != 0; }
  18.190     bool IsScrollToggled() const{ return (States & Key_ScrollToggled) != 0; }
  18.191 
  18.192     void SetShiftPressed(bool v = true)  { (v) ? States |= Key_ShiftPressed : States &= ~Key_ShiftPressed; }
  18.193     void SetCtrlPressed(bool v = true)   { (v) ? States |= Key_CtrlPressed  : States &= ~Key_CtrlPressed; }
  18.194     void SetAltPressed(bool v = true)    { (v) ? States |= Key_AltPressed   : States &= ~Key_AltPressed; }
  18.195     void SetMetaPressed(bool v = true)   { (v) ? States |= Key_MetaPressed  : States &= ~Key_MetaPressed; }
  18.196     void SetCapsToggled(bool v = true)   { (v) ? States |= Key_CapsToggled  : States &= ~Key_CapsToggled; }
  18.197     void SetNumToggled(bool v = true)    { (v) ? States |= Key_NumToggled   : States &= ~Key_NumToggled; }
  18.198     void SetScrollToggled(bool v = true) { (v) ? States |= Key_ScrollToggled: States &= ~Key_ScrollToggled; }
  18.199 
  18.200     bool IsInitialized() const { return (States & Initialized_Mask) != 0; }
  18.201 };
  18.202 
  18.203 
  18.204 //-----------------------------------------------------------------------------------
  18.205 
  18.206 /*
  18.207 enum PadKeyCode
  18.208 {
  18.209     Pad_None, // Indicates absence of key code.
  18.210     Pad_Back,
  18.211     Pad_Start,
  18.212     Pad_A,
  18.213     Pad_B,
  18.214     Pad_X,
  18.215     Pad_Y,
  18.216     Pad_R1,  // RightShoulder;
  18.217     Pad_L1,  // LeftShoulder;
  18.218     Pad_R2,  // RightTrigger;
  18.219     Pad_L2,  // LeftTrigger;
  18.220     Pad_Up,
  18.221     Pad_Down,
  18.222     Pad_Right,
  18.223     Pad_Left,
  18.224     Pad_Plus,
  18.225     Pad_Minus,
  18.226     Pad_1,
  18.227     Pad_2,
  18.228     Pad_H,
  18.229     Pad_C,
  18.230     Pad_Z,
  18.231     Pad_O,
  18.232     Pad_T,
  18.233     Pad_S,
  18.234     Pad_Select,
  18.235     Pad_Home,
  18.236     Pad_RT,  // RightThumb;
  18.237     Pad_LT   // LeftThumb;
  18.238 };
  18.239 */
  18.240 
  18.241 } // OVR
  18.242 
  18.243 #endif
  18.244 \ No newline at end of file
    19.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    19.2 +++ b/libovr/Src/Kernel/OVR_List.h	Sat Sep 14 16:14:59 2013 +0300
    19.3 @@ -0,0 +1,1 @@
    19.4 +/************************************************************************************
    19.5 
    19.6 PublicHeader:   OVR
    19.7 Filename    :   OVR_List.h
    19.8 Content     :   Template implementation for doubly-connected linked List
    19.9 Created     :   September 19, 2012
   19.10 Notes       : 
   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_List_h
   19.21 #define OVR_List_h
   19.22 
   19.23 #include "OVR_Types.h"
   19.24 
   19.25 namespace OVR {
   19.26 
   19.27 //-----------------------------------------------------------------------------------
   19.28 // ***** ListNode
   19.29 //
   19.30 // Base class for the elements of the intrusive linked list.
   19.31 // To store elements in the List do:
   19.32 //
   19.33 // struct MyData : ListNode<MyData>
   19.34 // {
   19.35 //     . . .
   19.36 // };
   19.37 
   19.38 template<class T>
   19.39 struct ListNode
   19.40 {
   19.41     union {
   19.42         T*    pPrev;
   19.43         void* pVoidPrev;
   19.44     };
   19.45     union {
   19.46         T*    pNext;
   19.47         void* pVoidNext;
   19.48     };
   19.49 
   19.50     void    RemoveNode()
   19.51     {
   19.52         pPrev->pNext = pNext;
   19.53         pNext->pPrev = pPrev;
   19.54     }
   19.55 
   19.56     // Removes us from the list and inserts pnew there instead.
   19.57     void    ReplaceNodeWith(T* pnew)
   19.58     {
   19.59         pPrev->pNext = pnew;
   19.60         pNext->pPrev = pnew;
   19.61         pnew->pPrev = pPrev;
   19.62         pnew->pNext = pNext;
   19.63     }
   19.64        
   19.65     // Inserts the argument linked list node after us in the list.
   19.66     void    InsertNodeAfter(T* p)
   19.67     {
   19.68         p->pPrev          = pNext->pPrev; // this
   19.69         p->pNext          = pNext;
   19.70         pNext->pPrev      = p;
   19.71         pNext             = p;
   19.72     }
   19.73     // Inserts the argument linked list node before us in the list.
   19.74     void    InsertNodeBefore(T* p)
   19.75     {
   19.76         p->pNext          = pNext->pPrev; // this
   19.77         p->pPrev          = pPrev;
   19.78         pPrev->pNext      = p;
   19.79         pPrev             = p;
   19.80     }
   19.81 
   19.82     void    Alloc_MoveTo(ListNode<T>* pdest)
   19.83     {
   19.84         pdest->pNext = pNext;
   19.85         pdest->pPrev = pPrev;
   19.86         pPrev->pNext = (T*)pdest;
   19.87         pNext->pPrev = (T*)pdest;
   19.88     }
   19.89 };
   19.90 
   19.91 
   19.92 //------------------------------------------------------------------------
   19.93 // ***** List
   19.94 //
   19.95 // Doubly linked intrusive list. 
   19.96 // The data type must be derived from ListNode.
   19.97 // 
   19.98 // Adding:   PushFront(), PushBack().
   19.99 // Removing: Remove() - the element must be in the list!
  19.100 // Moving:   BringToFront(), SendToBack() - the element must be in the list!
  19.101 //
  19.102 // Iterating:
  19.103 //    MyData* data = MyList.GetFirst();
  19.104 //    while (!MyList.IsNull(data))
  19.105 //    {
  19.106 //        . . .
  19.107 //        data = MyList.GetNext(data);
  19.108 //    }
  19.109 //
  19.110 // Removing:
  19.111 //    MyData* data = MyList.GetFirst();
  19.112 //    while (!MyList.IsNull(data))
  19.113 //    {
  19.114 //        MyData* next = MyList.GetNext(data);
  19.115 //        if (ToBeRemoved(data))
  19.116 //             MyList.Remove(data);
  19.117 //        data = next;
  19.118 //    }
  19.119 //
  19.120 
  19.121 // List<> represents a doubly-linked list of T, where each T must derive
  19.122 // from ListNode<B>. B specifies the base class that was directly
  19.123 // derived from ListNode, and is only necessary if there is an intermediate
  19.124 // inheritance chain.
  19.125 
  19.126 template<class T, class B = T> class List
  19.127 {
  19.128 public:
  19.129     typedef T ValueType;
  19.130 
  19.131     List()
  19.132     {
  19.133         Root.pNext = Root.pPrev = (ValueType*)&Root;
  19.134     }
  19.135 
  19.136     void Clear()
  19.137     {
  19.138         Root.pNext = Root.pPrev = (ValueType*)&Root;
  19.139     }
  19.140 
  19.141     const ValueType* GetFirst() const { return (const ValueType*)Root.pNext; }
  19.142     const ValueType* GetLast () const { return (const ValueType*)Root.pPrev; }
  19.143           ValueType* GetFirst()       { return (ValueType*)Root.pNext; }
  19.144           ValueType* GetLast ()       { return (ValueType*)Root.pPrev; }
  19.145 
  19.146     // Determine if list is empty (i.e.) points to itself.
  19.147     // Go through void* access to avoid issues with strict-aliasing optimizing out the
  19.148     // access after RemoveNode(), etc.
  19.149     bool IsEmpty()                   const { return Root.pVoidNext == (const T*)(const B*)&Root; }
  19.150     bool IsFirst(const ValueType* p) const { return p == Root.pNext; }
  19.151     bool IsLast (const ValueType* p) const { return p == Root.pPrev; }
  19.152     bool IsNull (const ValueType* p) const { return p == (const T*)(const B*)&Root; }
  19.153 
  19.154     inline static const ValueType* GetPrev(const ValueType* p) { return (const ValueType*)p->pPrev; }
  19.155     inline static const ValueType* GetNext(const ValueType* p) { return (const ValueType*)p->pNext; }
  19.156     inline static       ValueType* GetPrev(      ValueType* p) { return (ValueType*)p->pPrev; }
  19.157     inline static       ValueType* GetNext(      ValueType* p) { return (ValueType*)p->pNext; }
  19.158 
  19.159     void PushFront(ValueType* p)
  19.160     {
  19.161         p->pNext          =  Root.pNext;
  19.162         p->pPrev          = (ValueType*)&Root;
  19.163         Root.pNext->pPrev =  p;
  19.164         Root.pNext        =  p;
  19.165     }
  19.166 
  19.167     void PushBack(ValueType* p)
  19.168     {
  19.169         p->pPrev          =  Root.pPrev;
  19.170         p->pNext          = (ValueType*)&Root;
  19.171         Root.pPrev->pNext =  p;
  19.172         Root.pPrev        =  p;
  19.173     }
  19.174 
  19.175     static void Remove(ValueType* p)
  19.176     {
  19.177         p->pPrev->pNext = p->pNext;
  19.178         p->pNext->pPrev = p->pPrev;
  19.179     }
  19.180 
  19.181     void BringToFront(ValueType* p)
  19.182     {
  19.183         Remove(p);
  19.184         PushFront(p);
  19.185     }
  19.186 
  19.187     void SendToBack(ValueType* p)
  19.188     {
  19.189         Remove(p);
  19.190         PushBack(p);
  19.191     }
  19.192 
  19.193     // Appends the contents of the argument list to the front of this list;
  19.194     // items are removed from the argument list.
  19.195     void PushListToFront(List<T>& src)
  19.196     {
  19.197         if (!src.IsEmpty())
  19.198         {
  19.199             ValueType* pfirst = src.GetFirst();
  19.200             ValueType* plast  = src.GetLast();
  19.201             src.Clear();
  19.202             plast->pNext   = Root.pNext;
  19.203             pfirst->pPrev  = (ValueType*)&Root;
  19.204             Root.pNext->pPrev = plast;
  19.205             Root.pNext        = pfirst;
  19.206         }
  19.207     }
  19.208 
  19.209     void PushListToBack(List<T>& src)
  19.210     {
  19.211         if (!src.IsEmpty())
  19.212         {
  19.213             ValueType* pfirst = src.GetFirst();
  19.214             ValueType* plast  = src.GetLast();
  19.215             src.Clear();
  19.216             plast->pNext   = (ValueType*)&Root;
  19.217             pfirst->pPrev  = Root.pPrev;
  19.218             Root.pPrev->pNext = pfirst;
  19.219             Root.pPrev        = plast;
  19.220         }
  19.221     }
  19.222 
  19.223     // Removes all source list items after (and including) the 'pfirst' node from the 
  19.224     // source list and adds them to out list.
  19.225     void    PushFollowingListItemsToFront(List<T>& src, ValueType *pfirst)
  19.226     {
  19.227         if (pfirst != &src.Root)
  19.228         {
  19.229             ValueType *plast = src.Root.pPrev;
  19.230 
  19.231             // Remove list remainder from source.
  19.232             pfirst->pPrev->pNext = (ValueType*)&src.Root;
  19.233             src.Root.pPrev      = pfirst->pPrev;
  19.234             // Add the rest of the items to list.
  19.235             plast->pNext      = Root.pNext;
  19.236             pfirst->pPrev     = (ValueType*)&Root;
  19.237             Root.pNext->pPrev = plast;
  19.238             Root.pNext        = pfirst;
  19.239         }
  19.240     }
  19.241 
  19.242     // Removes all source list items up to but NOT including the 'pend' node from the 
  19.243     // source list and adds them to out list.
  19.244     void    PushPrecedingListItemsToFront(List<T>& src, ValueType *ptail)
  19.245     {
  19.246         if (src.GetFirst() != ptail)
  19.247         {
  19.248             ValueType *pfirst = src.Root.pNext;
  19.249             ValueType *plast  = ptail->pPrev;
  19.250 
  19.251             // Remove list remainder from source.
  19.252             ptail->pPrev      = (ValueType*)&src.Root;
  19.253             src.Root.pNext    = ptail;            
  19.254 
  19.255             // Add the rest of the items to list.
  19.256             plast->pNext      = Root.pNext;
  19.257             pfirst->pPrev     = (ValueType*)&Root;
  19.258             Root.pNext->pPrev = plast;
  19.259             Root.pNext        = pfirst;
  19.260         }
  19.261     }
  19.262 
  19.263 
  19.264     // Removes a range of source list items starting at 'pfirst' and up to, but not including 'pend',
  19.265     // and adds them to out list. Note that source items MUST already be in the list.
  19.266     void    PushListItemsToFront(ValueType *pfirst, ValueType *pend)
  19.267     {
  19.268         if (pfirst != pend)
  19.269         {
  19.270             ValueType *plast = pend->pPrev;
  19.271 
  19.272             // Remove list remainder from source.
  19.273             pfirst->pPrev->pNext = pend;
  19.274             pend->pPrev          = pfirst->pPrev;
  19.275             // Add the rest of the items to list.
  19.276             plast->pNext      = Root.pNext;
  19.277             pfirst->pPrev     = (ValueType*)&Root;
  19.278             Root.pNext->pPrev = plast;
  19.279             Root.pNext        = pfirst;
  19.280         }
  19.281     }
  19.282 
  19.283 
  19.284     void    Alloc_MoveTo(List<T>* pdest)
  19.285     {
  19.286         if (IsEmpty())
  19.287             pdest->Clear();
  19.288         else
  19.289         {
  19.290             pdest->Root.pNext = Root.pNext;
  19.291             pdest->Root.pPrev = Root.pPrev;
  19.292 
  19.293             Root.pNext->pPrev = (ValueType*)&pdest->Root;
  19.294             Root.pPrev->pNext = (ValueType*)&pdest->Root;
  19.295         }        
  19.296     }
  19.297 
  19.298 
  19.299 private:
  19.300     // Copying is prohibited
  19.301     List(const List<T>&);
  19.302     const List<T>& operator = (const List<T>&);
  19.303 
  19.304     ListNode<B> Root;
  19.305 };
  19.306 
  19.307 
  19.308 //------------------------------------------------------------------------
  19.309 // ***** FreeListElements
  19.310 //
  19.311 // Remove all elements in the list and free them in the allocator
  19.312 
  19.313 template<class List, class Allocator>
  19.314 void FreeListElements(List& list, Allocator& allocator)
  19.315 {
  19.316     typename List::ValueType* self = list.GetFirst();
  19.317     while(!list.IsNull(self))
  19.318     {
  19.319         typename List::ValueType* next = list.GetNext(self);
  19.320         allocator.Free(self);
  19.321         self = next;
  19.322     }
  19.323     list.Clear();
  19.324 }
  19.325 
  19.326 } // OVR
  19.327 
  19.328 #endif
  19.329 \ No newline at end of file
    20.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    20.2 +++ b/libovr/Src/Kernel/OVR_Log.cpp	Sat Sep 14 16:14:59 2013 +0300
    20.3 @@ -0,0 +1,1 @@
    20.4 +/************************************************************************************
    20.5 
    20.6 Filename    :   OVR_Log.cpp
    20.7 Content     :   Logging support
    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_Log.h"
   20.20 #include "OVR_Std.h"
   20.21 #include <stdarg.h>
   20.22 #include <stdio.h>
   20.23 
   20.24 #if defined(OVR_OS_WIN32)
   20.25 #include <windows.h>
   20.26 #elif defined(OVR_OS_ANDROID)
   20.27 #include <android/log.h>
   20.28 #endif
   20.29 
   20.30 namespace OVR {
   20.31 
   20.32 // Global Log pointer.
   20.33 Log* volatile OVR_GlobalLog = 0;
   20.34 
   20.35 //-----------------------------------------------------------------------------------
   20.36 // ***** Log Implementation
   20.37 
   20.38 Log::~Log()
   20.39 {
   20.40     // Clear out global log
   20.41     if (this == OVR_GlobalLog)
   20.42     {
   20.43         // TBD: perhaps we should ASSERT if this happens before system shutdown?
   20.44         OVR_GlobalLog = 0;
   20.45     }
   20.46 }
   20.47 
   20.48 void Log::LogMessageVarg(LogMessageType messageType, const char* fmt, va_list argList)
   20.49 {
   20.50     if ((messageType & LoggingMask) == 0)
   20.51         return;
   20.52 #ifndef OVR_BUILD_DEBUG
   20.53     if (IsDebugMessage(messageType))
   20.54         return;
   20.55 #endif
   20.56 
   20.57     char buffer[MaxLogBufferMessageSize];
   20.58     FormatLog(buffer, MaxLogBufferMessageSize, messageType, fmt, argList);
   20.59     DefaultLogOutput(buffer, IsDebugMessage(messageType));
   20.60 }
   20.61 
   20.62 void OVR::Log::LogMessage(LogMessageType messageType, const char* pfmt, ...)
   20.63 {
   20.64     va_list argList;
   20.65     va_start(argList, pfmt);
   20.66     LogMessageVarg(messageType, pfmt, argList);
   20.67     va_end(argList);
   20.68 }
   20.69 
   20.70 
   20.71 void Log::FormatLog(char* buffer, unsigned bufferSize, LogMessageType messageType,
   20.72                     const char* fmt, va_list argList)
   20.73 {    
   20.74     bool addNewline = true;
   20.75 
   20.76     switch(messageType)
   20.77     {
   20.78     case Log_Error:         OVR_strcpy(buffer, bufferSize, "Error: ");     break;
   20.79     case Log_Debug:         OVR_strcpy(buffer, bufferSize, "Debug: ");     break;
   20.80     case Log_Assert:        OVR_strcpy(buffer, bufferSize, "Assert: ");    break;
   20.81     case Log_Text:       buffer[0] = 0; addNewline = false; break;
   20.82     case Log_DebugText:  buffer[0] = 0; addNewline = false; break;
   20.83     default:        
   20.84         buffer[0] = 0;
   20.85         addNewline = false;
   20.86         break;
   20.87     }
   20.88 
   20.89     UPInt prefixLength = OVR_strlen(buffer);
   20.90     char *buffer2      = buffer + prefixLength;
   20.91     OVR_vsprintf(buffer2, bufferSize - prefixLength, fmt, argList);
   20.92 
   20.93     if (addNewline)
   20.94         OVR_strcat(buffer, bufferSize, "\n");
   20.95 }
   20.96 
   20.97 
   20.98 void Log::DefaultLogOutput(const char* formattedText, bool debug)
   20.99 {
  20.100 
  20.101 #if defined(OVR_OS_WIN32)
  20.102     // Under Win32, output regular messages to console if it exists; debug window otherwise.
  20.103     static DWORD dummyMode;
  20.104     static bool  hasConsole = (GetStdHandle(STD_OUTPUT_HANDLE) != INVALID_HANDLE_VALUE) &&
  20.105                               (GetConsoleMode(GetStdHandle(STD_OUTPUT_HANDLE), &dummyMode));
  20.106 
  20.107     if (!hasConsole || debug)
  20.108     {
  20.109         ::OutputDebugStringA(formattedText);
  20.110     }
  20.111     else
  20.112     {
  20.113          fputs(formattedText, stdout);
  20.114     }    
  20.115 
  20.116 #elif defined(OVR_OS_ANDROID)
  20.117     __android_log_write(ANDROID_LOG_INFO, "OVR", formattedText);
  20.118 
  20.119 #else
  20.120     fputs(formattedText, stdout);
  20.121 
  20.122 #endif
  20.123 
  20.124     // Just in case.
  20.125     OVR_UNUSED2(formattedText, debug);
  20.126 }
  20.127 
  20.128 
  20.129 //static
  20.130 void Log::SetGlobalLog(Log *log)
  20.131 {
  20.132     OVR_GlobalLog = log;
  20.133 }
  20.134 //static
  20.135 Log* Log::GetGlobalLog()
  20.136 {
  20.137 // No global log by default?
  20.138 //    if (!OVR_GlobalLog)
  20.139 //        OVR_GlobalLog = GetDefaultLog();
  20.140     return OVR_GlobalLog;
  20.141 }
  20.142 
  20.143 //static
  20.144 Log* Log::GetDefaultLog()
  20.145 {
  20.146     // Create default log pointer statically so that it can be used
  20.147     // even during startup.
  20.148     static Log defaultLog;
  20.149     return &defaultLog;
  20.150 }
  20.151 
  20.152 
  20.153 //-----------------------------------------------------------------------------------
  20.154 // ***** Global Logging functions
  20.155 
  20.156 #define OVR_LOG_FUNCTION_IMPL(Name)  \
  20.157     void Log##Name(const char* fmt, ...) \
  20.158     {                                                                    \
  20.159         if (OVR_GlobalLog)                                               \
  20.160         {                                                                \
  20.161             va_list argList; va_start(argList, fmt);                     \
  20.162             OVR_GlobalLog->LogMessageVarg(Log_##Name, fmt, argList);  \
  20.163             va_end(argList);                                             \
  20.164         }                                                                \
  20.165     }
  20.166 
  20.167 OVR_LOG_FUNCTION_IMPL(Text)
  20.168 OVR_LOG_FUNCTION_IMPL(Error)
  20.169 
  20.170 #ifdef OVR_BUILD_DEBUG
  20.171 OVR_LOG_FUNCTION_IMPL(DebugText)
  20.172 OVR_LOG_FUNCTION_IMPL(Debug)
  20.173 OVR_LOG_FUNCTION_IMPL(Assert)
  20.174 #endif
  20.175 
  20.176 } // OVR
  20.177 \ No newline at end of file
    21.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    21.2 +++ b/libovr/Src/Kernel/OVR_Log.h	Sat Sep 14 16:14:59 2013 +0300
    21.3 @@ -0,0 +1,1 @@
    21.4 +/************************************************************************************
    21.5 
    21.6 PublicHeader:   OVR
    21.7 Filename    :   OVR_Log.h
    21.8 Content     :   Logging support
    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_Log_h
   21.21 #define OVR_Log_h
   21.22 
   21.23 #include "OVR_Types.h"
   21.24 #include <stdarg.h>
   21.25 
   21.26 namespace OVR {
   21.27 
   21.28 //-----------------------------------------------------------------------------------
   21.29 // ***** Logging Constants
   21.30 
   21.31 // LogMaskConstants defined bit mask constants that describe what log messages
   21.32 // should be displayed.
   21.33 enum LogMaskConstants
   21.34 {
   21.35     LogMask_Regular = 0x100,
   21.36     LogMask_Debug   = 0x200,
   21.37     LogMask_None    = 0,
   21.38     LogMask_All     = LogMask_Regular|LogMask_Debug
   21.39 };
   21.40 
   21.41 
   21.42 // LogMessageType describes the type of the log message, controls when it is
   21.43 // displayed and what prefix/suffix is given to it. Messages are subdivided into
   21.44 // regular and debug logging types. Debug logging is only generated in debug builds.
   21.45 //
   21.46 // Log_Text         - General output text displayed without prefix or new-line.
   21.47 //                    Used in OVR libraries for general log flow messages
   21.48 //                    such as "Device Initialized".
   21.49 //
   21.50 // Log_Error        - Error message output with "Error: %s\n", intended for
   21.51 //                    application/sample-level use only, in cases where an expected
   21.52 //                    operation failed. OVR libraries should not use this internally,
   21.53 //                    reporting status codes instead.
   21.54 //
   21.55 // Log_DebugText    - Message without prefix or new lines; output in Debug build only.
   21.56 //
   21.57 // Log_Debug        - Debug-build only message, formatted with "Debug: %s\n".
   21.58 //                    Intended to comment on incorrect API usage that doesn't lead
   21.59 //                    to crashes but can be avoided with proper use.
   21.60 //                    There is no Debug Error on purpose, since real errors should
   21.61 //                    be handled by API user.
   21.62 //
   21.63 // Log_Assert      -  Debug-build only message, formatted with "Assert: %s\n".
   21.64 //                    Intended for severe unrecoverable conditions in library
   21.65 //                    source code. Generated though OVR_ASSERT_MSG(c, "Text").
   21.66 
   21.67 enum LogMessageType
   21.68 {    
   21.69     // General Logging
   21.70     Log_Text        = LogMask_Regular | 0,    
   21.71     Log_Error       = LogMask_Regular | 1, // "Error: %s\n".
   21.72     
   21.73     // Debug-only messages (not generated in release build)
   21.74     Log_DebugText   = LogMask_Debug | 0,
   21.75     Log_Debug       = LogMask_Debug | 1,   // "Debug: %s\n".
   21.76     Log_Assert      = LogMask_Debug | 2,   // "Assert: %s\n".
   21.77 };
   21.78 
   21.79 
   21.80 // LOG_VAARG_ATTRIBUTE macro, enforces printf-style fromatting for message types
   21.81 #ifdef __GNUC__
   21.82 #  define OVR_LOG_VAARG_ATTRIBUTE(a,b) __attribute__((format (printf, a, b)))
   21.83 #else
   21.84 #  define OVR_LOG_VAARG_ATTRIBUTE(a,b)
   21.85 #endif
   21.86 
   21.87 
   21.88 //-----------------------------------------------------------------------------------
   21.89 // ***** Log
   21.90 
   21.91 // Log defines a base class interface that can be implemented to catch both
   21.92 // debug and runtime messages.
   21.93 // Debug logging can be overridden by calling Log::SetGlobalLog.
   21.94 
   21.95 class Log
   21.96 {
   21.97     friend class System;
   21.98 public: 
   21.99     Log(unsigned logMask = LogMask_Debug) : LoggingMask(logMask) { }
  21.100     virtual ~Log();
  21.101 
  21.102     // Log formating buffer size used by default LogMessageVarg. Longer strings are truncated.
  21.103     enum { MaxLogBufferMessageSize = 2048 };
  21.104 
  21.105     unsigned        GetLoggingMask() const            { return LoggingMask; }
  21.106     void            SetLoggingMask(unsigned logMask)  { LoggingMask = logMask; }
  21.107 
  21.108     // This virtual function receives all the messages,
  21.109     // developers should override this function in order to do custom logging
  21.110     virtual void    LogMessageVarg(LogMessageType messageType, const char* fmt, va_list argList);
  21.111 
  21.112     // Call the logging function with specific message type, with no type filtering.
  21.113     void            LogMessage(LogMessageType messageType,
  21.114                                const char* fmt, ...) OVR_LOG_VAARG_ATTRIBUTE(3,4);
  21.115 
  21.116 
  21.117     // Helper used by LogMessageVarg to format the log message, writing the resulting
  21.118     // string into buffer. It formats text based on fmt and appends prefix/new line
  21.119     // based on LogMessageType.
  21.120     static void     FormatLog(char* buffer, unsigned bufferSize, LogMessageType messageType,
  21.121                               const char* fmt, va_list argList);
  21.122 
  21.123     // Default log output implementation used by by LogMessageVarg.
  21.124     // Debug flag may be used to re-direct output on some platforms, but doesn't
  21.125     // necessarily disable it in release builds; that is the job of the called.    
  21.126     static void     DefaultLogOutput(const char* textBuffer, bool debug);
  21.127 
  21.128     // Determines if the specified message type is for debugging only.
  21.129     static bool     IsDebugMessage(LogMessageType messageType)
  21.130     {
  21.131         return (messageType & LogMask_Debug) != 0;
  21.132     }
  21.133 
  21.134     // *** Global APIs
  21.135 
  21.136     // Global Log registration APIs.
  21.137     //  - Global log is used for OVR_DEBUG messages. Set global log to null (0)
  21.138     //    to disable all logging.
  21.139     static void     SetGlobalLog(Log *log);
  21.140     static Log*     GetGlobalLog();
  21.141 
  21.142     // Returns default log singleton instance.
  21.143     static Log*     GetDefaultLog();
  21.144 
  21.145     // Applies logMask to the default log and returns a pointer to it.
  21.146     // By default, only Debug logging is enabled, so to avoid SDK generating console
  21.147     // messages in user app (those are always disabled in release build,
  21.148     // even if the flag is set). This function is useful in System constructor.
  21.149     static Log*     ConfigureDefaultLog(unsigned logMask = LogMask_Debug)
  21.150     {
  21.151         Log* log = GetDefaultLog();
  21.152         log->SetLoggingMask(logMask);
  21.153         return log;
  21.154     }
  21.155 
  21.156 private:
  21.157     // Logging mask described by LogMaskConstants.
  21.158     unsigned    LoggingMask;
  21.159 };
  21.160 
  21.161 
  21.162 //-----------------------------------------------------------------------------------
  21.163 // ***** Global Logging Functions and Debug Macros
  21.164 
  21.165 // These functions will output text to global log with semantics described by
  21.166 // their LogMessageType.
  21.167 void LogText(const char* fmt, ...) OVR_LOG_VAARG_ATTRIBUTE(1,2);
  21.168 void LogError(const char* fmt, ...) OVR_LOG_VAARG_ATTRIBUTE(1,2);
  21.169 
  21.170 #ifdef OVR_BUILD_DEBUG
  21.171 
  21.172     // Debug build only logging.
  21.173     void LogDebugText(const char* fmt, ...) OVR_LOG_VAARG_ATTRIBUTE(1,2);
  21.174     void LogDebug(const char* fmt, ...) OVR_LOG_VAARG_ATTRIBUTE(1,2);
  21.175     void LogAssert(const char* fmt, ...) OVR_LOG_VAARG_ATTRIBUTE(1,2);
  21.176 
  21.177     // Macro to do debug logging, printf-style.
  21.178     // An extra set of set of parenthesis must be used around arguments,
  21.179     // as in: OVR_LOG_DEBUG(("Value %d", 2)).
  21.180     #define OVR_DEBUG_LOG(args)       do { OVR::LogDebug args; } while(0)
  21.181     #define OVR_DEBUG_LOG_TEXT(args)  do { OVR::LogDebugText args; } while(0)
  21.182 
  21.183     #define OVR_ASSERT_LOG(c, args)   do { if (!(c)) { OVR::LogAssert args; OVR_DEBUG_BREAK; } } while(0)
  21.184 
  21.185 #else
  21.186 
  21.187     // If not in debug build, macros do nothing.
  21.188     #define OVR_DEBUG_LOG(args)         ((void)0)
  21.189     #define OVR_DEBUG_LOG_TEXT(args)    ((void)0)
  21.190     #define OVR_ASSERT_LOG(c, args)     ((void)0)
  21.191 
  21.192 #endif
  21.193 
  21.194 } // OVR 
  21.195 
  21.196 #endif
  21.197 \ No newline at end of file
    22.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    22.2 +++ b/libovr/Src/Kernel/OVR_Math.cpp	Sat Sep 14 16:14:59 2013 +0300
    22.3 @@ -0,0 +1,1 @@
    22.4 +/************************************************************************************
    22.5 
    22.6 Filename    :   OVR_Math.h
    22.7 Content     :   Implementation of 3D primitives such as vectors, matrices.
    22.8 Created     :   September 4, 2012
    22.9 Authors     :   Andrew Reisse, Michael Antonov
   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_Math.h"
   22.20 
   22.21 #include <float.h>
   22.22 
   22.23 namespace OVR {
   22.24 
   22.25 
   22.26 //-------------------------------------------------------------------------------------
   22.27 // ***** Math
   22.28 
   22.29 
   22.30 // Single-precision Math constants class.
   22.31 const float Math<float>::Pi      = 3.1415926f;
   22.32 const float Math<float>::TwoPi   = 3.1415926f * 2;
   22.33 const float Math<float>::PiOver2 = 3.1415926f / 2.0f;
   22.34 const float Math<float>::PiOver4 = 3.1415926f / 4.0f;
   22.35 const float Math<float>::E       = 2.7182818f;
   22.36 
   22.37 const float Math<float>::MaxValue = FLT_MAX;
   22.38 const float Math<float>::MinPositiveValue = FLT_MIN;
   22.39 
   22.40 const float Math<float>::RadToDegreeFactor = 360.0f / Math<float>::TwoPi;
   22.41 const float Math<float>::DegreeToRadFactor = Math<float>::TwoPi / 360.0f;
   22.42 
   22.43 const float Math<float>::Tolerance = 0.00001f;
   22.44 const float Math<float>::SingularityRadius = 0.0000001f; // Use for Gimbal lock numerical problems
   22.45 
   22.46 
   22.47 // Double-precision Math constants class.
   22.48 const double Math<double>::Pi      = 3.14159265358979;
   22.49 const double Math<double>::TwoPi   = 3.14159265358979 * 2;
   22.50 const double Math<double>::PiOver2 = 3.14159265358979 / 2.0;
   22.51 const double Math<double>::PiOver4 = 3.14159265358979 / 4.0;
   22.52 const double Math<double>::E       = 2.71828182845905;
   22.53 
   22.54 const double Math<double>::MaxValue = DBL_MAX;
   22.55 const double Math<double>::MinPositiveValue = DBL_MIN;
   22.56 
   22.57 const double Math<double>::RadToDegreeFactor = 360.0 / Math<double>::TwoPi;
   22.58 const double Math<double>::DegreeToRadFactor = Math<double>::TwoPi / 360.0;
   22.59 
   22.60 const double Math<double>::Tolerance = 0.00001;
   22.61 const double Math<double>::SingularityRadius = 0.000000000001; // Use for Gimbal lock numerical problems
   22.62 
   22.63 
   22.64 
   22.65 //-------------------------------------------------------------------------------------
   22.66 // ***** Matrix4f
   22.67 
   22.68 
   22.69 Matrix4f Matrix4f::LookAtRH(const Vector3f& eye, const Vector3f& at, const Vector3f& up)
   22.70 {
   22.71     Vector3f z = (eye - at).Normalized();  // Forward
   22.72     Vector3f x = up.Cross(z).Normalized(); // Right
   22.73     Vector3f y = z.Cross(x);
   22.74 
   22.75     Matrix4f m(x.x,  x.y,  x.z,  -(x * eye),
   22.76                y.x,  y.y,  y.z,  -(y * eye),
   22.77                z.x,  z.y,  z.z,  -(z * eye),
   22.78                0,    0,    0,    1 );
   22.79     return m;
   22.80 }
   22.81 
   22.82 Matrix4f Matrix4f::LookAtLH(const Vector3f& eye, const Vector3f& at, const Vector3f& up)
   22.83 {
   22.84     Vector3f z = (at - eye).Normalized();  // Forward
   22.85     Vector3f x = up.Cross(z).Normalized(); // Right
   22.86     Vector3f y = z.Cross(x);
   22.87 
   22.88     Matrix4f m(x.x,  x.y,  x.z,  -(x * eye),
   22.89                y.x,  y.y,  y.z,  -(y * eye),
   22.90                z.x,  z.y,  z.z,  -(z * eye),
   22.91                0,    0,    0,    1 ); 
   22.92     return m;
   22.93 }
   22.94 
   22.95 
   22.96 Matrix4f Matrix4f::PerspectiveLH(float yfov, float aspect, float znear, float zfar)
   22.97 {
   22.98     Matrix4f m;
   22.99     float    tanHalfFov = tan(yfov * 0.5f);
  22.100 
  22.101     m.M[0][0] = 1.0f / (aspect * tanHalfFov);
  22.102     m.M[1][1] = 1.0f / tanHalfFov;
  22.103     m.M[2][2] = zfar / (zfar - znear);
  22.104     m.M[3][2] = 1.0f;
  22.105     m.M[2][3] = (zfar * znear) / (znear - zfar);
  22.106     m.M[3][3] = 0.0f;
  22.107 
  22.108     // Note: Post-projection matrix result assumes Left-Handed coordinate system,
  22.109     //       with Y up, X right and Z forward. This supports positive z-buffer values.
  22.110     return m;
  22.111 }
  22.112 
  22.113 
  22.114 Matrix4f Matrix4f::PerspectiveRH(float yfov, float aspect, float znear, float zfar)
  22.115 {
  22.116     Matrix4f m;
  22.117     float    tanHalfFov = tan(yfov * 0.5f);
  22.118   
  22.119     m.M[0][0] = 1.0f / (aspect * tanHalfFov);
  22.120     m.M[1][1] = 1.0f / tanHalfFov;
  22.121     m.M[2][2] = zfar / (znear - zfar);
  22.122    // m.M[2][2] = zfar / (zfar - znear);
  22.123     m.M[3][2] = -1.0f;
  22.124     m.M[2][3] = (zfar * znear) / (znear - zfar);
  22.125     m.M[3][3] = 0.0f;
  22.126 
  22.127     // Note: Post-projection matrix result assumes Left-Handed coordinate system,    
  22.128     //       with Y up, X right and Z forward. This supports positive z-buffer values.
  22.129     // This is the case even for RHS cooridnate input.       
  22.130     return m;
  22.131 }
  22.132 
  22.133 
  22.134 /*
  22.135 OffCenterLH
  22.136 
  22.137 2*zn/(r-l)   0            0              0
  22.138 0            2*zn/(t-b)   0              0
  22.139 (l+r)/(l-r)  (t+b)/(b-t)  zf/(zf-zn)     1
  22.140 0            0            zn*zf/(zn-zf)  0
  22.141 
  22.142 */
  22.143 
  22.144 
  22.145 Matrix4f Matrix4f::Ortho2D(float w, float h)
  22.146 {
  22.147     Matrix4f m;
  22.148     m.M[0][0] = 2.0f/w;
  22.149     m.M[1][1] = -2.0f/h;
  22.150     m.M[0][3] = -1.0;
  22.151     m.M[1][3] = 1.0;
  22.152     m.M[2][2] = 0;
  22.153     return m;
  22.154 }
  22.155 
  22.156 }
  22.157 \ No newline at end of file
    23.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    23.2 +++ b/libovr/Src/Kernel/OVR_Math.h	Sat Sep 14 16:14:59 2013 +0300
    23.3 @@ -0,0 +1,1 @@
    23.4 +/************************************************************************************
    23.5 
    23.6 PublicHeader:   OVR.h
    23.7 Filename    :   OVR_Math.h
    23.8 Content     :   Implementation of 3D primitives such as vectors, matrices.
    23.9 Created     :   September 4, 2012
   23.10 Authors     :   Andrew Reisse, Michael Antonov, Steve LaValle, Anna Yershova
   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_Math_h
   23.21 #define OVR_Math_h
   23.22 
   23.23 #include <assert.h>
   23.24 #include <stdlib.h>
   23.25 #include <math.h>
   23.26 
   23.27 #include "OVR_Types.h"
   23.28 #include "OVR_RefCount.h"
   23.29 
   23.30 namespace OVR {
   23.31 
   23.32 //-------------------------------------------------------------------------------------
   23.33 // Constants for 3D world/axis definitions.
   23.34 
   23.35 // Definitions of axes for coordinate and rotation conversions.
   23.36 enum Axis
   23.37 {
   23.38     Axis_X = 0, Axis_Y = 1, Axis_Z = 2
   23.39 };
   23.40 
   23.41 // RotateDirection describes the rotation direction around an axis, interpreted as follows:
   23.42 //  CW  - Clockwise while looking "down" from positive axis towards the origin.
   23.43 //  CCW - Counter-clockwise while looking from the positive axis towards the origin,
   23.44 //        which is in the negative axis direction.
   23.45 //  CCW is the default for the RHS coordinate system. Oculus standard RHS coordinate
   23.46 //  system defines Y up, X right, and Z back (pointing out from the screen). In this
   23.47 //  system Rotate_CCW around Z will specifies counter-clockwise rotation in XY plane.
   23.48 enum RotateDirection
   23.49 {
   23.50     Rotate_CCW = 1,
   23.51     Rotate_CW  = -1 
   23.52 };
   23.53 
   23.54 enum HandedSystem
   23.55 {
   23.56     Handed_R = 1, Handed_L = -1
   23.57 };
   23.58 
   23.59 // AxisDirection describes which way the axis points. Used by WorldAxes.
   23.60 enum AxisDirection
   23.61 {
   23.62     Axis_Up    =  2,
   23.63     Axis_Down  = -2,
   23.64     Axis_Right =  1,
   23.65     Axis_Left  = -1,
   23.66     Axis_In    =  3,
   23.67     Axis_Out   = -3
   23.68 };
   23.69 
   23.70 struct WorldAxes
   23.71 {
   23.72     AxisDirection XAxis, YAxis, ZAxis;
   23.73 
   23.74     WorldAxes(AxisDirection x, AxisDirection y, AxisDirection z)
   23.75         : XAxis(x), YAxis(y), ZAxis(z) 
   23.76     { OVR_ASSERT(abs(x) != abs(y) && abs(y) != abs(z) && abs(z) != abs(x));}
   23.77 };
   23.78 
   23.79 
   23.80 //-------------------------------------------------------------------------------------
   23.81 // ***** Math
   23.82 
   23.83 // Math class contains constants and functions. This class is a template specialized
   23.84 // per type, with Math<float> and Math<double> being distinct.
   23.85 template<class Type>
   23.86 class Math
   23.87 {  
   23.88 };
   23.89 
   23.90 // Single-precision Math constants class.
   23.91 template<>
   23.92 class Math<float>
   23.93 {
   23.94 public:
   23.95     static const float Pi;
   23.96     static const float TwoPi;
   23.97     static const float PiOver2;
   23.98     static const float PiOver4;
   23.99     static const float E;
  23.100 
  23.101     static const float MaxValue;          // Largest positive float Value
  23.102     static const float MinPositiveValue;  // Smallest possible positive value
  23.103 
  23.104     static const float RadToDegreeFactor;
  23.105     static const float DegreeToRadFactor;
  23.106 
  23.107     static const float Tolerance; //  0.00001f;
  23.108     static const float SingularityRadius; //0.00000000001f for Gimbal lock numerical problems
  23.109 };
  23.110 
  23.111 // Double-precision Math constants class.
  23.112 template<>
  23.113 class Math<double>
  23.114 {
  23.115 public:
  23.116     static const double Pi;
  23.117     static const double TwoPi;
  23.118     static const double PiOver2;
  23.119     static const double PiOver4;
  23.120     static const double E;
  23.121 
  23.122     static const double MaxValue;          // Largest positive double Value
  23.123     static const double MinPositiveValue;  // Smallest possible positive value
  23.124 
  23.125     static const double RadToDegreeFactor;
  23.126     static const double DegreeToRadFactor;
  23.127 
  23.128     static const double Tolerance; //  0.00001f;
  23.129     static const double SingularityRadius; //0.00000000001 for Gimbal lock numerical problems
  23.130 };
  23.131 
  23.132 typedef Math<float>  Mathf;
  23.133 typedef Math<double> Mathd;
  23.134 
  23.135 // Conversion functions between degrees and radians
  23.136 template<class FT>
  23.137 FT RadToDegree(FT rads) { return rads * Math<FT>::RadToDegreeFactor; }
  23.138 template<class FT>
  23.139 FT DegreeToRad(FT rads) { return rads * Math<FT>::DegreeToRadFactor; }
  23.140 
  23.141 template<class T>
  23.142 class Quat;
  23.143 
  23.144 //-------------------------------------------------------------------------------------
  23.145 // ***** Vector2f - 2D Vector2f
  23.146 
  23.147 // Vector2f represents a 2-dimensional vector or point in space,
  23.148 // consisting of coordinates x and y,
  23.149 
  23.150 template<class T>
  23.151 class Vector2
  23.152 {
  23.153 public:
  23.154     T x, y;
  23.155 
  23.156     Vector2() : x(0), y(0) { }
  23.157     Vector2(T x_, T y_) : x(x_), y(y_) { }
  23.158     explicit Vector2(T s) : x(s), y(s) { }
  23.159 
  23.160     bool     operator== (const Vector2& b) const  { return x == b.x && y == b.y; }
  23.161     bool     operator!= (const Vector2& b) const  { return x != b.x || y != b.y; }
  23.162              
  23.163     Vector2  operator+  (const Vector2& b) const  { return Vector2(x + b.x, y + b.y); }
  23.164     Vector2& operator+= (const Vector2& b)        { x += b.x; y += b.y; return *this; }
  23.165     Vector2  operator-  (const Vector2& b) const  { return Vector2(x - b.x, y - b.y); }
  23.166     Vector2& operator-= (const Vector2& b)        { x -= b.x; y -= b.y; return *this; }
  23.167     Vector2  operator- () const                   { return Vector2(-x, -y); }
  23.168 
  23.169     // Scalar multiplication/division scales vector.
  23.170     Vector2  operator*  (T s) const               { return Vector2(x*s, y*s); }
  23.171     Vector2& operator*= (T s)                     { x *= s; y *= s; return *this; }
  23.172 
  23.173     Vector2  operator/  (T s) const               { T rcp = T(1)/s;
  23.174                                                     return Vector2(x*rcp, y*rcp); }
  23.175     Vector2& operator/= (T s)                     { T rcp = T(1)/s;
  23.176                                                     x *= rcp; y *= rcp;
  23.177                                                     return *this; }
  23.178 
  23.179     // Compare two vectors for equality with tolerance. Returns true if vectors match withing tolerance.
  23.180     bool      Compare(const Vector2&b, T tolerance = Mathf::Tolerance)
  23.181     {
  23.182         return (fabs(b.x-x) < tolerance) && (fabs(b.y-y) < tolerance);
  23.183     }
  23.184     
  23.185     // Dot product overload.
  23.186     // Used to calculate angle q between two vectors among other things,
  23.187     // as (A dot B) = |a||b|cos(q).
  23.188     T     operator*  (const Vector2& b) const    { return x*b.x + y*b.y; }
  23.189 
  23.190     // Returns the angle from this vector to b, in radians.
  23.191     T       Angle(const Vector2& b) const        { return acos((*this * b)/(Length()*b.Length())); }
  23.192 
  23.193     // Return Length of the vector squared.
  23.194     T       LengthSq() const                     { return (x * x + y * y); }
  23.195     // Return vector length.
  23.196     T       Length() const                       { return sqrt(LengthSq()); }
  23.197 
  23.198     // Returns distance between two points represented by vectors.
  23.199     T       Distance(Vector2& b) const           { return (*this - b).Length(); }
  23.200     
  23.201     // Determine if this a unit vector.
  23.202     bool    IsNormalized() const                 { return fabs(LengthSq() - T(1)) < Math<T>::Tolerance; }
  23.203     // Normalize, convention vector length to 1.    
  23.204     void    Normalize()                          { *this /= Length(); }
  23.205     // Returns normalized (unit) version of the vector without modifying itself.
  23.206     Vector2 Normalized() const                   { return *this / Length(); }
  23.207 
  23.208     // Linearly interpolates from this vector to another.
  23.209     // Factor should be between 0.0 and 1.0, with 0 giving full value to this.
  23.210     Vector2 Lerp(const Vector2& b, T f) const    { return *this*(T(1) - f) + b*f; }
  23.211 
  23.212     // Projects this vector onto the argument; in other words,
  23.213     // A.Project(B) returns projection of vector A onto B.
  23.214     Vector2 ProjectTo(const Vector2& b) const    { return b * ((*this * b) / b.LengthSq()); }
  23.215 };
  23.216 
  23.217 
  23.218 typedef Vector2<float>  Vector2f;
  23.219 typedef Vector2<double> Vector2d;
  23.220 
  23.221 //-------------------------------------------------------------------------------------
  23.222 // ***** Vector3f - 3D Vector3f
  23.223 
  23.224 // Vector3f represents a 3-dimensional vector or point in space,
  23.225 // consisting of coordinates x, y and z.
  23.226 
  23.227 template<class T>
  23.228 class Vector3
  23.229 {
  23.230 public:
  23.231     T x, y, z;
  23.232 
  23.233     Vector3() : x(0), y(0), z(0) { }
  23.234     Vector3(T x_, T y_, T z_ = 0) : x(x_), y(y_), z(z_) { }
  23.235     explicit Vector3(T s) : x(s), y(s), z(s) { }
  23.236 
  23.237     bool     operator== (const Vector3& b) const  { return x == b.x && y == b.y && z == b.z; }
  23.238     bool     operator!= (const Vector3& b) const  { return x != b.x || y != b.y || z != b.z; }
  23.239              
  23.240     Vector3  operator+  (const Vector3& b) const  { return Vector3(x + b.x, y + b.y, z + b.z); }
  23.241     Vector3& operator+= (const Vector3& b)        { x += b.x; y += b.y; z += b.z; return *this; }
  23.242     Vector3  operator-  (const Vector3& b) const  { return Vector3(x - b.x, y - b.y, z - b.z); }
  23.243     Vector3& operator-= (const Vector3& b)        { x -= b.x; y -= b.y; z -= b.z; return *this; }
  23.244     Vector3  operator- () const                   { return Vector3(-x, -y, -z); }
  23.245 
  23.246     // Scalar multiplication/division scales vector.
  23.247     Vector3  operator*  (T s) const               { return Vector3(x*s, y*s, z*s); }
  23.248     Vector3& operator*= (T s)                     { x *= s; y *= s; z *= s; return *this; }
  23.249 
  23.250     Vector3  operator/  (T s) const               { T rcp = T(1)/s;
  23.251                                                     return Vector3(x*rcp, y*rcp, z*rcp); }
  23.252     Vector3& operator/= (T s)                     { T rcp = T(1)/s;
  23.253                                                     x *= rcp; y *= rcp; z *= rcp;
  23.254                                                     return *this; }
  23.255 
  23.256     // Compare two vectors for equality with tolerance. Returns true if vectors match withing tolerance.
  23.257     bool      Compare(const Vector3&b, T tolerance = Mathf::Tolerance)
  23.258     {
  23.259         return (fabs(b.x-x) < tolerance) && (fabs(b.y-y) < tolerance) && (fabs(b.z-z) < tolerance);
  23.260     }
  23.261     
  23.262     // Dot product overload.
  23.263     // Used to calculate angle q between two vectors among other things,
  23.264     // as (A dot B) = |a||b|cos(q).
  23.265     T     operator*  (const Vector3& b) const    { return x*b.x + y*b.y + z*b.z; }
  23.266 
  23.267     // Compute cross product, which generates a normal vector.
  23.268     // Direction vector can be determined by right-hand rule: Pointing index finder in
  23.269     // direction a and middle finger in direction b, thumb will point in a.Cross(b).
  23.270     Vector3 Cross(const Vector3& b) const        { return Vector3(y*b.z - z*b.y,
  23.271                                                                   z*b.x - x*b.z,
  23.272                                                                   x*b.y - y*b.x); }
  23.273 
  23.274     // Returns the angle from this vector to b, in radians.
  23.275     T       Angle(const Vector3& b) const        { return acos((*this * b)/(Length()*b.Length())); }
  23.276 
  23.277     // Return Length of the vector squared.
  23.278     T       LengthSq() const                     { return (x * x + y * y + z * z); }
  23.279     // Return vector length.
  23.280     T       Length() const                       { return sqrt(LengthSq()); }
  23.281 
  23.282     // Returns distance between two points represented by vectors.
  23.283     T       Distance(Vector3& b) const           { return (*this - b).Length(); }
  23.284     
  23.285     // Determine if this a unit vector.
  23.286     bool    IsNormalized() const                 { return fabs(LengthSq() - T(1)) < Math<T>::Tolerance; }
  23.287     // Normalize, convention vector length to 1.    
  23.288     void    Normalize()                          { *this /= Length(); }
  23.289     // Returns normalized (unit) version of the vector without modifying itself.
  23.290     Vector3 Normalized() const                   { return *this / Length(); }
  23.291 
  23.292     // Linearly interpolates from this vector to another.
  23.293     // Factor should be between 0.0 and 1.0, with 0 giving full value to this.
  23.294     Vector3 Lerp(const Vector3& b, T f) const    { return *this*(T(1) - f) + b*f; }
  23.295 
  23.296     // Projects this vector onto the argument; in other words,
  23.297     // A.Project(B) returns projection of vector A onto B.
  23.298     Vector3 ProjectTo(const Vector3& b) const    { return b * ((*this * b) / b.LengthSq()); }
  23.299 };
  23.300 
  23.301 
  23.302 typedef Vector3<float>  Vector3f;
  23.303 typedef Vector3<double> Vector3d;
  23.304 
  23.305 
  23.306 //-------------------------------------------------------------------------------------
  23.307 // ***** Matrix4f 
  23.308 
  23.309 // Matrix4f is a 4x4 matrix used for 3d transformations and projections.
  23.310 // Translation stored in the last column.
  23.311 // The matrix is stored in row-major order in memory, meaning that values
  23.312 // of the first row are stored before the next one.
  23.313 //
  23.314 // The arrangement of the matrix is chosen to be in Right-Handed 
  23.315 // coordinate system and counterclockwise rotations when looking down
  23.316 // the axis
  23.317 //
  23.318 // Transformation Order:
  23.319 //   - Transformations are applied from right to left, so the expression
  23.320 //     M1 * M2 * M3 * V means that the vector V is transformed by M3 first,
  23.321 //     followed by M2 and M1. 
  23.322 //
  23.323 // Coordinate system: Right Handed
  23.324 //
  23.325 // Rotations: Counterclockwise when looking down the axis. All angles are in radians.
  23.326 //    
  23.327 //  | sx   01   02   tx |    // First column  (sx, 10, 20): Axis X basis vector.
  23.328 //  | 10   sy   12   ty |    // Second column (01, sy, 21): Axis Y basis vector.
  23.329 //  | 20   21   sz   tz |    // Third columnt (02, 12, sz): Axis Z basis vector.
  23.330 //  | 30   31   32   33 |
  23.331 //
  23.332 //  The basis vectors are first three columns.
  23.333 
  23.334 class Matrix4f
  23.335 {
  23.336     static Matrix4f IdentityValue;
  23.337 
  23.338 public:
  23.339     float M[4][4];    
  23.340 
  23.341     enum NoInitType { NoInit };
  23.342 
  23.343     // Construct with no memory initialization.
  23.344     Matrix4f(NoInitType) { }
  23.345 
  23.346     // By default, we construct identity matrix.
  23.347     Matrix4f()
  23.348     {
  23.349         SetIdentity();        
  23.350     }
  23.351 
  23.352     Matrix4f(float m11, float m12, float m13, float m14,
  23.353              float m21, float m22, float m23, float m24,
  23.354              float m31, float m32, float m33, float m34,
  23.355              float m41, float m42, float m43, float m44)
  23.356     {
  23.357         M[0][0] = m11; M[0][1] = m12; M[0][2] = m13; M[0][3] = m14;
  23.358         M[1][0] = m21; M[1][1] = m22; M[1][2] = m23; M[1][3] = m24;
  23.359         M[2][0] = m31; M[2][1] = m32; M[2][2] = m33; M[2][3] = m34;
  23.360         M[3][0] = m41; M[3][1] = m42; M[3][2] = m43; M[3][3] = m44;
  23.361     }
  23.362 
  23.363     Matrix4f(float m11, float m12, float m13,
  23.364              float m21, float m22, float m23,
  23.365              float m31, float m32, float m33)
  23.366     {
  23.367         M[0][0] = m11; M[0][1] = m12; M[0][2] = m13; M[0][3] = 0;
  23.368         M[1][0] = m21; M[1][1] = m22; M[1][2] = m23; M[1][3] = 0;
  23.369         M[2][0] = m31; M[2][1] = m32; M[2][2] = m33; M[2][3] = 0;
  23.370         M[3][0] = 0;   M[3][1] = 0;   M[3][2] = 0;   M[3][3] = 1;
  23.371     }
  23.372 
  23.373     static const Matrix4f& Identity()  { return IdentityValue; }
  23.374 
  23.375     void SetIdentity()
  23.376     {
  23.377         M[0][0] = M[1][1] = M[2][2] = M[3][3] = 1;
  23.378         M[0][1] = M[1][0] = M[2][3] = M[3][1] = 0;
  23.379         M[0][2] = M[1][2] = M[2][0] = M[3][2] = 0;
  23.380         M[0][3] = M[1][3] = M[2][1] = M[3][0] = 0;
  23.381     }
  23.382 
  23.383     // Multiplies two matrices into destination with minimum copying.
  23.384     static Matrix4f& Multiply(Matrix4f* d, const Matrix4f& a, const Matrix4f& b)
  23.385     {
  23.386         OVR_ASSERT((d != &a) && (d != &b));
  23.387         int i = 0;
  23.388         do {
  23.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];
  23.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];
  23.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];
  23.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];
  23.393         } while((++i) < 4);
  23.394 
  23.395         return *d;
  23.396     }
  23.397 
  23.398     Matrix4f operator* (const Matrix4f& b) const
  23.399     {
  23.400         Matrix4f result(Matrix4f::NoInit);
  23.401         Multiply(&result, *this, b);
  23.402         return result;
  23.403     }
  23.404 
  23.405     Matrix4f& operator*= (const Matrix4f& b)
  23.406     {
  23.407         return Multiply(this, Matrix4f(*this), b);
  23.408     }
  23.409 
  23.410     Matrix4f operator* (float s) const
  23.411     {
  23.412         return Matrix4f(M[0][0] * s, M[0][1] * s, M[0][2] * s, M[0][3] * s,
  23.413                         M[1][0] * s, M[1][1] * s, M[1][2] * s, M[1][3] * s,
  23.414                         M[2][0] * s, M[2][1] * s, M[2][2] * s, M[2][3] * s,
  23.415                         M[3][0] * s, M[3][1] * s, M[3][2] * s, M[3][3] * s);
  23.416     }
  23.417 
  23.418     Matrix4f& operator*= (float s)
  23.419     {
  23.420         M[0][0] *= s; M[0][1] *= s; M[0][2] *= s; M[0][3] *= s;
  23.421         M[1][0] *= s; M[1][1] *= s; M[1][2] *= s; M[1][3] *= s;
  23.422         M[2][0] *= s; M[2][1] *= s; M[2][2] *= s; M[2][3] *= s;
  23.423         M[3][0] *= s; M[3][1] *= s; M[3][2] *= s; M[3][3] *= s;
  23.424         return *this;
  23.425     }
  23.426 
  23.427     Vector3f Transform(const Vector3f& v) const
  23.428     {
  23.429         return Vector3f(M[0][0] * v.x + M[0][1] * v.y + M[0][2] * v.z + M[0][3],
  23.430                         M[1][0] * v.x + M[1][1] * v.y + M[1][2] * v.z + M[1][3],
  23.431                         M[2][0] * v.x + M[2][1] * v.y + M[2][2] * v.z + M[2][3]);
  23.432     }
  23.433 
  23.434     Matrix4f Transposed() const
  23.435     {
  23.436         return Matrix4f(M[0][0], M[1][0], M[2][0], M[3][0],
  23.437                         M[0][1], M[1][1], M[2][1], M[3][1],
  23.438                         M[0][2], M[1][2], M[2][2], M[3][2],
  23.439                         M[0][3], M[1][3], M[2][3], M[3][3]);
  23.440     }
  23.441 
  23.442     void     Transpose()
  23.443     {
  23.444         *this = Transposed();
  23.445     }
  23.446 
  23.447 
  23.448     float SubDet (const int* rows, const int* cols) const
  23.449     {
  23.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]])
  23.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]])
  23.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]]);
  23.453     }
  23.454 
  23.455     float Cofactor(int I, int J) const
  23.456     {
  23.457         const int indices[4][3] = {{1,2,3},{0,2,3},{0,1,3},{0,1,2}};
  23.458         return ((I+J)&1) ? -SubDet(indices[I],indices[J]) : SubDet(indices[I],indices[J]);
  23.459     }
  23.460 
  23.461     float    Determinant() const
  23.462     {
  23.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);
  23.464     }
  23.465 
  23.466     Matrix4f Adjugated() const
  23.467     {
  23.468         return Matrix4f(Cofactor(0,0), Cofactor(1,0), Cofactor(2,0), Cofactor(3,0), 
  23.469                         Cofactor(0,1), Cofactor(1,1), Cofactor(2,1), Cofactor(3,1), 
  23.470                         Cofactor(0,2), Cofactor(1,2), Cofactor(2,2), Cofactor(3,2),
  23.471                         Cofactor(0,3), Cofactor(1,3), Cofactor(2,3), Cofactor(3,3));
  23.472     }
  23.473 
  23.474     Matrix4f Inverted() const
  23.475     {
  23.476         float det = Determinant();
  23.477         assert(det != 0);
  23.478         return Adjugated() * (1.0f/det);
  23.479     }
  23.480 
  23.481     void Invert()
  23.482     {
  23.483         *this = Inverted();
  23.484     }
  23.485 
  23.486     //AnnaSteve:
  23.487     // a,b,c, are the YawPitchRoll angles to be returned
  23.488     // rotation a around axis A1
  23.489     // is followed by rotation b around axis A2
  23.490     // is followed by rotation c around axis A3
  23.491     // rotations are CCW or CW (D) in LH or RH coordinate system (S)
  23.492     template <Axis A1, Axis A2, Axis A3, RotateDirection D, HandedSystem S>
  23.493     void ToEulerAngles(float *a, float *b, float *c)
  23.494     {
  23.495         OVR_COMPILER_ASSERT((A1 != A2) && (A2 != A3) && (A1 != A3));
  23.496 
  23.497         float psign = -1.0f;
  23.498         if (((A1 + 1) % 3 == A2) && ((A2 + 1) % 3 == A3)) // Determine whether even permutation
  23.499         psign = 1.0f;
  23.500         
  23.501         float pm = psign*M[A1][A3];
  23.502         if (pm < -1.0f + Math<float>::SingularityRadius)
  23.503         { // South pole singularity
  23.504             *a = 0.0f;
  23.505             *b = -S*D*Math<float>::PiOver2;
  23.506             *c = S*D*atan2( psign*M[A2][A1], M[A2][A2] );
  23.507         }
  23.508         else if (pm > 1.0 - Math<float>::SingularityRadius)
  23.509         { // North pole singularity
  23.510             *a = 0.0f;
  23.511             *b = S*D*Math<float>::PiOver2;
  23.512             *c = S*D*atan2( psign*M[A2][A1], M[A2][A2] );
  23.513         }
  23.514         else
  23.515         { // Normal case (nonsingular)
  23.516             *a = S*D*atan2( -psign*M[A2][A3], M[A3][A3] );
  23.517             *b = S*D*asin(pm);
  23.518             *c = S*D*atan2( -psign*M[A1][A2], M[A1][A1] );
  23.519         }
  23.520 
  23.521         return;
  23.522     }
  23.523 
  23.524     //AnnaSteve:
  23.525     // a,b,c, are the YawPitchRoll angles to be returned
  23.526     // rotation a around axis A1
  23.527     // is followed by rotation b around axis A2
  23.528     // is followed by rotation c around axis A1
  23.529     // rotations are CCW or CW (D) in LH or RH coordinate system (S)
  23.530     template <Axis A1, Axis A2, RotateDirection D, HandedSystem S>
  23.531     void ToEulerAnglesABA(float *a, float *b, float *c)
  23.532     {        
  23.533          OVR_COMPILER_ASSERT(A1 != A2);
  23.534   
  23.535         // Determine the axis that was not supplied
  23.536         int m = 3 - A1 - A2;
  23.537 
  23.538         float psign = -1.0f;
  23.539         if ((A1 + 1) % 3 == A2) // Determine whether even permutation
  23.540             psign = 1.0f;
  23.541 
  23.542         float c2 = M[A1][A1];
  23.543         if (c2 < -1.0 + Math<float>::SingularityRadius)
  23.544         { // South pole singularity
  23.545             *a = 0.0f;
  23.546             *b = S*D*Math<float>::Pi;
  23.547             *c = S*D*atan2( -psign*M[A2][m],M[A2][A2]);
  23.548         }
  23.549         else if (c2 > 1.0 - Math<float>::SingularityRadius)
  23.550         { // North pole singularity
  23.551             *a = 0.0f;
  23.552             *b = 0.0f;
  23.553             *c = S*D*atan2( -psign*M[A2][m],M[A2][A2]);
  23.554         }
  23.555         else
  23.556         { // Normal case (nonsingular)
  23.557             *a = S*D*atan2( M[A2][A1],-psign*M[m][A1]);
  23.558             *b = S*D*acos(c2);
  23.559             *c = S*D*atan2( M[A1][A2],psign*M[A1][m]);
  23.560         }
  23.561         return;
  23.562     }
  23.563   
  23.564     // Creates a matrix that converts the vertices from one coordinate system
  23.565     // to another.
  23.566     // 
  23.567     static Matrix4f AxisConversion(const WorldAxes& to, const WorldAxes& from)
  23.568     {        
  23.569         // Holds axis values from the 'to' structure
  23.570         int toArray[3] = { to.XAxis, to.YAxis, to.ZAxis };
  23.571 
  23.572         // The inverse of the toArray
  23.573         int inv[4]; 
  23.574         inv[0] = inv[abs(to.XAxis)] = 0;
  23.575         inv[abs(to.YAxis)] = 1;
  23.576         inv[abs(to.ZAxis)] = 2;
  23.577 
  23.578         Matrix4f m(0,  0,  0, 
  23.579                    0,  0,  0,
  23.580                    0,  0,  0);
  23.581 
  23.582         // Only three values in the matrix need to be changed to 1 or -1.
  23.583         m.M[inv[abs(from.XAxis)]][0] = float(from.XAxis/toArray[inv[abs(from.XAxis)]]);
  23.584         m.M[inv[abs(from.YAxis)]][1] = float(from.YAxis/toArray[inv[abs(from.YAxis)]]);
  23.585         m.M[inv[abs(from.ZAxis)]][2] = float(from.ZAxis/toArray[inv[abs(from.ZAxis)]]);
  23.586         return m;
  23.587     } 
  23.588 
  23.589 
  23.590 
  23.591     static Matrix4f Translation(const Vector3f& v)
  23.592     {
  23.593         Matrix4f t;
  23.594         t.M[0][3] = v.x;
  23.595         t.M[1][3] = v.y;
  23.596         t.M[2][3] = v.z;
  23.597         return t;
  23.598     }
  23.599 
  23.600     static Matrix4f Translation(float x, float y, float z = 0.0f)
  23.601     {
  23.602         Matrix4f t;
  23.603         t.M[0][3] = x;
  23.604         t.M[1][3] = y;
  23.605         t.M[2][3] = z;
  23.606         return t;
  23.607     }
  23.608 
  23.609     static Matrix4f Scaling(const Vector3f& v)
  23.610     {
  23.611         Matrix4f t;
  23.612         t.M[0][0] = v.x;
  23.613         t.M[1][1] = v.y;
  23.614         t.M[2][2] = v.z;
  23.615         return t;
  23.616     }
  23.617 
  23.618     static Matrix4f Scaling(float x, float y, float z)
  23.619     {
  23.620         Matrix4f t;
  23.621         t.M[0][0] = x;
  23.622         t.M[1][1] = y;
  23.623         t.M[2][2] = z;
  23.624         return t;
  23.625     }
  23.626 
  23.627     static Matrix4f Scaling(float s)
  23.628     {
  23.629         Matrix4f t;
  23.630         t.M[0][0] = s;
  23.631         t.M[1][1] = s;
  23.632         t.M[2][2] = s;
  23.633         return t;
  23.634     }
  23.635 
  23.636   
  23.637 
  23.638     //AnnaSteve : Just for quick testing.  Not for final API.  Need to remove case.
  23.639     static Matrix4f RotationAxis(Axis A, float angle, RotateDirection d, HandedSystem s)
  23.640     {
  23.641         float sina = s * d *sin(angle);
  23.642         float cosa = cos(angle);
  23.643         
  23.644         switch(A)
  23.645         {
  23.646         case Axis_X:
  23.647             return Matrix4f(1,  0,     0, 
  23.648                             0,  cosa,  -sina,
  23.649                             0,  sina,  cosa);
  23.650         case Axis_Y:
  23.651             return Matrix4f(cosa,  0,   sina, 
  23.652                             0,     1,   0,
  23.653                             -sina, 0,   cosa);
  23.654         case Axis_Z:
  23.655             return Matrix4f(cosa,  -sina,  0, 
  23.656                             sina,  cosa,   0,
  23.657                             0,     0,      1);
  23.658         }
  23.659     }
  23.660 
  23.661 
  23.662     // Creates a rotation matrix rotating around the X axis by 'angle' radians.
  23.663     // Rotation direction is depends on the coordinate system:
  23.664     //  RHS (Oculus default): Positive angle values rotate Counter-clockwise (CCW),
  23.665     //                        while looking in the negative axis direction. This is the
  23.666     //                        same as looking down from positive axis values towards origin.
  23.667     //  LHS: Positive angle values rotate clock-wise (CW), while looking in the
  23.668     //       negative axis direction.
  23.669     static Matrix4f RotationX(float angle)
  23.670     {
  23.671         float sina = sin(angle);
  23.672         float cosa = cos(angle);
  23.673         return Matrix4f(1,  0,     0, 
  23.674                         0,  cosa,  -sina,
  23.675                         0,  sina,  cosa);
  23.676     }
  23.677 
  23.678     // Creates a rotation matrix rotating around the Y axis by 'angle' radians.
  23.679     // Rotation direction is depends on the coordinate system:
  23.680     //  RHS (Oculus default): Positive angle values rotate Counter-clockwise (CCW),
  23.681     //                        while looking in the negative axis direction. This is the
  23.682     //                        same as looking down from positive axis values towards origin.
  23.683     //  LHS: Positive angle values rotate clock-wise (CW), while looking in the
  23.684     //       negative axis direction.
  23.685     static Matrix4f RotationY(float angle)
  23.686     {
  23.687         float sina = sin(angle);
  23.688         float cosa = cos(angle);
  23.689         return Matrix4f(cosa,  0,   sina, 
  23.690                         0,     1,   0,
  23.691                         -sina, 0,   cosa);
  23.692     }
  23.693 
  23.694     // Creates a rotation matrix rotating around the Z axis by 'angle' radians.
  23.695     // Rotation direction is depends on the coordinate system:
  23.696     //  RHS (Oculus default): Positive angle values rotate Counter-clockwise (CCW),
  23.697     //                        while looking in the negative axis direction. This is the
  23.698     //                        same as looking down from positive axis values towards origin.
  23.699     //  LHS: Positive angle values rotate clock-wise (CW), while looking in the
  23.700     //       negative axis direction.
  23.701     static Matrix4f RotationZ(float angle)
  23.702     {
  23.703         float sina = sin(angle);
  23.704         float cosa = cos(angle);
  23.705         return Matrix4f(cosa,  -sina,  0, 
  23.706                         sina,  cosa,   0,
  23.707                         0,     0,      1);
  23.708     }
  23.709 
  23.710 
  23.711     // LookAtRH creates a View transformation matrix for right-handed coordinate system.
  23.712     // The resulting matrix points camera from 'eye' towards 'at' direction, with 'up'
  23.713     // specifying the up vector. The resulting matrix should be used with PerspectiveRH
  23.714     // projection.
  23.715     static Matrix4f LookAtRH(const Vector3f& eye, const Vector3f& at, const Vector3f& up);
  23.716 
  23.717     // LookAtLH creates a View transformation matrix for left-handed coordinate system.
  23.718     // The resulting matrix points camera from 'eye' towards 'at' direction, with 'up'
  23.719     // specifying the up vector. 
  23.720     static Matrix4f LookAtLH(const Vector3f& eye, const Vector3f& at, const Vector3f& up);
  23.721     
  23.722     
  23.723     // PerspectiveRH creates a right-handed perspective projection matrix that can be
  23.724     // used with the Oculus sample renderer. 
  23.725     //  yfov   - Specifies vertical field of view in radians.
  23.726     //  aspect - Screen aspect ration, which is usually width/height for square pixels.
  23.727     //           Note that xfov = yfov * aspect.
  23.728     //  znear  - Absolute value of near Z clipping clipping range.
  23.729     //  zfar   - Absolute value of far  Z clipping clipping range (larger then near).
  23.730     // Even though RHS usually looks in the direction of negative Z, positive values
  23.731     // are expected for znear and zfar.
  23.732     static Matrix4f PerspectiveRH(float yfov, float aspect, float znear, float zfar);
  23.733     
  23.734     
  23.735     // PerspectiveRH creates a left-handed perspective projection matrix that can be
  23.736     // used with the Oculus sample renderer. 
  23.737     //  yfov   - Specifies vertical field of view in radians.
  23.738     //  aspect - Screen aspect ration, which is usually width/height for square pixels.
  23.739     //           Note that xfov = yfov * aspect.
  23.740     //  znear  - Absolute value of near Z clipping clipping range.
  23.741     //  zfar   - Absolute value of far  Z clipping clipping range (larger then near).
  23.742     static Matrix4f PerspectiveLH(float yfov, float aspect, float znear, float zfar);
  23.743 
  23.744 
  23.745     static Matrix4f Ortho2D(float w, float h);
  23.746 };
  23.747 
  23.748 
  23.749 //-------------------------------------------------------------------------------------
  23.750 // ***** Quat
  23.751 
  23.752 // Quatf represents a quaternion class used for rotations.
  23.753 // 
  23.754 // Quaternion multiplications are done in right-to-left order, to match the
  23.755 // behavior of matrices.
  23.756 
  23.757 
  23.758 template<class T>
  23.759 class Quat
  23.760 {
  23.761 public:
  23.762     // w + Xi + Yj + Zk
  23.763     T x, y, z, w;    
  23.764 
  23.765     Quat() : x(0), y(0), z(0), w(1) {}
  23.766     Quat(T x_, T y_, T z_, T w_) : x(x_), y(y_), z(z_), w(w_) {}
  23.767 
  23.768 
  23.769     // Constructs rotation quaternion around the axis.
  23.770     Quat(const Vector3<T>& axis, T angle)
  23.771     {
  23.772         Vector3<T> unitAxis = axis.Normalized();
  23.773         T          sinHalfAngle = sin(angle * T(0.5));
  23.774 
  23.775         w = cos(angle * T(0.5));
  23.776         x = unitAxis.x * sinHalfAngle;
  23.777         y = unitAxis.y * sinHalfAngle;
  23.778         z = unitAxis.z * sinHalfAngle;
  23.779     }
  23.780 
  23.781     //AnnaSteve:
  23.782     void AxisAngle(Axis A, T angle, RotateDirection d, HandedSystem s)
  23.783     {
  23.784         T sinHalfAngle = s * d *sin(angle * (T)0.5);
  23.785         T v[3];
  23.786         v[0] = v[1] = v[2] = (T)0;
  23.787         v[A] = sinHalfAngle;
  23.788         //return Quat(v[0], v[1], v[2], cos(angle * (T)0.5));
  23.789         w = cos(angle * (T)0.5);
  23.790         x = v[0];
  23.791         y = v[1];
  23.792         z = v[2];
  23.793     }
  23.794 
  23.795 
  23.796     void GetAxisAngle(Vector3<T>* axis, T* angle) const
  23.797     {
  23.798         if (LengthSq() > Math<T>::Tolerance * Math<T>::Tolerance)
  23.799         {
  23.800             *axis  = Vector3<T>(x, y, z).Normalized();
  23.801             *angle = 2 * acos(w);
  23.802         }
  23.803         else
  23.804         {
  23.805             *axis = Vector3<T>(1, 0, 0);
  23.806             *angle= 0;
  23.807         }
  23.808     }
  23.809 
  23.810     bool operator== (const Quat& b) const   { return x == b.x && y == b.y && z == b.z && w == b.w; }
  23.811     bool operator!= (const Quat& b) const   { return x != b.x || y != b.y || z != b.z || w != b.w; }
  23.812 
  23.813     Quat  operator+  (const Quat& b) const  { return Quat(x + b.x, y + b.y, z + b.z, w + b.w); }
  23.814     Quat& operator+= (const Quat& b)        { w += b.w; x += b.x; y += b.y; z += b.z; return *this; }
  23.815     Quat  operator-  (const Quat& b) const  { return Quat(x - b.x, y - b.y, z - b.z, w - b.w); }
  23.816     Quat& operator-= (const Quat& b)        { w -= b.w; x -= b.x; y -= b.y; z -= b.z; return *this; }
  23.817 
  23.818     Quat  operator*  (T s) const            { return Quat(x * s, y * s, z * s, w * s); }
  23.819     Quat& operator*= (T s)                  { w *= s; x *= s; y *= s; z *= s; return *this; }
  23.820     Quat  operator/  (T s) const            { T rcp = T(1)/s; return Quat(x * rcp, y * rcp, z * rcp, w *rcp); }
  23.821     Quat& operator/= (T s)                  { T rcp = T(1)/s; w *= rcp; x *= rcp; y *= rcp; z *= rcp; return *this; }
  23.822 
  23.823     // Get Imaginary part vector
  23.824     Vector3<T> Imag() const                 { return Vector3<T>(x,y,z); }
  23.825 
  23.826     // Get quaternion length.
  23.827     T       Length() const                  { return sqrt(x * x + y * y + z * z + w * w); }
  23.828     // Get quaternion length squared.
  23.829     T       LengthSq() const                { return (x * x + y * y + z * z + w * w); }
  23.830     // Simple Eulidean distance in R^4 (not SLERP distance, but at least respects Haar measure)
  23.831     T       Distance(const Quat& q) const
  23.832     {
  23.833         T d1 = (*this - q).Length();
  23.834         T d2 = (*this + q).Length(); // Antipoldal point check
  23.835         return (d1 < d2) ? d1 : d2;
  23.836     }
  23.837     T       DistanceSq(const Quat& q) const
  23.838     {
  23.839         T d1 = (*this - q).LengthSq();
  23.840         T d2 = (*this + q).LengthSq(); // Antipoldal point check
  23.841         return (d1 < d2) ? d1 : d2;
  23.842     }
  23.843 
  23.844     // Normalize
  23.845     bool    IsNormalized() const            { return fabs(LengthSq() - 1) < Math<T>::Tolerance; }
  23.846     void    Normalize()                     { *this /= Length(); }
  23.847     Quat    Normalized() const              { return *this / Length(); }
  23.848 
  23.849     // Returns conjugate of the quaternion. Produces inverse rotation if quaternion is normalized.
  23.850     Quat    Conj() const                    { return Quat(-x, -y, -z, w); }
  23.851 
  23.852     // AnnaSteve fixed: order of quaternion multiplication
  23.853     // Quaternion multiplication. Combines quaternion rotations, performing the one on the 
  23.854     // right hand side first.
  23.855     Quat  operator* (const Quat& b) const   { return Quat(w * b.x + x * b.w + y * b.z - z * b.y,
  23.856                                                           w * b.y - x * b.z + y * b.w + z * b.x,
  23.857                                                           w * b.z + x * b.y - y * b.x + z * b.w,
  23.858                                                           w * b.w - x * b.x - y * b.y - z * b.z); }
  23.859 
  23.860     // 
  23.861     // this^p normalized; same as rotating by this p times.
  23.862     Quat PowNormalized(T p) const
  23.863     {
  23.864         Vector3<T> v;
  23.865         T          a;
  23.866         GetAxisAngle(&v, &a);
  23.867         return Quat(v, a * p);
  23.868     }
  23.869     
  23.870     // Rotate transforms vector in a manner that matches Matrix rotations (counter-clockwise,
  23.871     // assuming negative direction of the axis). Standard formula: q(t) * V * q(t)^-1. 
  23.872     Vector3<T> Rotate(const Vector3<T>& v) const
  23.873     {
  23.874         return ((*this * Quat<T>(v.x, v.y, v.z, 0)) * Inverted()).Imag();
  23.875     }
  23.876 
  23.877     
  23.878     // Inversed quaternion rotates in the opposite direction.
  23.879     Quat        Inverted() const
  23.880     {
  23.881         return Quat(-x, -y, -z, w);
  23.882     }
  23.883 
  23.884     // Sets this quaternion to the one rotates in the opposite direction.
  23.885     void        Invert()
  23.886     {
  23.887         *this = Quat(-x, -y, -z, w);
  23.888     }
  23.889     
  23.890     // Converting quaternion to matrix.
  23.891     operator Matrix4f() const
  23.892     {
  23.893         T ww = w*w;
  23.894         T xx = x*x;
  23.895         T yy = y*y;
  23.896         T zz = z*z;
  23.897 
  23.898         return Matrix4f(float(ww + xx - yy - zz),  float(T(2) * (x*y - w*z)), float(T(2) * (x*z + w*y)),
  23.899                         float(T(2) * (x*y + w*z)), float(ww - xx + yy - zz),  float(T(2) * (y*z - w*x)),
  23.900                         float(T(2) * (x*z - w*y)), float(T(2) * (y*z + w*x)), float(ww - xx - yy + zz) );
  23.901     }
  23.902 
  23.903     
  23.904     // GetEulerAngles extracts Euler angles from the quaternion, in the specified order of
  23.905     // axis rotations and the specified coordinate system. Right-handed coordinate system
  23.906     // is the default, with CCW rotations while looking in the negative axis direction.
  23.907     // Here a,b,c, are the Yaw/Pitch/Roll angles to be returned.
  23.908     // rotation a around axis A1
  23.909     // is followed by rotation b around axis A2
  23.910     // is followed by rotation c around axis A3
  23.911     // rotations are CCW or CW (D) in LH or RH coordinate system (S)
  23.912     template <Axis A1, Axis A2, Axis A3, RotateDirection D, HandedSystem S>
  23.913     void GetEulerAngles(T *a, T *b, T *c)
  23.914     {
  23.915         OVR_COMPILER_ASSERT((A1 != A2) && (A2 != A3) && (A1 != A3));
  23.916 
  23.917         T Q[3] = { x, y, z };  //Quaternion components x,y,z
  23.918 
  23.919         T ww  = w*w;
  23.920         T Q11 = Q[A1]*Q[A1];
  23.921         T Q22 = Q[A2]*Q[A2];
  23.922         T Q33 = Q[A3]*Q[A3];
  23.923 
  23.924         T psign = T(-1.0);
  23.925         // Determine whether even permutation
  23.926         if (((A1 + 1) % 3 == A2) && ((A2 + 1) % 3 == A3))
  23.927             psign = T(1.0);
  23.928         
  23.929         T s2 = psign * T(2.0) * (psign*w*Q[A2] + Q[A1]*Q[A3]);
  23.930 
  23.931         if (s2 < (T)-1.0 + Math<T>::SingularityRadius)
  23.932         { // South pole singularity
  23.933             *a = T(0.0);
  23.934             *b = -S*D*Math<T>::PiOver2;
  23.935             *c = S*D*atan2((T)2.0*(psign*Q[A1]*Q[A2] + w*Q[A3]),
  23.936 		                   ww + Q22 - Q11 - Q33 );
  23.937         }
  23.938         else if (s2 > (T)1.0 - Math<T>::SingularityRadius)
  23.939         {  // North pole singularity
  23.940             *a = (T)0.0;
  23.941             *b = S*D*Math<T>::PiOver2;
  23.942             *c = S*D*atan2((T)2.0*(psign*Q[A1]*Q[A2] + w*Q[A3]),
  23.943 		                   ww + Q22 - Q11 - Q33);
  23.944         }
  23.945         else
  23.946         {
  23.947             *a = -S*D*atan2((T)-2.0*(w*Q[A1] - psign*Q[A2]*Q[A3]),
  23.948 		                    ww + Q33 - Q11 - Q22);
  23.949             *b = S*D*asin(s2);
  23.950             *c = S*D*atan2((T)2.0*(w*Q[A3] - psign*Q[A1]*Q[A2]),
  23.951 		                   ww + Q11 - Q22 - Q33);
  23.952         }      
  23.953         return;
  23.954     }
  23.955 
  23.956     template <Axis A1, Axis A2, Axis A3, RotateDirection D>
  23.957     void GetEulerAngles(T *a, T *b, T *c)
  23.958     { GetEulerAngles<A1, A2, A3, D, Handed_R>(a, b, c); }
  23.959 
  23.960     template <Axis A1, Axis A2, Axis A3>
  23.961     void GetEulerAngles(T *a, T *b, T *c)
  23.962     { GetEulerAngles<A1, A2, A3, Rotate_CCW, Handed_R>(a, b, c); }
  23.963 
  23.964 
  23.965     // GetEulerAnglesABA extracts Euler angles from the quaternion, in the specified order of
  23.966     // axis rotations and the specified coordinate system. Right-handed coordinate system
  23.967     // is the default, with CCW rotations while looking in the negative axis direction.
  23.968     // Here a,b,c, are the Yaw/Pitch/Roll angles to be returned.
  23.969     // rotation a around axis A1
  23.970     // is followed by rotation b around axis A2
  23.971     // is followed by rotation c around axis A1
  23.972     // Rotations are CCW or CW (D) in LH or RH coordinate system (S)
  23.973     template <Axis A1, Axis A2, RotateDirection D, HandedSystem S>
  23.974     void GetEulerAnglesABA(T *a, T *b, T *c)
  23.975     {
  23.976         OVR_COMPILER_ASSERT(A1 != A2);
  23.977 
  23.978         T Q[3] = {x, y, z}; // Quaternion components
  23.979 
  23.980         // Determine the missing axis that was not supplied
  23.981         int m = 3 - A1 - A2;
  23.982 
  23.983         T ww = w*w;
  23.984         T Q11 = Q[A1]*Q[A1];
  23.985         T Q22 = Q[A2]*Q[A2];
  23.986         T Qmm = Q[m]*Q[m];
  23.987 
  23.988         T psign = T(-1.0);
  23.989         if ((A1 + 1) % 3 == A2) // Determine whether even permutation
  23.990         {
  23.991             psign = (T)1.0;
  23.992         }
  23.993 
  23.994         T c2 = ww + Q11 - Q22 - Qmm;
  23.995         if (c2 < (T)-1.0 + Math<T>::SingularityRadius)
  23.996         { // South pole singularity
  23.997             *a = (T)0.0;
  23.998             *b = S*D*Math<T>::Pi;
  23.999             *c = S*D*atan2( (T)2.0*(w*Q[A1] - psign*Q[A2]*Q[m]),
 23.1000 		                    ww + Q22 - Q11 - Qmm);
 23.1001         }
 23.1002         else if (c2 > (T)1.0 - Math<T>::SingularityRadius)
 23.1003         {  // North pole singularity
 23.1004             *a = (T)0.0;
 23.1005             *b = (T)0.0;
 23.1006             *c = S*D*atan2( (T)2.0*(w*Q[A1] - psign*Q[A2]*Q[m]),
 23.1007 		                   ww + Q22 - Q11 - Qmm);
 23.1008         }
 23.1009         else
 23.1010         {
 23.1011             *a = S*D*atan2( psign*w*Q[m] + Q[A1]*Q[A2],
 23.1012 		                   w*Q[A2] -psign*Q[A1]*Q[m]);
 23.1013             *b = S*D*acos(c2);
 23.1014             *c = S*D*atan2( -psign*w*Q[m] + Q[A1]*Q[A2],
 23.1015 		                   w*Q[A2] + psign*Q[A1]*Q[m]);
 23.1016         }
 23.1017         return;
 23.1018     }
 23.1019 };
 23.1020 
 23.1021 
 23.1022 typedef Quat<float>  Quatf;
 23.1023 typedef Quat<double> Quatd;
 23.1024 
 23.1025 
 23.1026 
 23.1027 //-------------------------------------------------------------------------------------
 23.1028 // ***** Angle
 23.1029 
 23.1030 // Cleanly representing the algebra of 2D rotations.
 23.1031 // The operations maintain the angle between -Pi and Pi, the same range as atan2.
 23.1032 // 
 23.1033 
 23.1034 template<class T>
 23.1035 class Angle
 23.1036 {
 23.1037 public:
 23.1038 	enum AngularUnits
 23.1039 	{
 23.1040 		Radians = 0,
 23.1041 		Degrees = 1
 23.1042 	};
 23.1043 
 23.1044     Angle() : a(0) {}
 23.1045     
 23.1046 	// Fix the range to be between -Pi and Pi
 23.1047 	Angle(T a_, AngularUnits u = Radians) : a((u == Radians) ? a_ : a_*Math<T>::DegreeToRadFactor) { FixRange(); }
 23.1048 
 23.1049 	T    Get(AngularUnits u = Radians) const       { return (u == Radians) ? a : a*Math<T>::RadToDegreeFactor; }
 23.1050 	void Set(const T& x, AngularUnits u = Radians) { a = (u == Radians) ? x : x*Math<T>::DegreeToRadFactor; FixRange(); }
 23.1051 	int Sign() const                               { if (a == 0) return 0; else return (a > 0) ? 1 : -1; }
 23.1052 	T   Abs() const                                { return (a > 0) ? a : -a; }
 23.1053 
 23.1054     bool operator== (const Angle& b) const    { return a == b.a; }
 23.1055     bool operator!= (const Angle& b) const    { return a != b.a; }
 23.1056 //	bool operator<  (const Angle& b) const    { return a < a.b; } 
 23.1057 //	bool operator>  (const Angle& b) const    { return a > a.b; } 
 23.1058 //	bool operator<= (const Angle& b) const    { return a <= a.b; } 
 23.1059 //	bool operator>= (const Angle& b) const    { return a >= a.b; } 
 23.1060 //	bool operator= (const T& x)               { a = x; FixRange(); }
 23.1061 
 23.1062 	// These operations assume a is already between -Pi and Pi.
 23.1063     Angle  operator+  (const Angle& b) const  { return Angle(a + b.a); }
 23.1064 	Angle  operator+  (const T& x) const      { return Angle(a + x); }
 23.1065 	Angle& operator+= (const Angle& b)        { a = a + b.a; FastFixRange(); return *this; }
 23.1066 	Angle& operator+= (const T& x)            { a = a + x; FixRange(); return *this; }
 23.1067 	Angle  operator-  (const Angle& b) const  { return Angle(a - b.a); }
 23.1068 	Angle  operator-  (const T& x) const      { return Angle(a - x); }
 23.1069 	Angle& operator-= (const Angle& b)        { a = a - b.a; FastFixRange(); return *this; }
 23.1070 	Angle& operator-= (const T& x)            { a = a - x; FixRange(); return *this; }
 23.1071 	
 23.1072 	T   Distance(const Angle& b)              { T c = fabs(a - b.a); return (c <= Math<T>::Pi) ? c : Math<T>::TwoPi - c; }
 23.1073 
 23.1074 private:
 23.1075 
 23.1076 	// The stored angle, which should be maintained between -Pi and Pi
 23.1077 	T a;
 23.1078 
 23.1079 	// Fixes the angle range to [-Pi,Pi], but assumes no more than 2Pi away on either side 
 23.1080 	inline void FastFixRange()
 23.1081 	{
 23.1082 		if (a < -Math<T>::Pi)
 23.1083 			a += Math<T>::TwoPi;
 23.1084 		else if (a > Math<T>::Pi)
 23.1085 			a -= Math<T>::TwoPi;
 23.1086 	}
 23.1087 
 23.1088 	// Fixes the angle range to [-Pi,Pi] for any given range, but slower then the fast method
 23.1089 	inline void FixRange()
 23.1090 	{
 23.1091 		a = fmod(a,Math<T>::TwoPi);
 23.1092 		if (a < -Math<T>::Pi)
 23.1093 			a += Math<T>::TwoPi;
 23.1094 		else if (a > Math<T>::Pi)
 23.1095 			a -= Math<T>::TwoPi;
 23.1096 	}
 23.1097 };
 23.1098 
 23.1099 
 23.1100 typedef Angle<float>  Anglef;
 23.1101 typedef Angle<double> Angled;
 23.1102 
 23.1103 
 23.1104 //-------------------------------------------------------------------------------------
 23.1105 // ***** Plane
 23.1106 
 23.1107 // Consists of a normal vector and distance from the origin where the plane is located.
 23.1108 
 23.1109 template<class T>
 23.1110 class Plane : public RefCountBase<Plane<T> >
 23.1111 {
 23.1112 public:
 23.1113     Vector3<T> N;
 23.1114     T          D;
 23.1115 
 23.1116     Plane() : D(0) {}
 23.1117 
 23.1118     // Normals must already be normalized
 23.1119     Plane(const Vector3<T>& n, T d) : N(n), D(d) {}
 23.1120     Plane(T x, T y, T z, T d) : N(x,y,z), D(d) {}
 23.1121 
 23.1122     // construct from a point on the plane and the normal
 23.1123     Plane(const Vector3<T>& p, const Vector3<T>& n) : N(n), D(-(p * n)) {}
 23.1124 
 23.1125     // Find the point to plane distance. The sign indicates what side of the plane the point is on (0 = point on plane).
 23.1126     T TestSide(const Vector3<T>& p) const
 23.1127     {
 23.1128         return (N * p) + D;
 23.1129     }
 23.1130 
 23.1131     Plane<T> Flipped() const
 23.1132     {
 23.1133         return Plane(-N, -D);
 23.1134     }
 23.1135 
 23.1136     void Flip()
 23.1137     {
 23.1138         N = -N;
 23.1139         D = -D;
 23.1140     }
 23.1141 
 23.1142 	bool operator==(const Plane<T>& rhs) const
 23.1143 	{
 23.1144 		return (this->D == rhs.D && this->N == rhs.N);
 23.1145 	}
 23.1146 };
 23.1147 
 23.1148 typedef Plane<float> Planef;
 23.1149 
 23.1150 }
 23.1151 
 23.1152 #endif
 23.1153 \ No newline at end of file
    24.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    24.2 +++ b/libovr/Src/Kernel/OVR_RefCount.cpp	Sat Sep 14 16:14:59 2013 +0300
    24.3 @@ -0,0 +1,1 @@
    24.4 +/************************************************************************************
    24.5 
    24.6 Filename    :   OVR_RefCount.cpp
    24.7 Content     :   Reference counting implementation
    24.8 Created     :   September 19, 2012
    24.9 Notes       : 
   24.10 
   24.11 Copyright   :   Copyright 2012 Oculus VR, Inc. All Rights reserved.
   24.12 
   24.13 Use of this software is subject to the terms of the Oculus license
   24.14 agreement provided at the time of installation or download, or which
   24.15 otherwise accompanies this software in either electronic or hard copy form.
   24.16 
   24.17 ************************************************************************************/
   24.18 
   24.19 #include "OVR_RefCount.h"
   24.20 #include "OVR_Atomic.h"
   24.21 #include "OVR_Log.h"
   24.22 
   24.23 namespace OVR {
   24.24 
   24.25 #ifdef OVR_CC_ARM
   24.26 void* ReturnArg0(void* p)
   24.27 {
   24.28     return p;
   24.29 }
   24.30 #endif
   24.31 
   24.32 // ***** Reference Count Base implementation
   24.33 
   24.34 RefCountImplCore::~RefCountImplCore()
   24.35 {
   24.36     // RefCount can be either 1 or 0 here.
   24.37     //  0 if Release() was properly called.
   24.38     //  1 if the object was declared on stack or as an aggregate.
   24.39     OVR_ASSERT(RefCount <= 1);
   24.40 }
   24.41 
   24.42 #ifdef OVR_BUILD_DEBUG
   24.43 void RefCountImplCore::reportInvalidDelete(void *pmem)
   24.44 {
   24.45     OVR_DEBUG_LOG(
   24.46         ("Invalid delete call on ref-counted object at %p. Please use Release()", pmem));
   24.47     OVR_ASSERT(0);
   24.48 }
   24.49 #endif
   24.50 
   24.51 RefCountNTSImplCore::~RefCountNTSImplCore()
   24.52 {
   24.53     // RefCount can be either 1 or 0 here.
   24.54     //  0 if Release() was properly called.
   24.55     //  1 if the object was declared on stack or as an aggregate.
   24.56     OVR_ASSERT(RefCount <= 1);
   24.57 }
   24.58 
   24.59 #ifdef OVR_BUILD_DEBUG
   24.60 void RefCountNTSImplCore::reportInvalidDelete(void *pmem)
   24.61 {
   24.62     OVR_DEBUG_LOG(
   24.63         ("Invalid delete call on ref-counted object at %p. Please use Release()", pmem));
   24.64     OVR_ASSERT(0);
   24.65 }
   24.66 #endif
   24.67 
   24.68 
   24.69 // *** Thread-Safe RefCountImpl
   24.70 
   24.71 void    RefCountImpl::AddRef()
   24.72 {
   24.73     AtomicOps<int>::ExchangeAdd_NoSync(&RefCount, 1);
   24.74 }
   24.75 void    RefCountImpl::Release()
   24.76 {
   24.77     if ((AtomicOps<int>::ExchangeAdd_NoSync(&RefCount, -1) - 1) == 0)
   24.78         delete this;
   24.79 }
   24.80 
   24.81 // *** Thread-Safe RefCountVImpl w/virtual AddRef/Release
   24.82 
   24.83 void    RefCountVImpl::AddRef()
   24.84 {
   24.85     AtomicOps<int>::ExchangeAdd_NoSync(&RefCount, 1);
   24.86 }
   24.87 void    RefCountVImpl::Release()
   24.88 {
   24.89     if ((AtomicOps<int>::ExchangeAdd_NoSync(&RefCount, -1) - 1) == 0)
   24.90         delete this;
   24.91 }
   24.92 
   24.93 // *** NON-Thread-Safe RefCountImpl
   24.94 
   24.95 void    RefCountNTSImpl::Release() const
   24.96 {
   24.97     RefCount--;
   24.98     if (RefCount == 0)
   24.99         delete this;
  24.100 }
  24.101 
  24.102 
  24.103 } // OVR
  24.104 \ No newline at end of file
    25.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    25.2 +++ b/libovr/Src/Kernel/OVR_RefCount.h	Sat Sep 14 16:14:59 2013 +0300
    25.3 @@ -0,0 +1,1 @@
    25.4 +/************************************************************************************
    25.5 
    25.6 PublicHeader:   Kernel
    25.7 Filename    :   OVR_RefCount.h
    25.8 Content     :   Reference counting implementation headers
    25.9 Created     :   September 19, 2012
   25.10 Notes       : 
   25.11 
   25.12 Copyright   :   Copyright 2012 Oculus VR, Inc. All Rights reserved.
   25.13 
   25.14 Use of this software is subject to the terms of the Oculus license
   25.15 agreement provided at the time of installation or download, or which
   25.16 otherwise accompanies this software in either electronic or hard copy form.
   25.17 
   25.18 ************************************************************************************/
   25.19 
   25.20 #ifndef OVR_RefCount_h
   25.21 #define OVR_RefCount_h
   25.22 
   25.23 #include "OVR_Types.h"
   25.24 #include "OVR_Allocator.h"
   25.25 
   25.26 namespace OVR {
   25.27 
   25.28 //-----------------------------------------------------------------------------------
   25.29 // ***** Reference Counting
   25.30 
   25.31 // There are three types of reference counting base classes:
   25.32 //
   25.33 //  RefCountBase     - Provides thread-safe reference counting (Default).
   25.34 //  RefCountBaseNTS  - Non Thread Safe version of reference counting.
   25.35 
   25.36 
   25.37 // ***** Declared classes
   25.38 
   25.39 template<class C>
   25.40 class   RefCountBase;
   25.41 template<class C>
   25.42 class   RefCountBaseNTS;
   25.43 
   25.44 class   RefCountImpl;
   25.45 class   RefCountNTSImpl;
   25.46 
   25.47 
   25.48 //-----------------------------------------------------------------------------------
   25.49 // ***** Implementation For Reference Counting
   25.50 
   25.51 // RefCountImplCore holds RefCount value and defines a few utility
   25.52 // functions shared by all implementations.
   25.53 
   25.54 class RefCountImplCore
   25.55 {
   25.56 protected:
   25.57     volatile int RefCount;
   25.58 
   25.59 public:
   25.60     // RefCountImpl constructor always initializes RefCount to 1 by default.
   25.61     OVR_FORCE_INLINE RefCountImplCore() : RefCount(1) { }
   25.62 
   25.63     // Need virtual destructor
   25.64     // This:    1. Makes sure the right destructor's called.
   25.65     //          2. Makes us have VTable, necessary if we are going to have format needed by InitNewMem()
   25.66     virtual ~RefCountImplCore();
   25.67 
   25.68     // Debug method only.
   25.69     int GetRefCount() const { return RefCount;  }
   25.70 
   25.71     // This logic is used to detect invalid 'delete' calls of reference counted
   25.72     // objects. Direct delete calls are not allowed on them unless they come in
   25.73     // internally from Release.
   25.74 #ifdef OVR_BUILD_DEBUG    
   25.75     static void   OVR_CDECL  reportInvalidDelete(void *pmem);
   25.76     inline static void checkInvalidDelete(RefCountImplCore *pmem)
   25.77     {
   25.78         if (pmem->RefCount != 0)
   25.79             reportInvalidDelete(pmem);
   25.80     }
   25.81 #else
   25.82     inline static void checkInvalidDelete(RefCountImplCore *) { }
   25.83 #endif
   25.84 
   25.85     // Base class ref-count content should not be copied.
   25.86     void operator = (const RefCountImplCore &) { }  
   25.87 };
   25.88 
   25.89 class RefCountNTSImplCore
   25.90 {
   25.91 protected:
   25.92     mutable int RefCount;
   25.93 
   25.94 public:
   25.95     // RefCountImpl constructor always initializes RefCount to 1 by default.
   25.96     OVR_FORCE_INLINE RefCountNTSImplCore() : RefCount(1) { }
   25.97 
   25.98     // Need virtual destructor
   25.99     // This:    1. Makes sure the right destructor's called.
  25.100     //          2. Makes us have VTable, necessary if we are going to have format needed by InitNewMem()
  25.101     virtual ~RefCountNTSImplCore();
  25.102 
  25.103     // Debug method only.
  25.104     int             GetRefCount() const { return RefCount;  }
  25.105 
  25.106     // This logic is used to detect invalid 'delete' calls of reference counted
  25.107     // objects. Direct delete calls are not allowed on them unless they come in
  25.108     // internally from Release.
  25.109 #ifdef OVR_BUILD_DEBUG    
  25.110     static void   OVR_CDECL  reportInvalidDelete(void *pmem);
  25.111     OVR_FORCE_INLINE static void checkInvalidDelete(RefCountNTSImplCore *pmem)
  25.112     {
  25.113         if (pmem->RefCount != 0)
  25.114             reportInvalidDelete(pmem);
  25.115     }
  25.116 #else
  25.117     OVR_FORCE_INLINE static void checkInvalidDelete(RefCountNTSImplCore *) { }
  25.118 #endif
  25.119 
  25.120     // Base class ref-count content should not be copied.
  25.121     void operator = (const RefCountNTSImplCore &) { }  
  25.122 };
  25.123 
  25.124 
  25.125 
  25.126 // RefCountImpl provides Thread-Safe implementation of reference counting, so
  25.127 // it should be used by default in most places.
  25.128 
  25.129 class RefCountImpl : public RefCountImplCore
  25.130 {
  25.131 public:
  25.132     // Thread-Safe Ref-Count Implementation.
  25.133     void    AddRef();
  25.134     void    Release();   
  25.135 };
  25.136 
  25.137 // RefCountVImpl provides Thread-Safe implementation of reference counting, plus,
  25.138 // virtual AddRef and Release.
  25.139 
  25.140 class RefCountVImpl : public RefCountImplCore
  25.141 {
  25.142 public:
  25.143     // Thread-Safe Ref-Count Implementation.
  25.144     virtual void      AddRef();
  25.145     virtual void      Release();   
  25.146 };
  25.147 
  25.148 
  25.149 // RefCountImplNTS provides Non-Thread-Safe implementation of reference counting,
  25.150 // which is slightly more efficient since it doesn't use atomics.
  25.151 
  25.152 class RefCountNTSImpl : public RefCountNTSImplCore
  25.153 {
  25.154 public:
  25.155     OVR_FORCE_INLINE void    AddRef() const { RefCount++; }
  25.156     void    Release() const;   
  25.157 };
  25.158 
  25.159 
  25.160 
  25.161 // RefCountBaseStatImpl<> is a common class that adds new/delete override with Stat tracking
  25.162 // to the reference counting implementation. Base must be one of the RefCountImpl classes.
  25.163 
  25.164 template<class Base>
  25.165 class RefCountBaseStatImpl : public Base
  25.166 {
  25.167 public:
  25.168     RefCountBaseStatImpl() { }
  25.169      
  25.170     // *** Override New and Delete
  25.171 
  25.172     // DOM-IGNORE-BEGIN
  25.173     // Undef new temporarily if it is being redefined
  25.174 #ifdef OVR_DEFINE_NEW
  25.175 #undef new
  25.176 #endif
  25.177 
  25.178 #ifdef OVR_BUILD_DEBUG
  25.179     // Custom check used to detect incorrect calls of 'delete' on ref-counted objects.
  25.180     #define OVR_REFCOUNTALLOC_CHECK_DELETE(class_name, p)   \
  25.181         do {if (p) Base::checkInvalidDelete((class_name*)p); } while(0)
  25.182 #else
  25.183     #define OVR_REFCOUNTALLOC_CHECK_DELETE(class_name, p)
  25.184 #endif
  25.185 
  25.186     // Redefine all new & delete operators.
  25.187     OVR_MEMORY_REDEFINE_NEW_IMPL(Base, OVR_REFCOUNTALLOC_CHECK_DELETE)
  25.188 
  25.189 #ifdef OVR_DEFINE_NEW
  25.190 #define new OVR_DEFINE_NEW
  25.191 #endif
  25.192         // OVR_BUILD_DEFINE_NEW
  25.193         // DOM-IGNORE-END
  25.194 };
  25.195 
  25.196 
  25.197 
  25.198 //-----------------------------------------------------------------------------------
  25.199 // *** End user RefCountBase<> classes
  25.200 
  25.201 
  25.202 // RefCountBase is a base class for classes that require thread-safe reference
  25.203 // counting; it also overrides the new and delete operators to use MemoryHeap.
  25.204 //
  25.205 // Reference counted objects start out with RefCount value of 1. Further lifetime
  25.206 // management is done through the AddRef() and Release() methods, typically
  25.207 // hidden by Ptr<>.
  25.208 
  25.209 template<class C>
  25.210 class RefCountBase : public RefCountBaseStatImpl<RefCountImpl>
  25.211 {
  25.212 public:    
  25.213     // Constructor.
  25.214     OVR_FORCE_INLINE RefCountBase() : RefCountBaseStatImpl<RefCountImpl>() { }    
  25.215 };
  25.216 
  25.217 // RefCountBaseV is the same as RefCountBase but with virtual AddRef/Release
  25.218 
  25.219 template<class C>
  25.220 class RefCountBaseV : public RefCountBaseStatImpl<RefCountVImpl>
  25.221 {
  25.222 public:    
  25.223     // Constructor.
  25.224     OVR_FORCE_INLINE RefCountBaseV() : RefCountBaseStatImpl<RefCountVImpl>() { }    
  25.225 };
  25.226 
  25.227 
  25.228 // RefCountBaseNTS is a base class for classes that require Non-Thread-Safe reference
  25.229 // counting; it also overrides the new and delete operators to use MemoryHeap.
  25.230 // This class should only be used if all pointers to it are known to be assigned,
  25.231 // destroyed and manipulated within one thread.
  25.232 //
  25.233 // Reference counted objects start out with RefCount value of 1. Further lifetime
  25.234 // management is done through the AddRef() and Release() methods, typically
  25.235 // hidden by Ptr<>.
  25.236 
  25.237 template<class C>
  25.238 class RefCountBaseNTS : public RefCountBaseStatImpl<RefCountNTSImpl>
  25.239 {
  25.240 public:    
  25.241     // Constructor.
  25.242     OVR_FORCE_INLINE RefCountBaseNTS() : RefCountBaseStatImpl<RefCountNTSImpl>() { }    
  25.243 };
  25.244 
  25.245 //-----------------------------------------------------------------------------------
  25.246 // ***** Pickable template pointer
  25.247 enum PickType { PickValue };
  25.248 
  25.249 template <typename T>
  25.250 class Pickable
  25.251 {
  25.252 public:
  25.253     Pickable() : pV(NULL) {}
  25.254     explicit Pickable(T* p) : pV(p) {}
  25.255     Pickable(T* p, PickType) : pV(p) 
  25.256     {
  25.257         OVR_ASSERT(pV);
  25.258         if (pV)
  25.259             pV->AddRef();
  25.260     }
  25.261     template <typename OT>
  25.262     Pickable(const Pickable<OT>& other) : pV(other.GetPtr()) {}
  25.263 
  25.264 public:
  25.265     Pickable& operator =(const Pickable& other)
  25.266     {
  25.267         OVR_ASSERT(pV == NULL);
  25.268         pV = other.pV;
  25.269         // Extra check.
  25.270         //other.pV = NULL;
  25.271         return *this;
  25.272     }
  25.273 
  25.274 public:
  25.275     T* GetPtr() const { return pV; }
  25.276     T* operator->() const
  25.277     {
  25.278         return pV;
  25.279     }
  25.280     T& operator*() const
  25.281     {
  25.282         OVR_ASSERT(pV);
  25.283         return *pV;
  25.284     }
  25.285 
  25.286 private:
  25.287     T* pV;
  25.288 };
  25.289 
  25.290 template <typename T>
  25.291 OVR_FORCE_INLINE
  25.292 Pickable<T> MakePickable(T* p)
  25.293 {
  25.294     return Pickable<T>(p);
  25.295 }
  25.296 
  25.297 //-----------------------------------------------------------------------------------
  25.298 // ***** Ref-Counted template pointer
  25.299 
  25.300 // Automatically AddRefs and Releases interfaces
  25.301 
  25.302 void* ReturnArg0(void* p);
  25.303 
  25.304 template<class C>
  25.305 class Ptr
  25.306 {
  25.307 #ifdef OVR_CC_ARM
  25.308     static C* ReturnArg(void* p) { return (C*)ReturnArg0(p); }
  25.309 #endif
  25.310 
  25.311 protected:
  25.312     C   *pObject;
  25.313 
  25.314 public:
  25.315 
  25.316     // Constructors
  25.317     OVR_FORCE_INLINE Ptr() : pObject(0)
  25.318     { }
  25.319 #ifdef OVR_CC_ARM
  25.320     OVR_FORCE_INLINE Ptr(C &robj) : pObject(ReturnArg(&robj))
  25.321 #else
  25.322     OVR_FORCE_INLINE Ptr(C &robj) : pObject(&robj)
  25.323 #endif
  25.324     { }
  25.325     OVR_FORCE_INLINE Ptr(Pickable<C> v) : pObject(v.GetPtr())
  25.326     {
  25.327         // No AddRef() on purpose.
  25.328     }
  25.329     OVR_FORCE_INLINE Ptr(Ptr<C>& other, PickType) : pObject(other.pObject)
  25.330     {
  25.331         other.pObject = NULL;
  25.332         // No AddRef() on purpose.
  25.333     }
  25.334     OVR_FORCE_INLINE Ptr(C *pobj)
  25.335     {
  25.336         if (pobj) pobj->AddRef();   
  25.337         pObject = pobj;
  25.338     }
  25.339     OVR_FORCE_INLINE Ptr(const Ptr<C> &src)
  25.340     {
  25.341         if (src.pObject) src.pObject->AddRef();     
  25.342         pObject = src.pObject;
  25.343     }
  25.344 
  25.345     template<class R>
  25.346     OVR_FORCE_INLINE Ptr(Ptr<R> &src)
  25.347     {
  25.348         if (src) src->AddRef();
  25.349         pObject = src;
  25.350     }
  25.351     template<class R>
  25.352     OVR_FORCE_INLINE Ptr(Pickable<R> v) : pObject(v.GetPtr())
  25.353     {
  25.354         // No AddRef() on purpose.
  25.355     }
  25.356 
  25.357     // Destructor
  25.358     OVR_FORCE_INLINE ~Ptr()
  25.359     {
  25.360         if (pObject) pObject->Release();        
  25.361     }
  25.362 
  25.363     // Compares
  25.364     OVR_FORCE_INLINE bool operator == (const Ptr &other) const       { return pObject == other.pObject; }
  25.365     OVR_FORCE_INLINE bool operator != (const Ptr &other) const       { return pObject != other.pObject; }
  25.366 
  25.367     OVR_FORCE_INLINE bool operator == (C *pother) const              { return pObject == pother; }
  25.368     OVR_FORCE_INLINE bool operator != (C *pother) const              { return pObject != pother; }
  25.369 
  25.370 
  25.371     OVR_FORCE_INLINE bool operator < (const Ptr &other) const       { return pObject < other.pObject; }
  25.372 
  25.373     // Assignment
  25.374     template<class R>
  25.375     OVR_FORCE_INLINE const Ptr<C>& operator = (const Ptr<R> &src)
  25.376     {
  25.377         if (src) src->AddRef();
  25.378         if (pObject) pObject->Release();        
  25.379         pObject = src;
  25.380         return *this;
  25.381     }   
  25.382     // Specialization
  25.383     OVR_FORCE_INLINE const Ptr<C>& operator = (const Ptr<C> &src)
  25.384     {
  25.385         if (src) src->AddRef();
  25.386         if (pObject) pObject->Release();        
  25.387         pObject = src;
  25.388         return *this;
  25.389     }   
  25.390     
  25.391     OVR_FORCE_INLINE const Ptr<C>& operator = (C *psrc)
  25.392     {
  25.393         if (psrc) psrc->AddRef();
  25.394         if (pObject) pObject->Release();        
  25.395         pObject = psrc;
  25.396         return *this;
  25.397     }   
  25.398     OVR_FORCE_INLINE const Ptr<C>& operator = (C &src)
  25.399     {       
  25.400         if (pObject) pObject->Release();        
  25.401         pObject = &src;
  25.402         return *this;
  25.403     }
  25.404     OVR_FORCE_INLINE Ptr<C>& operator = (Pickable<C> src)
  25.405     {
  25.406         return Pick(src);
  25.407     }
  25.408     template<class R>
  25.409     OVR_FORCE_INLINE Ptr<C>& operator = (Pickable<R> src)
  25.410     {
  25.411         return Pick(src);
  25.412     }
  25.413     
  25.414     // Set Assignment
  25.415     template<class R>
  25.416     OVR_FORCE_INLINE Ptr<C>& SetPtr(const Ptr<R> &src)
  25.417     {
  25.418         if (src) src->AddRef();
  25.419         if (pObject) pObject->Release();
  25.420         pObject = src;
  25.421         return *this;
  25.422     }
  25.423     // Specialization
  25.424     OVR_FORCE_INLINE Ptr<C>& SetPtr(const Ptr<C> &src)
  25.425     {
  25.426         if (src) src->AddRef();
  25.427         if (pObject) pObject->Release();
  25.428         pObject = src;
  25.429         return *this;
  25.430     }   
  25.431     
  25.432     OVR_FORCE_INLINE Ptr<C>& SetPtr(C *psrc)
  25.433     {
  25.434         if (psrc) psrc->AddRef();
  25.435         if (pObject) pObject->Release();
  25.436         pObject = psrc;
  25.437         return *this;
  25.438     }   
  25.439     OVR_FORCE_INLINE Ptr<C>& SetPtr(C &src)
  25.440     {       
  25.441         if (pObject) pObject->Release();
  25.442         pObject = &src;
  25.443         return *this;
  25.444     }
  25.445     OVR_FORCE_INLINE Ptr<C>& SetPtr(Pickable<C> src)
  25.446     {       
  25.447         return Pick(src);
  25.448     }
  25.449 
  25.450     // Nulls ref-counted pointer without decrement
  25.451     OVR_FORCE_INLINE void    NullWithoutRelease()    
  25.452     { 
  25.453         pObject = 0;    
  25.454     }
  25.455 
  25.456     // Clears the pointer to the object
  25.457     OVR_FORCE_INLINE void    Clear()
  25.458     {
  25.459         if (pObject) pObject->Release();
  25.460         pObject = 0;
  25.461     }
  25.462 
  25.463     // Obtain pointer reference directly, for D3D interfaces
  25.464     OVR_FORCE_INLINE C*& GetRawRef()                 { return pObject; }
  25.465 
  25.466     // Access Operators
  25.467     OVR_FORCE_INLINE C* GetPtr() const               { return pObject; }
  25.468     OVR_FORCE_INLINE C& operator * () const          { return *pObject; }
  25.469     OVR_FORCE_INLINE C* operator -> ()  const        { return pObject; }
  25.470     // Conversion                   
  25.471     OVR_FORCE_INLINE operator C* () const            { return pObject; }
  25.472 
  25.473     // Pickers.
  25.474 
  25.475     // Pick a value.
  25.476     OVR_FORCE_INLINE Ptr<C>& Pick(Ptr<C>& other)
  25.477     {
  25.478         if (&other != this)
  25.479         {
  25.480             if (pObject) pObject->Release();
  25.481             pObject = other.pObject;
  25.482             other.pObject = 0;
  25.483         }
  25.484 
  25.485         return *this;
  25.486     }
  25.487 
  25.488     OVR_FORCE_INLINE Ptr<C>& Pick(Pickable<C> v)
  25.489     {
  25.490         if (v.GetPtr() != pObject)
  25.491         {
  25.492             if (pObject) pObject->Release();
  25.493             pObject = v.GetPtr();
  25.494         }
  25.495 
  25.496         return *this;
  25.497     }
  25.498 
  25.499     template<class R>
  25.500     OVR_FORCE_INLINE Ptr<C>& Pick(Pickable<R> v)
  25.501     {
  25.502         if (v.GetPtr() != pObject)
  25.503         {
  25.504             if (pObject) pObject->Release();
  25.505             pObject = v.GetPtr();
  25.506         }
  25.507 
  25.508         return *this;
  25.509     }
  25.510 
  25.511     OVR_FORCE_INLINE Ptr<C>& Pick(C* p)
  25.512     {
  25.513         if (p != pObject)
  25.514         {
  25.515             if (pObject) pObject->Release();
  25.516             pObject = p;
  25.517         }
  25.518 
  25.519         return *this;
  25.520     }
  25.521 };
  25.522 
  25.523 } // OVR
  25.524 
  25.525 #endif
  25.526 \ No newline at end of file
    26.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    26.2 +++ b/libovr/Src/Kernel/OVR_Std.cpp	Sat Sep 14 16:14:59 2013 +0300
    26.3 @@ -0,0 +1,1 @@
    26.4 +/************************************************************************************
    26.5 
    26.6 Filename    :   OVR_Std.cpp
    26.7 Content     :   Standard C function implementation
    26.8 Created     :   September 19, 2012
    26.9 Notes       : 
   26.10 
   26.11 Copyright   :   Copyright 2012 Oculus VR, Inc. All Rights reserved.
   26.12 
   26.13 Use of this software is subject to the terms of the Oculus license
   26.14 agreement provided at the time of installation or download, or which
   26.15 otherwise accompanies this software in either electronic or hard copy form.
   26.16 
   26.17 ************************************************************************************/
   26.18 
   26.19 #include "OVR_Std.h"
   26.20 #include "OVR_Alg.h"
   26.21 
   26.22 // localeconv() call in OVR_strtod()
   26.23 #include <locale.h>
   26.24 
   26.25 namespace OVR {
   26.26 
   26.27 // Source for functions not available on all platforms is included here.
   26.28 
   26.29 // Case insensitive compare implemented in platform-specific way.
   26.30 int OVR_CDECL OVR_stricmp(const char* a, const char* b)
   26.31 {
   26.32 #if defined(OVR_OS_WIN32)
   26.33     #if defined(OVR_CC_MSVC) && (OVR_CC_MSVC >= 1400)
   26.34         return ::_stricmp(a, b);
   26.35     #else
   26.36         return ::stricmp(a, b);
   26.37     #endif
   26.38 
   26.39 #else
   26.40     return strcasecmp(a, b);
   26.41 #endif
   26.42 }
   26.43 
   26.44 int OVR_CDECL OVR_strnicmp(const char* a, const char* b, UPInt count)
   26.45 {
   26.46 #if defined(OVR_OS_WIN32)
   26.47 #if defined(OVR_CC_MSVC) && (OVR_CC_MSVC >= 1400)
   26.48     return ::_strnicmp(a, b, count);
   26.49 #else
   26.50     return ::strnicmp(a, b, count);
   26.51 #endif
   26.52 
   26.53 #else
   26.54     return strncasecmp(a, b, count);
   26.55 #endif
   26.56 }
   26.57 
   26.58 wchar_t* OVR_CDECL OVR_wcscpy(wchar_t* dest, UPInt destsize, const wchar_t* src)
   26.59 {
   26.60 #if defined(OVR_MSVC_SAFESTRING)
   26.61     wcscpy_s(dest, destsize, src);
   26.62     return dest;
   26.63 #elif defined(OVR_OS_WIN32)
   26.64     OVR_UNUSED(destsize);
   26.65     wcscpy(dest, src);
   26.66     return dest;
   26.67 #else
   26.68     UPInt l = OVR_wcslen(src) + 1; // incl term null
   26.69     l = (l < destsize) ? l : destsize;
   26.70     memcpy(dest, src, l * sizeof(wchar_t));
   26.71     return dest;
   26.72 #endif
   26.73 }
   26.74 
   26.75 wchar_t* OVR_CDECL OVR_wcsncpy(wchar_t* dest, UPInt destsize, const wchar_t* src, UPInt count)
   26.76 {
   26.77 #if defined(OVR_MSVC_SAFESTRING)
   26.78     wcsncpy_s(dest, destsize, src, count);
   26.79     return dest;
   26.80 #else
   26.81     UPInt srclen = OVR_wcslen(src);
   26.82     UPInt l = Alg::Min(srclen, count);
   26.83     l = (l < destsize) ? l : destsize;
   26.84     memcpy(dest, src, l * sizeof(wchar_t));
   26.85     if (count > srclen)
   26.86     {
   26.87         UPInt remLen = Alg::Min(destsize - l, (count - srclen));
   26.88         memset(&dest[l], 0, sizeof(wchar_t)*remLen);
   26.89     }
   26.90     else if (l < destsize)
   26.91         dest[l] = 0;
   26.92     return dest;
   26.93 #endif
   26.94 }
   26.95 
   26.96 
   26.97 wchar_t* OVR_CDECL OVR_wcscat(wchar_t* dest, UPInt destsize, const wchar_t* src)
   26.98 {
   26.99 #if defined(OVR_MSVC_SAFESTRING)
  26.100     wcscat_s(dest, destsize, src);
  26.101     return dest;
  26.102 #elif defined(OVR_OS_WIN32)
  26.103     OVR_UNUSED(destsize);
  26.104     wcscat(dest, src);
  26.105     return dest;
  26.106 #else
  26.107     UPInt dstlen = OVR_wcslen(dest); // do not incl term null
  26.108     UPInt srclen = OVR_wcslen(src) + 1; // incl term null
  26.109     UPInt copylen = (dstlen + srclen < destsize) ? srclen : destsize - dstlen;
  26.110     memcpy(dest + dstlen, src, copylen * sizeof(wchar_t));
  26.111     return dest;
  26.112 #endif
  26.113 }
  26.114 
  26.115 UPInt   OVR_CDECL OVR_wcslen(const wchar_t* str)
  26.116 {
  26.117 #if defined(OVR_OS_WIN32)
  26.118     return wcslen(str);
  26.119 #else
  26.120     UPInt i = 0;
  26.121     while(str[i] != '\0')
  26.122         ++i;
  26.123     return i;
  26.124 #endif
  26.125 }
  26.126 
  26.127 int OVR_CDECL OVR_wcscmp(const wchar_t* a, const wchar_t* b)
  26.128 {
  26.129 #if defined(OVR_OS_WIN32) || defined(OVR_OS_LINUX)
  26.130     return wcscmp(a, b);
  26.131 #else
  26.132     // not supported, use custom implementation
  26.133     const wchar_t *pa = a, *pb = b;
  26.134     while (*pa && *pb)
  26.135     {
  26.136         wchar_t ca = *pa;
  26.137         wchar_t cb = *pb;
  26.138         if (ca < cb)
  26.139             return -1;
  26.140         else if (ca > cb)
  26.141             return 1;
  26.142         pa++;
  26.143         pb++;
  26.144     }
  26.145     if (*pa)
  26.146         return 1;
  26.147     else if (*pb)
  26.148         return -1;
  26.149     else
  26.150         return 0;
  26.151 #endif
  26.152 }
  26.153 
  26.154 int OVR_CDECL OVR_wcsicmp(const wchar_t* a, const wchar_t* b)
  26.155 {
  26.156 #if defined(OVR_OS_WIN32)
  26.157 #if defined(OVR_CC_MSVC) && (OVR_CC_MSVC >= 1400)
  26.158     return ::_wcsicmp(a, b);
  26.159 #else
  26.160     return ::wcsicmp(a, b);
  26.161 #endif
  26.162 #elif defined(OVR_OS_MAC) || defined(__CYGWIN__) || defined(OVR_OS_ANDROID) || defined(OVR_OS_IPHONE)
  26.163     // not supported, use custom implementation
  26.164     const wchar_t *pa = a, *pb = b;
  26.165     while (*pa && *pb)
  26.166     {
  26.167         wchar_t ca = OVR_towlower(*pa);
  26.168         wchar_t cb = OVR_towlower(*pb);
  26.169         if (ca < cb)
  26.170             return -1;
  26.171         else if (ca > cb)
  26.172             return 1;
  26.173         pa++;
  26.174         pb++;
  26.175     }
  26.176     if (*pa)
  26.177         return 1;
  26.178     else if (*pb)
  26.179         return -1;
  26.180     else
  26.181         return 0;
  26.182 #else
  26.183     return wcscasecmp(a, b);
  26.184 #endif
  26.185 }
  26.186 
  26.187 // This function is not inline because of dependency on <locale.h>
  26.188 double OVR_CDECL OVR_strtod(const char* string, char** tailptr)
  26.189 {
  26.190 #if !defined(OVR_OS_ANDROID)
  26.191     const char s = *localeconv()->decimal_point;
  26.192 
  26.193     if (s != '.')
  26.194     {
  26.195         char buffer[347 + 1];
  26.196 
  26.197         OVR_strcpy(buffer, sizeof(buffer), string);
  26.198 
  26.199         for (char* c = buffer; *c != '\0'; ++c)
  26.200         {
  26.201             if (*c == '.')
  26.202             {
  26.203                 *c = s;
  26.204                 break;
  26.205             }
  26.206         }
  26.207 
  26.208         return strtod(buffer, tailptr);
  26.209     }
  26.210 #endif
  26.211 
  26.212     return strtod(string, tailptr);
  26.213 }
  26.214 
  26.215 
  26.216 #ifndef OVR_NO_WCTYPE
  26.217 
  26.218 //// Use this class to generate Unicode bitsets. For example:
  26.219 ////
  26.220 //// UnicodeBitSet bitSet;
  26.221 //// for(unsigned i = 0; i < 65536; ++i)
  26.222 //// {
  26.223 ////     if (iswalpha(i))
  26.224 ////         bitSet.Set(i);
  26.225 //// }
  26.226 //// bitSet.Dump();
  26.227 ////
  26.228 ////---------------------------------------------------------------
  26.229 //class UnicodeBitSet
  26.230 //{
  26.231 //public:
  26.232 //    UnicodeBitSet()
  26.233 //    {
  26.234 //        memset(Offsets, 0, sizeof(Offsets));
  26.235 //        memset(Bits,    0, sizeof(Bits));
  26.236 //    }
  26.237 //
  26.238 //    void Set(unsigned bit) { Bits[bit >> 8][(bit >> 4) & 15] |= 1 << (bit & 15); }
  26.239 //
  26.240 //    void Dump()
  26.241 //    {
  26.242 //        unsigned i, j;
  26.243 //        unsigned offsetCount = 0;
  26.244 //        for(i = 0; i < 256; ++i)
  26.245 //        {
  26.246 //            if (isNull(i)) Offsets[i] = 0;
  26.247 //            else
  26.248 //            if (isFull(i)) Offsets[i] = 1;
  26.249 //            else           Offsets[i] = UInt16(offsetCount++ * 16 + 256);
  26.250 //        }
  26.251 //        for(i = 0; i < 16; ++i)
  26.252 //        {
  26.253 //            for(j = 0; j < 16; ++j)
  26.254 //            {
  26.255 //                printf("%5u,", Offsets[i*16+j]);
  26.256 //            }
  26.257 //            printf("\n");
  26.258 //        }
  26.259 //        for(i = 0; i < 256; ++i)
  26.260 //        {
  26.261 //            if (Offsets[i] > 255)
  26.262 //            {
  26.263 //                for(j = 0; j < 16; j++)
  26.264 //                {
  26.265 //                    printf("%5u,", Bits[i][j]);
  26.266 //                }
  26.267 //                printf("\n");
  26.268 //            }
  26.269 //        }
  26.270 //    }
  26.271 //
  26.272 //private:
  26.273 //    bool isNull(unsigned n) const
  26.274 //    {
  26.275 //        const UInt16* p = Bits[n];
  26.276 //        for(unsigned i = 0; i < 16; ++i)
  26.277 //            if (p[i] != 0) return false;
  26.278 //        return true;
  26.279 //    }
  26.280 //
  26.281 //    bool isFull(unsigned n) const
  26.282 //    {
  26.283 //        const UInt16* p = Bits[n];
  26.284 //        for(unsigned i = 0; i < 16; ++i)
  26.285 //            if (p[i] != 0xFFFF) return false;
  26.286 //        return true;
  26.287 //    }
  26.288 //
  26.289 //    UInt16 Offsets[256];
  26.290 //    UInt16 Bits[256][16];
  26.291 //};
  26.292 
  26.293 
  26.294 const UInt16 UnicodeAlnumBits[] = {
  26.295   256,    1,  272,  288,  304,  320,  336,  352,    0,  368,  384,  400,  416,  432,  448,  464,
  26.296   480,  496,  512,  528,  544,    1,  560,  576,  592,    0,    0,    0,    0,    0,  608,  624,
  26.297   640,  656,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  26.298   672,  688,    0,    0,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
  26.299     1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,  704,    1,    1,
  26.300     1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
  26.301     1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
  26.302     1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
  26.303     1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
  26.304     1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,  720,
  26.305     1,    1,    1,    1,  736,    0,    0,    0,    0,    0,    0,    0,    1,    1,    1,    1,
  26.306     1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
  26.307     1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
  26.308     1,    1,    1,    1,    1,    1,    1,  752,    0,    0,    0,    0,    0,    0,    0,    0,
  26.309     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  26.310     0,    0,    0,    0,    0,    0,    0,    0,    0,    1,  768,  784,    1,  800,  816,  832,
  26.311     0,    0,    0, 1023,65534, 2047,65534, 2047,    0,    0,    0,  524,65535,65407,65535,65407,
  26.312 65535,65535,65532,   15,    0,65535,65535,65535,65535,65535,16383,63999,    3,    0,16415,    0,
  26.313     0,    0,    0,    0,   32,    0,    0, 1024,55104,65535,65531,65535,32767,64767,65535,   15,
  26.314 65535,65535,65535,65535,65535,65535,65535,65535,61443,65535,65535,65535, 6559,65535,65535,  831,
  26.315     0,    0,    0,65534,65535,  639,65534,65535,  255,    0,    0,    0,    0,65535, 2047,    7,
  26.316     0,    0,65534, 2047,65534,   63, 1023,65535,65535,65535,65535,65535,65535, 8175, 8702, 8191,
  26.317     0,65535, 8191,65535,    0,    0,    0,    0,65535,65535,65535,    1,    0,    0,    0,    0,
  26.318 65518,65535,65535,58367, 8191,65281,65487,    0,40942,65529,65023,50117, 6559,45184,65487,    3,
  26.319 34788,65529,65023,50029, 6535,24064,65472,   31,45038,65531,65023,58349, 7103,    1,65473,    0,
  26.320 40942,65529,65023,58317, 6543,45248,65475,    0,51180,54845,50968,50111, 7623,  128,65408,    0,
  26.321 57326,65533,65023,50159, 7647,   96,65475,    0,57324,65533,65023,50159, 7647,16480,65475,    0,
  26.322 57324,65533,65023,50175, 7631,  128,65475,    0,65516,64639,65535,12283,32895,65375,    0,   12,
  26.323 65534,65535,65535, 2047,32767, 1023,    0,    0, 9622,65264,60590,15359, 8223,13311,    0,    0,
  26.324     1,    0, 1023,    0,65279,65535, 2047,65534, 3843,65279,65535, 8191,    0,    0,    0,    0,
  26.325 65535,65535,63227,  327, 1023, 1023,    0,    0,    0,    0,65535,65535,   63,65535,65535,  127,
  26.326 65535,65535,65535,65535,65535,33791,65535,65535,65535,65535,65287,65535,65535,65535,65535, 1023,
  26.327 65407,65535,65535,65535,15743,15743,65535,65535,15743,65535,32767,32573,32573,65407,32767,65535,
  26.328 32767,32573,65535,65535,65407, 2047,65024,    3,    0,    0,65535,65535,65535,65535,65535,   31,
  26.329 65534,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,
  26.330 65535,65535,65535,65535,65535,65535,40959,  127,65534, 2047,65535,65535,65535,65535, 2047,    0,
  26.331     0,    0,    0,    0,    0,    0,    0,    0,65535,65535,65535,65535,  511,    0, 1023,    0,
  26.332     0, 1023,65535,65535,65527,65535,65535,  255,65535,65535, 1023,    0,    0,    0,    0,    0,
  26.333 65535,65535,65535,65535,65535,65535,65535,65535,65535, 4095,65535,65535,65535,65535,65535, 1023,
  26.334 65535,16191,65535,65535,16191,43775,65535,16383,65535,65535,65535,24543, 8156, 4047, 8191, 8156,
  26.335     0,    0,    0,    0,    0,    0,    0,32768,    0,    0,    0,    0,    0,    0,    0,    0,
  26.336 64644,15919,48464, 1019,    0,    0,65535,65535,   15,    0,    0,    0,    0,    0,    0,    0,
  26.337   192,    0, 1022, 1792,65534,65535,65535,65535,65535,   31,65534,65535,65535,65535,65535, 2047,
  26.338 65504,65535, 8191,65534,65535,65535,65535,65535,32767,    0,65535,  255,    0,    0,    0,    0,
  26.339 65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,   63,    0,    0,    0,    0,
  26.340 65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,   63,    0,    0,    0,    0,    0,
  26.341 65535,65535,65535,65535,65535,65535,65535,65535, 8191,    0,    0,    0,    0,    0,    0,    0,
  26.342 65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,   15,    0,    0,    0,    0,    0,
  26.343 65535,65535,16383,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  26.344   127,41208,65023,24447,65499,65535,65535,65535,65535,65535,65535,    3,    0,65528,65535,65535,
  26.345 65535,65535,65535,16383,    0,65535,65535,65535,65535,65532,65535,65535,  255,    0,    0, 4095,
  26.346     0,    0,    0,    0,    0,    0,    0,65495,65535,65535,65535,65535,65535,65535,65535, 8191,
  26.347     0, 1023,65534, 2047,65534, 2047,65472,65534,65535,16383,65535,32767,64764, 7420,    0,    0};
  26.348 
  26.349 const UInt16 UnicodeAlphaBits[] = {
  26.350   256,    1,  272,  288,  304,  320,  336,  352,    0,  368,  384,  400,  416,  432,  448,  464,
  26.351   480,  496,  512,  528,  544,    1,  560,  576,  592,    0,    0,    0,    0,    0,  608,  624,
  26.352   640,  656,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  26.353   672,  688,    0,    0,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
  26.354     1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,  704,    1,    1,
  26.355     1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
  26.356     1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
  26.357     1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
  26.358     1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
  26.359     1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,  720,
  26.360     1,    1,    1,    1,  736,    0,    0,    0,    0,    0,    0,    0,    1,    1,    1,    1,
  26.361     1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
  26.362     1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
  26.363     1,    1,    1,    1,    1,    1,    1,  752,    0,    0,    0,    0,    0,    0,    0,    0,
  26.364     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  26.365     0,    0,    0,    0,    0,    0,    0,    0,    0,    1,  768,  784,    1,  800,  816,  832,
  26.366     0,    0,    0,    0,65534, 2047,65534, 2047,    0,    0,    0,    0,65535,65407,65535,65407,
  26.367 65535,65535,65532,   15,    0,65535,65535,65535,65535,65535,16383,63999,    3,    0,16415,    0,
  26.368     0,    0,    0,    0,   32,    0,    0, 1024,55104,65535,65531,65535,32767,64767,65535,   15,
  26.369 65535,65535,65535,65535,65535,65535,65535,65535,61443,65535,65535,65535, 6559,65535,65535,  831,
  26.370     0,    0,    0,65534,65535,  639,65534,65535,  255,    0,    0,    0,    0,65535, 2047,    7,
  26.371     0,    0,65534, 2047,65534,   63,    0,65535,65535,65535,65535,65535,65535, 8175, 8702, 7168,
  26.372     0,65535, 8191,65535,    0,    0,    0,    0,65535,65535,65535,    1,    0,    0,    0,    0,
  26.373 65518,65535,65535,58367, 8191,65281,   15,    0,40942,65529,65023,50117, 6559,45184,   15,    3,
  26.374 34788,65529,65023,50029, 6535,24064,    0,   31,45038,65531,65023,58349, 7103,    1,    1,    0,
  26.375 40942,65529,65023,58317, 6543,45248,    3,    0,51180,54845,50968,50111, 7623,  128,    0,    0,
  26.376 57326,65533,65023,50159, 7647,   96,    3,    0,57324,65533,65023,50159, 7647,16480,    3,    0,
  26.377 57324,65533,65023,50175, 7631,  128,    3,    0,65516,64639,65535,12283,32895,65375,    0,   12,
  26.378 65534,65535,65535, 2047,32767,    0,    0,    0, 9622,65264,60590,15359, 8223,12288,    0,    0,
  26.379     1,    0,    0,    0,65279,65535, 2047,65534, 3843,65279,65535, 8191,    0,    0,    0,    0,
  26.380 65535,65535,63227,  327,    0, 1023,    0,    0,    0,    0,65535,65535,   63,65535,65535,  127,
  26.381 65535,65535,65535,65535,65535,33791,65535,65535,65535,65535,65287,65535,65535,65535,65535, 1023,
  26.382 65407,65535,65535,65535,15743,15743,65535,65535,15743,65535,32767,32573,32573,65407,32767,65535,
  26.383 32767,32573,65535,65535,65407, 2047,    0,    0,    0,    0,65535,65535,65535,65535,65535,   31,
  26.384 65534,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,
  26.385 65535,65535,65535,65535,65535,65535,40959,  127,65534, 2047,65535,65535,65535,65535, 2047,    0,
  26.386     0,    0,    0,    0,    0,    0,    0,    0,65535,65535,65535,65535,  511,    0,    0,    0,
  26.387     0,    0,65535,65535,65527,65535,65535,  255,65535,65535, 1023,    0,    0,    0,    0,    0,
  26.388 65535,65535,65535,65535,65535,65535,65535,65535,65535, 4095,65535,65535,65535,65535,65535, 1023,
  26.389 65535,16191,65535,65535,16191,43775,65535,16383,65535,65535,65535,24543, 8156, 4047, 8191, 8156,
  26.390     0,    0,    0,    0,    0,    0,    0,32768,    0,    0,    0,    0,    0,    0,    0,    0,
  26.391 64644,15919,48464, 1019,    0,    0,65535,65535,   15,    0,    0,    0,    0,    0,    0,    0,
  26.392   192,    0, 1022, 1792,65534,65535,65535,65535,65535,   31,65534,65535,65535,65535,65535, 2047,
  26.393 65504,65535, 8191,65534,65535,65535,65535,65535,32767,    0,65535,  255,    0,    0,    0,    0,
  26.394 65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,   63,    0,    0,    0,    0,
  26.395 65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,   63,    0,    0,    0,    0,    0,
  26.396 65535,65535,65535,65535,65535,65535,65535,65535, 8191,    0,    0,    0,    0,    0,    0,    0,
  26.397 65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,   15,    0,    0,    0,    0,    0,
  26.398 65535,65535,16383,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  26.399   127,41208,65023,24447,65499,65535,65535,65535,65535,65535,65535,    3,    0,65528,65535,65535,
  26.400 65535,65535,65535,16383,    0,65535,65535,65535,65535,65532,65535,65535,  255,    0,    0, 4095,
  26.401     0,    0,    0,    0,    0,    0,    0,65495,65535,65535,65535,65535,65535,65535,65535, 8191,
  26.402     0,    0,65534, 2047,65534, 2047,65472,65534,65535,16383,65535,32767,64764, 7420,    0,    0};
  26.403 
  26.404 const UInt16 UnicodeDigitBits[] = {
  26.405   256,    0,    0,    0,    0,    0,  272,    0,    0,  288,  304,  320,  336,  352,  368,  384,
  26.406   400,    0,    0,  416,    0,    0,    0,  432,  448,    0,    0,    0,    0,    0,    0,    0,
  26.407     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  26.408     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  26.409     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  26.410     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  26.411     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  26.412     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  26.413     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  26.414     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  26.415     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  26.416     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  26.417     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  26.418     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  26.419     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  26.420     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,  464,
  26.421     0,    0,    0, 1023,    0,    0,    0,    0,    0,    0,    0,  524,    0,    0,    0,    0,
  26.422     0,    0,    0,    0,    0,    0, 1023,    0,    0,    0,    0,    0,    0,    0,    0, 1023,
  26.423     0,    0,    0,    0,    0,    0,65472,    0,    0,    0,    0,    0,    0,    0,65472,    0,
  26.424     0,    0,    0,    0,    0,    0,65472,    0,    0,    0,    0,    0,    0,    0,65472,    0,
  26.425     0,    0,    0,    0,    0,    0,65472,    0,    0,    0,    0,    0,    0,    0,65408,    0,
  26.426     0,    0,    0,    0,    0,    0,65472,    0,    0,    0,    0,    0,    0,    0,65472,    0,
  26.427     0,    0,    0,    0,    0,    0,65472,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  26.428     0,    0,    0,    0,    0, 1023,    0,    0,    0,    0,    0,    0,    0, 1023,    0,    0,
  26.429     0,    0, 1023,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  26.430     0,    0,    0,    0, 1023,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  26.431     0,    0,    0,    0,    0,    0,65024,    3,    0,    0,    0,    0,    0,    0,    0,    0,
  26.432     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0, 1023,    0,
  26.433     0, 1023,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  26.434     0, 1023,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0};
  26.435 
  26.436 const UInt16 UnicodeSpaceBits[] = {
  26.437   256,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  26.438     0,    0,    0,    0,    0,    0,  272,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  26.439   288,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  26.440   304,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  26.441     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  26.442     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  26.443     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  26.444     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  26.445     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  26.446     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  26.447     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  26.448     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  26.449     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  26.450     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  26.451     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  26.452     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  26.453 15872,    0,    1,    0,    0,    0,    0,    0,    0,    0,    1,    0,    0,    0,    0,    0,
  26.454     0,    0,    0,    0,    0,    0,    0,    0,    1,    0,    0,    0,    0,    0,    0,    0,
  26.455  4095,    0,33536,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  26.456     1,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0};
  26.457 
  26.458 const UInt16 UnicodeXDigitBits[] = {
  26.459   256,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  26.460     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  26.461     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  26.462     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  26.463     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  26.464     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  26.465     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  26.466     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  26.467     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  26.468     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  26.469     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  26.470     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  26.471     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  26.472     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  26.473     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  26.474     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,  272,
  26.475     0,    0,    0, 1023,  126,    0,  126,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  26.476     0, 1023,  126,    0,  126,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0};
  26.477 
  26.478 // Uncomment if necessary
  26.479 //const UInt16 UnicodeCntrlBits[] = {
  26.480 //  256,    0,    0,    0,    0,    0,    0,  272,    0,    0,    0,    0,    0,    0,    0,    0,
  26.481 //    0,    0,    0,    0,    0,    0,    0,    0,  288,    0,    0,    0,    0,    0,    0,    0,
  26.482 //  304,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  26.483 //    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  26.484 //    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  26.485 //    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  26.486 //    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  26.487 //    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  26.488 //    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  26.489 //    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  26.490 //    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  26.491 //    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  26.492 //    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  26.493 //    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  26.494 //    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  26.495 //    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,  320,  336,
  26.496 //65535,65535,    0,    0,    0,    0,    0,32768,65535,65535,    0,    0,    0,    0,    0,    0,
  26.497 //32768,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  26.498 //30720,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  26.499 //61440,    0,31744,    0,    0,    0,64512,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  26.500 //    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,32768,
  26.501 //    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0, 3584};
  26.502 //
  26.503 //const UInt16 UnicodeGraphBits[] = {
  26.504 //  256,    1,  272,  288,  304,  320,  336,  352,    0,  368,  384,  400,  416,  432,  448,  464,
  26.505 //  480,  496,  512,  528,  544,    1,  560,  576,  592,    0,    0,    0,    0,    0,  608,  624,
  26.506 //  640,  656,    0,  672,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  26.507 //  688,  704,    0,    0,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
  26.508 //    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,  720,    1,    1,
  26.509 //    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
  26.510 //    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
  26.511 //    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
  26.512 //    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
  26.513 //    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,  736,
  26.514 //    1,    1,    1,    1,  752,    0,    0,    0,    0,    0,    0,    0,    1,    1,    1,    1,
  26.515 //    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
  26.516 //    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
  26.517 //    1,    1,    1,    1,    1,    1,    1,  768,    0,    0,    0,    0,    0,    0,    0,    0,
  26.518 //    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  26.519 //    0,    0,    0,    0,    0,    0,    0,    0,    0,    1,  784,  800,    1,  816,  832,  848,
  26.520 //    0,    0,65534,65535,65535,65535,65535,32767,    0,    0,65534,65535,65535,65535,65535,65535,
  26.521 //65535,65535,65532,   15,    0,65535,65535,65535,65535,65535,16383,63999,    3,    0,16415,    0,
  26.522 //    0,    0,    0,    0,   32,    0,    0,17408,55232,65535,65531,65535,32767,64767,65535,   15,
  26.523 //65535,65535,65535,65535,65535,65535,65535,65535,61443,65535,65535,65535, 6559,65535,65535,  831,
  26.524 //    0,    0,    0,65534,65535,65151,65534,65535, 1791,    0,    0,16384,    9,65535, 2047,   31,
  26.525 // 4096,34816,65534, 2047,65534,   63,16383,65535,65535,65535,65535,65535,65535, 8191, 8702, 8191,
  26.526 //16383,65535, 8191,65535,    0,    0,    0,    0,65535,65535,65535,    1,    0,    0,    0,    0,
  26.527 //65518,65535,65535,58367, 8191,65281,65535,    1,40942,65529,65023,50117, 6559,45184,65487,    3,
  26.528 //34788,65529,65023,50029, 6535,24064,65472,   31,45038,65531,65023,58349, 7103,    1,65473,    0,
  26.529 //40942,65529,65023,58317, 6543,45248,65475,    0,51180,54845,50968,50111, 7623,  128,65408,    0,
  26.530 //57326,65533,65023,50159, 7647,   96,65475,    0,57324,65533,65023,50159, 7647,16480,65475,    0,
  26.531 //57324,65533,65023,50175, 7631,  128,65475,    0,65516,64639,65535,12283,32895,65375,    0,   28,
  26.532 //65534,65535,65535, 2047,65535, 4095,    0,    0, 9622,65264,60590,15359, 8223,13311,    0,    0,
  26.533 //65521,    7, 1023,15360,65279,65535, 2047,65534, 3875,65279,65535, 8191,    0,    0,    0,    0,
  26.534 //65535,65535,63227,  327,65535, 1023,    0,    0,    0,    0,65535,65535,   63,65535,65535, 2175,
  26.535 //65535,65535,65535,65535,65535,33791,65535,65535,65535,65535,65287,65535,65535,65535,65535, 1023,
  26.536 //65407,65535,65535,65535,15743,15743,65535,65535,15743,65535,32767,32573,32573,65407,32767,65535,
  26.537 //32767,32573,65535,65535,65407, 2047,65534,    3,    0,    0,65535,65535,65535,65535,65535,   31,
  26.538 //65534,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,
  26.539 //65535,65535,65535,65535,65535,65535,65535,  127,65534, 8191,65535,65535,65535,65535,16383,    0,
  26.540 //    0,    0,    0,    0,    0,    0,    0,    0,65535,65535,65535,65535,  511, 6128, 1023,    0,
  26.541 // 2047, 1023,65535,65535,65527,65535,65535,  255,65535,65535, 1023,    0,    0,    0,    0,    0,
  26.542 //65535,65535,65535,65535,65535,65535,65535,65535,65535, 4095,65535,65535,65535,65535,65535, 1023,
  26.543 //65535,16191,65535,65535,16191,43775,65535,16383,65535,65535,65535,24543, 8156, 4047, 8191, 8156,
  26.544 //    0,65535,  255,65535,16239,    0,    0,57344,24576,    0,    0,    0,    0,    0,    0,    0,
  26.545 //64644,15919,48464, 1019,    0,    0,65535,65535,   15,    0,    0,    0,    0,    0,    0,    0,
  26.546 //    0,    0, 1536,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  26.547 //65486,65523, 1022, 1793,65534,65535,65535,65535,65535,   31,65534,65535,65535,65535,65535, 4095,
  26.548 //65504,65535, 8191,65534,65535,65535,65535,65535,32767,    0,65535,  255,    0,    0,    0,    0,
  26.549 //65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,   63,    0,    0,    0,    0,
  26.550 //65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,   63,    0,    0,    0,    0,    0,
  26.551 //65535,65535,65535,65535,65535,65535,65535,65535, 8191,    0,    0,    0,    0,    0,    0,    0,
  26.552 //65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,   15,    0,    0,    0,    0,    0,
  26.553 //65535,65535,16383,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  26.554 //  127,41208,65023,24447,65499,65535,65535,65535,65535,65535,65535,    3,    0,65528,65535,65535,
  26.555 //65535,65535,65535,65535,    0,65535,65535,65535,65535,65532,65535,65535,  255,    0,    0, 4095,
  26.556 //    0,    0,    0,65535,65055,65527, 3339,65495,65535,65535,65535,65535,65535,65535,65535, 8191,
  26.557 //63470,36863,65535,49151,65534,12287,65534,65534,65535,16383,65535,32767,64764, 7420,    0,    0};
  26.558 //
  26.559 //const UInt16 UnicodePrintBits[] = {
  26.560 //  256,    1,  272,  288,  304,  320,  336,  352,    0,  368,  384,  400,  416,  432,  448,  464,
  26.561 //  480,  496,  512,  528,  544,    1,  560,  576,  592,    0,    0,    0,    0,    0,  608,  624,
  26.562 //  640,  656,    0,  672,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  26.563 //  688,  704,    0,    0,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
  26.564 //    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,  720,    1,    1,
  26.565 //    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
  26.566 //    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
  26.567 //    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
  26.568 //    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
  26.569 //    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,  736,
  26.570 //    1,    1,    1,    1,  752,    0,    0,    0,    0,    0,    0,    0,    1,    1,    1,    1,
  26.571 //    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
  26.572 //    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
  26.573 //    1,    1,    1,    1,    1,    1,    1,  768,    0,    0,    0,    0,    0,    0,    0,    0,
  26.574 //    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  26.575 //    0,    0,    0,    0,    0,    0,    0,    0,    0,    1,  784,  800,    1,  816,  832,  848,
  26.576 //  512,    0,65535,65535,65535,65535,65535,32767,    0,    0,65535,65535,65535,65535,65535,65535,
  26.577 //65535,65535,65532,   15,    0,65535,65535,65535,65535,65535,16383,63999,    3,    0,16415,    0,
  26.578 //    0,    0,    0,    0,   32,    0,    0,17408,55232,65535,65531,65535,32767,64767,65535,   15,
  26.579 //65535,65535,65535,65535,65535,65535,65535,65535,61443,65535,65535,65535, 6559,65535,65535,  831,
  26.580 //    0,    0,    0,65534,65535,65151,65534,65535, 1791,    0,    0,16384,    9,65535, 2047,   31,
  26.581 // 4096,34816,65534, 2047,65534,   63,16383,65535,65535,65535,65535,65535,65535, 8191, 8702, 8191,
  26.582 //16383,65535, 8191,65535,    0,    0,    0,    0,65535,65535,65535,    1,    0,    0,    0,    0,
  26.583 //65518,65535,65535,58367, 8191,65281,65535,    1,40942,65529,65023,50117, 6559,45184,65487,    3,
  26.584 //34788,65529,65023,50029, 6535,24064,65472,   31,45038,65531,65023,58349, 7103,    1,65473,    0,
  26.585 //40942,65529,65023,58317, 6543,45248,65475,    0,51180,54845,50968,50111, 7623,  128,65408,    0,
  26.586 //57326,65533,65023,50159, 7647,   96,65475,    0,57324,65533,65023,50159, 7647,16480,65475,    0,
  26.587 //57324,65533,65023,50175, 7631,  128,65475,    0,65516,64639,65535,12283,32895,65375,    0,   28,
  26.588 //65534,65535,65535, 2047,65535, 4095,    0,    0, 9622,65264,60590,15359, 8223,13311,    0,    0,
  26.589 //65521,    7, 1023,15360,65279,65535, 2047,65534, 3875,65279,65535, 8191,    0,    0,    0,    0,
  26.590 //65535,65535,63227,  327,65535, 1023,    0,    0,    0,    0,65535,65535,   63,65535,65535, 2175,
  26.591 //65535,65535,65535,65535,65535,33791,65535,65535,65535,65535,65287,65535,65535,65535,65535, 1023,
  26.592 //65407,65535,65535,65535,15743,15743,65535,65535,15743,65535,32767,32573,32573,65407,32767,65535,
  26.593 //32767,32573,65535,65535,65407, 2047,65534,    3,    0,    0,65535,65535,65535,65535,65535,   31,
  26.594 //65534,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,
  26.595 //65535,65535,65535,65535,65535,65535,65535,  127,65534, 8191,65535,65535,65535,65535,16383,    0,
  26.596 //    0,    0,    0,    0,    0,    0,    0,    0,65535,65535,65535,65535,  511, 6128, 1023,    0,
  26.597 // 2047, 1023,65535,65535,65527,65535,65535,  255,65535,65535, 1023,    0,    0,    0,    0,    0,
  26.598 //65535,65535,65535,65535,65535,65535,65535,65535,65535, 4095,65535,65535,65535,65535,65535, 1023,
  26.599 //65535,16191,65535,65535,16191,43775,65535,16383,65535,65535,65535,24543, 8156, 4047, 8191, 8156,
  26.600 //    0,65535,  255,65535,16239,    0,    0,57344,24576,    0,    0,    0,    0,    0,    0,    0,
  26.601 //64644,15919,48464, 1019,    0,    0,65535,65535,   15,    0,    0,    0,    0,    0,    0,    0,
  26.602 //    0,    0, 1536,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  26.603 //65487,65523, 1022, 1793,65534,65535,65535,65535,65535,   31,65534,65535,65535,65535,65535, 4095,
  26.604 //65504,65535, 8191,65534,65535,65535,65535,65535,32767,    0,65535,  255,    0,    0,    0,    0,
  26.605 //65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,   63,    0,    0,    0,    0,
  26.606 //65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,   63,    0,    0,    0,    0,    0,
  26.607 //65535,65535,65535,65535,65535,65535,65535,65535, 8191,    0,    0,    0,    0,    0,    0,    0,
  26.608 //65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,   15,    0,    0,    0,    0,    0,
  26.609 //65535,65535,16383,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  26.610 //  127,41208,65023,24447,65499,65535,65535,65535,65535,65535,65535,    3,    0,65528,65535,65535,
  26.611 //65535,65535,65535,65535,    0,65535,65535,65535,65535,65532,65535,65535,  255,    0,    0, 4095,
  26.612 //    0,    0,    0,65535,65055,65527, 3339,65495,65535,65535,65535,65535,65535,65535,65535,40959,
  26.613 //63470,36863,65535,49151,65534,12287,65534,65534,65535,16383,65535,32767,64764, 7420,    0,    0};
  26.614 //
  26.615 //const UInt16 UnicodePunctBits[] = {
  26.616 //  256,    0,    0,  272,    0,  288,  304,  320,    0,  336,    0,    0,    0,  352,  368,  384,
  26.617 //  400,    0,    0,  416,    0,    0,  432,  448,  464,    0,    0,    0,    0,    0,    0,    0,
  26.618 //  480,    0,    0,  496,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  26.619 //  512,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  26.620 //    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  26.621 //    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  26.622 //    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  26.623 //    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  26.624 //    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  26.625 //    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  26.626 //    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  26.627 //    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  26.628 //    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  26.629 //    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  26.630 //    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  26.631 //    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,  528,  544,  560,
  26.632 //    0,    0,65534,64512,    1,63488,    1,30720,    0,    0,65534,65535,    0,  128,    0,  128,
  26.633 //    0,    0,    0,    0,    0,    0,    0,16384,  128,    0,    0,    0,    0,    0,    0,    0,
  26.634 //    0,    0,    0,    0,    0,64512,    0,    0, 1536,    0,    0,16384,    9,    0,    0,   24,
  26.635 // 4096,34816,    0,    0,    0,    0,15360,    0,    0,    0,    0,    0,    0,   16,    0,    0,
  26.636 //16383,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  26.637 //    0,    0,    0,    0,    0,    0,   48,    1,    0,    0,    0,    0,    0,    0,    0,    0,
  26.638 //    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,   16,
  26.639 //    0,    0,    0,    0,32768, 3072,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  26.640 //65520,    7,    0,15360,    0,    0,    0,    0,   32,    0,    0,    0,    0,    0,    0,    0,
  26.641 //    0,    0,    0,    0,64512,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0, 2048,
  26.642 //    0,    0,    0,    0,    0,    0,  510,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  26.643 //    0,    0,    0,    0,    0,    0,24576,    0,    0, 6144,    0,    0,    0,    0,14336,    0,
  26.644 //    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0, 6128,    0,    0,
  26.645 // 2047,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  26.646 //    0,65535,  255,65535,16239,    0,    0,24576,24576,    0,    0,    0,    0,    0,    0,    0,
  26.647 //    0,    0, 1536,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  26.648 //65294,65523,    0,    1,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0, 2048,
  26.649 //    0,    0,    0,49152,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  26.650 //    0,    0,    0,65535,65055,65527, 3339,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  26.651 //63470,35840,    1,47104,    0,10240,   62,    0,    0,    0,    0,    0,    0,    0,    0,    0};
  26.652 //
  26.653 //const UInt16 UnicodeLowerBits[] = {
  26.654 //  256,  272,  288,  304,  320,  336,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  26.655 //    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,  352,  368,
  26.656 //  384,  400,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  26.657 //    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  26.658 //    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  26.659 //    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  26.660 //    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  26.661 //    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  26.662 //    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  26.663 //    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  26.664 //    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  26.665 //    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  26.666 //    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  26.667 //    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  26.668 //    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  26.669 //    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,  416,    0,    0,    0,  432,
  26.670 //    0,    0,    0,    0,    0,    0,65534, 2047,    0,    0,    0,    0,    0,32768,65535,65407,
  26.671 //43690,43690,43690,21930,43861,43690,43690,54442,12585,20004,11562,58961,23392,46421,43690,43565,
  26.672 //43690,43690,43688,   10,    0,65535,65535,65535,65535,65535,16383,    0,    0,    0,    0,    0,
  26.673 //    0,    0,    0,    0,    0,    0,    0,    0,    0,    1,61440,65535,32767,43235,43690,   15,
  26.674 //    0,    0,    0,65535,65535,65535,43690,43690,40962,43690,43690,43690, 4372,43690,43690,  554,
  26.675 //    0,    0,    0,    0,    0,    0,65534,65535,  255,    0,    0,    0,    0,    0,    0,    0,
  26.676 //43690,43690,43690,43690,43690,43690,43690,43690,43690, 4074,43690,43690,43690,43690,43690,  682,
  26.677 //  255,   63,  255,  255,   63,  255,  255,16383,65535,65535,65535,20703, 4316,  207,  255, 4316,
  26.678 //    0,    0,    0,    0,    0,    0,    0,32768,    0,    0,    0,    0,    0,    0,    0,    0,
  26.679 //50176,    8,32768,  528,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  26.680 //  127,  248,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  26.681 //    0,    0,    0,    0,65534, 2047,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0};
  26.682 //
  26.683 //const UInt16 UnicodeUpperBits[] = {
  26.684 //  256,  272,  288,  304,  320,  336,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  26.685 //  352,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,  368,  384,
  26.686 //    0,  400,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  26.687 //    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  26.688 //    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  26.689 //    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  26.690 //    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  26.691 //    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  26.692 //    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  26.693 //    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  26.694 //    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  26.695 //    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  26.696 //    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  26.697 //    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  26.698 //    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  26.699 //    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,  416,
  26.700 //    0,    0,    0,    0,65534, 2047,    0,    0,    0,    0,    0,    0,65535,32639,    0,    0,
  26.701 //21845,21845,21845,43605,21674,21845,21845,11093,52950,45531,53973, 4526,44464,19114,21845,21974,
  26.702 //21845,21845,21844,    5,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  26.703 //    0,    0,    0,    0,    0,    0,    0,    0,55104,65534, 4091,    0,    0,21532,21845,    0,
  26.704 //65535,65535,65535,    0,    0,    0,21845,21845,20481,21845,21845,21845, 2187,21845,21845,  277,
  26.705 //    0,    0,    0,65534,65535,  127,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  26.706 //    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,65535,65535,   63,    0,    0,    0,
  26.707 //21845,21845,21845,21845,21845,21845,21845,21845,21845,   21,21845,21845,21845,21845,21845,  341,
  26.708 //65280,16128,65280,65280,16128,43520,65280,    0,65280,65280,65280, 7936, 7936, 3840, 7936, 7936,
  26.709 //14468,15911,15696,   11,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  26.710 //    0,    0,65534, 2047,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0};
  26.711 
  26.712 
  26.713 // MA: March 19, 2010
  26.714 // Modified ToUpper and ToLower tables to match values expected by AS3 tests.
  26.715 // ToLower modifications:
  26.716 //    304 ->  105
  26.717 //   1024 -> 1104 *
  26.718 //   1037 -> 1117 * 
  26.719 // UoUpper modifications:
  26.720 //    255 ->  376
  26.721 //    305 ->   73
  26.722 //    383 ->   83
  26.723 //   1104 -> 1024 *
  26.724 //   1117 -> 1037 *
  26.725 // Entries marked with a '*' don't make complete sense based on Unicode manual, although
  26.726 // they match AS3.
  26.727 
  26.728 
  26.729 static const UInt16 UnicodeToUpperBits[] = {
  26.730   256,  272,  288,  304,  320,  336,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  26.731     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,  352,  368,
  26.732     0,  384,    0,    0,  400,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  26.733     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  26.734     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  26.735     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  26.736     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  26.737     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  26.738     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  26.739     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  26.740     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  26.741     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  26.742     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  26.743     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  26.744     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  26.745     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,  416,
  26.746     0,    0,    0,    0,    0,    0,65534, 2047,    0,    0,    0,    0,    0,    0,65535,65407,
  26.747 43690,43690,43690,21674,43349,43690,43690,54442, 4392,  516, 8490, 8785,21056,46421,43690,43048, // MA: Modified for AS3.
  26.748 43690,  170,    0,    0,    0, 2776,33545,   36, 3336,    4,    0,    0,    0,    0,    0,    0,
  26.749     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,61440,65534,32767,    0,43688,    0,
  26.750     0,    0,    0,65535,65535,65535,43690,43690,    2,43690,43690,43690, 4372,43690,35498,  554, // MA: Modified for AS3.
  26.751     0,    0,    0,    0,    0,    0,65534,65535,  127,    0,    0,    0,    0,    0,    0,    0,
  26.752 43690,43690,43690,43690,43690,43690,43690,43690,43690,   42,43690,43690,43690,43690,43690,  682,
  26.753   255,   63,  255,  255,   63,  170,  255,16383,    0,    0,    0,    3,    0,    3,   35,    0,
  26.754     0,    0,    0,    0,    0,    0,    0,65535,    0,    0,    0,    0,    0,    0,    0,    0,
  26.755     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,65535, 1023,    0,
  26.756     0,    0,    0,    0,65534, 2047,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0};
  26.757 
  26.758 static const UInt16 UnicodeToLowerBits[] = {
  26.759   256,  272,  288,  304,  320,  336,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  26.760   352,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,  368,  384,
  26.761     0,  400,    0,    0,  416,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  26.762     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  26.763     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  26.764     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  26.765     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  26.766     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  26.767     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  26.768     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  26.769     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  26.770     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  26.771     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  26.772     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  26.773     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  26.774     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,  432,
  26.775     0,    0,    0,    0,65534, 2047,    0,    0,    0,    0,    0,    0,65535,32639,    0,    0,
  26.776 21845,21845,21845,43605,21674,21845,21845,11093,52950,45531,53909, 4526,42128,19114,21845,21522,// MA: Modidied for AS3.
  26.777 21845,   85,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  26.778     0,    0,    0,    0,    0,    0,    0,    0,55104,65534, 4091,    0,    0,    0,21844,    0,
  26.779 65535,65535,65535,    0,    0,    0,21845,21845,    1,21845,21845,21845, 2186,21845,17749,  277,
  26.780     0,    0,    0,65534,65535,  127,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  26.781     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,65535,65535,   63,    0,    0,    0,
  26.782 21845,21845,21845,21845,21845,21845,21845,21845,21845,   21,21845,21845,21845,21845,21845,  341,
  26.783 65280,16128,65280,65280,16128,43520,65280,    0,    0,    0,    0, 3840, 3840, 3840, 7936, 3840,
  26.784     0,    0,    0,    0,    0,    0,65535,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  26.785     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,65472,65535,    0,    0,    0,
  26.786     0,    0,65534, 2047,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0};
  26.787 
  26.788 struct GUnicodePairType
  26.789 {
  26.790     UInt16 Key, Value;
  26.791 };
  26.792 
  26.793 static inline bool CmpUnicodeKey(const GUnicodePairType& a, UInt16 key)
  26.794 {
  26.795     return a.Key < key;
  26.796 }
  26.797 
  26.798 static const GUnicodePairType UnicodeToUpperTable[] = {
  26.799 {   97,   65}, {   98,   66}, {   99,   67}, {  100,   68}, {  101,   69}, {  102,   70}, {  103,   71},
  26.800 {  104,   72}, {  105,   73}, {  106,   74}, {  107,   75}, {  108,   76}, {  109,   77}, {  110,   78},
  26.801 {  111,   79}, {  112,   80}, {  113,   81}, {  114,   82}, {  115,   83}, {  116,   84}, {  117,   85},
  26.802 {  118,   86}, {  119,   87}, {  120,   88}, {  121,   89}, {  122,   90}, {  224,  192}, {  225,  193},
  26.803 {  226,  194}, {  227,  195}, {  228,  196}, {  229,  197}, {  230,  198}, {  231,  199}, {  232,  200},
  26.804 {  233,  201}, {  234,  202}, {  235,  203}, {  236,  204}, {  237,  205}, {  238,  206}, {  239,  207},
  26.805 {  240,  208}, {  241,  209}, {  242,  210}, {  243,  211}, {  244,  212}, {  245,  213}, {  246,  214},
  26.806 {  248,  216}, {  249,  217}, {  250,  218}, {  251,  219}, {  252,  220}, {  253,  221}, {  254,  222},
  26.807 {  255,  376}, {  257,  256}, {  259,  258}, {  261,  260}, {  263,  262}, {  265,  264}, {  267,  266},
  26.808 {  269,  268}, {  271,  270}, {  273,  272}, {  275,  274}, {  277,  276}, {  279,  278}, {  281,  280},
  26.809 {  283,  282}, {  285,  284}, {  287,  286}, {  289,  288}, {  291,  290}, {  293,  292}, {  295,  294},
  26.810 {  297,  296}, {  299,  298}, {  301,  300}, {  303,  302}, {  305,   73}, {  307,  306}, {  309,  308}, {  311,  310},
  26.811 {  314,  313}, {  316,  315}, {  318,  317}, {  320,  319}, {  322,  321}, {  324,  323}, {  326,  325},
  26.812 {  328,  327}, {  331,  330}, {  333,  332}, {  335,  334}, {  337,  336}, {  339,  338}, {  341,  340},
  26.813 {  343,  342}, {  345,  344}, {  347,  346}, {  349,  348}, {  351,  350}, {  353,  352}, {  355,  354},
  26.814 {  357,  356}, {  359,  358}, {  361,  360}, {  363,  362}, {  365,  364}, {  367,  366}, {  369,  368},
  26.815 {  371,  370}, {  373,  372}, {  375,  374}, {  378,  377}, {  380,  379}, {  382,  381}, {  383,   83}, {  387,  386},
  26.816 {  389,  388}, {  392,  391}, {  396,  395}, {  402,  401}, {  409,  408}, {  417,  416}, {  419,  418},
  26.817 {  421,  420}, {  424,  423}, {  429,  428}, {  432,  431}, {  436,  435}, {  438,  437}, {  441,  440},
  26.818 {  445,  444}, {  454,  452}, {  457,  455}, {  460,  458}, {  462,  461}, {  464,  463}, {  466,  465},
  26.819 {  468,  467}, {  470,  469}, {  472,  471}, {  474,  473}, {  476,  475}, {  477,  398}, {  479,  478},
  26.820 {  481,  480}, {  483,  482}, {  485,  484}, {  487,  486}, {  489,  488}, {  491,  490}, {  493,  492},
  26.821 {  495,  494}, {  499,  497}, {  501,  500}, {  507,  506}, {  509,  508}, {  511,  510}, {  513,  512},
  26.822 {  515,  514}, {  517,  516}, {  519,  518}, {  521,  520}, {  523,  522}, {  525,  524}, {  527,  526},
  26.823 {  529,  528}, {  531,  530}, {  533,  532}, {  535,  534}, {  595,  385}, {  596,  390}, {  598,  393},
  26.824 {  599,  394}, {  601,  399}, {  603,  400}, {  608,  403}, {  611,  404}, {  616,  407}, {  617,  406},
  26.825 {  623,  412}, {  626,  413}, {  629,  415}, {  643,  425}, {  648,  430}, {  650,  433}, {  651,  434},
  26.826 {  658,  439}, {  940,  902}, {  941,  904}, {  942,  905}, {  943,  906}, {  945,  913}, {  946,  914},
  26.827 {  947,  915}, {  948,  916}, {  949,  917}, {  950,  918}, {  951,  919}, {  952,  920}, {  953,  921},
  26.828 {  954,  922}, {  955,  923}, {  956,  924}, {  957,  925}, {  958,  926}, {  959,  927}, {  960,  928},
  26.829 {  961,  929}, {  962,  931}, {  963,  931}, {  964,  932}, {  965,  933}, {  966,  934}, {  967,  935},
  26.830 {  968,  936}, {  969,  937}, {  970,  938}, {  971,  939}, {  972,  908}, {  973,  910}, {  974,  911},
  26.831 {  995,  994}, {  997,  996}, {  999,  998}, { 1001, 1000}, { 1003, 1002}, { 1005, 1004}, { 1007, 1006},
  26.832 { 1072, 1040}, { 1073, 1041}, { 1074, 1042}, { 1075, 1043}, { 1076, 1044}, { 1077, 1045}, { 1078, 1046},
  26.833 { 1079, 1047}, { 1080, 1048}, { 1081, 1049}, { 1082, 1050}, { 1083, 1051}, { 1084, 1052}, { 1085, 1053},
  26.834 { 1086, 1054}, { 1087, 1055}, { 1088, 1056}, { 1089, 1057}, { 1090, 1058}, { 1091, 1059}, { 1092, 1060},
  26.835 { 1093, 1061}, { 1094, 1062}, { 1095, 1063}, { 1096, 1064}, { 1097, 1065}, { 1098, 1066}, { 1099, 1067},
  26.836 { 1100, 1068}, { 1101, 1069}, { 1102, 1070}, { 1103, 1071}, { 1104, 1024}, { 1105, 1025}, { 1106, 1026}, { 1107, 1027},
  26.837 { 1108, 1028}, { 1109, 1029}, { 1110, 1030}, { 1111, 1031}, { 1112, 1032}, { 1113, 1033}, { 1114, 1034},
  26.838 { 1115, 1035}, { 1116, 1036}, { 1117, 1037}, { 1118, 1038}, { 1119, 1039}, { 1121, 1120}, { 1123, 1122}, { 1125, 1124},
  26.839 { 1127, 1126}, { 1129, 1128}, { 1131, 1130}, { 1133, 1132}, { 1135, 1134}, { 1137, 1136}, { 1139, 1138},
  26.840 { 1141, 1140}, { 1143, 1142}, { 1145, 1144}, { 1147, 1146}, { 1149, 1148}, { 1151, 1150}, { 1153, 1152},
  26.841 { 1169, 1168}, { 1171, 1170}, { 1173, 1172}, { 1175, 1174}, { 1177, 1176}, { 1179, 1178}, { 1181, 1180},
  26.842 { 1183, 1182}, { 1185, 1184}, { 1187, 1186}, { 1189, 1188}, { 1191, 1190}, { 1193, 1192}, { 1195, 1194},
  26.843 { 1197, 1196}, { 1199, 1198}, { 1201, 1200}, { 1203, 1202}, { 1205, 1204}, { 1207, 1206}, { 1209, 1208},
  26.844 { 1211, 1210}, { 1213, 1212}, { 1215, 1214}, { 1218, 1217}, { 1220, 1219}, { 1224, 1223}, { 1228, 1227},
  26.845 { 1233, 1232}, { 1235, 1234}, { 1237, 1236}, { 1239, 1238}, { 1241, 1240}, { 1243, 1242}, { 1245, 1244},
  26.846 { 1247, 1246}, { 1249, 1248}, { 1251, 1250}, { 1253, 1252}, { 1255, 1254}, { 1257, 1256}, { 1259, 1258},
  26.847 { 1263, 1262}, { 1265, 1264}, { 1267, 1266}, { 1269, 1268}, { 1273, 1272}, { 1377, 1329}, { 1378, 1330},
  26.848 { 1379, 1331}, { 1380, 1332}, { 1381, 1333}, { 1382, 1334}, { 1383, 1335}, { 1384, 1336}, { 1385, 1337},
  26.849 { 1386, 1338}, { 1387, 1339}, { 1388, 1340}, { 1389, 1341}, { 1390, 1342}, { 1391, 1343}, { 1392, 1344},
  26.850 { 1393, 1345}, { 1394, 1346}, { 1395, 1347}, { 1396, 1348}, { 1397, 1349}, { 1398, 1350}, { 1399, 1351},
  26.851 { 1400, 1352}, { 1401, 1353}, { 1402, 1354}, { 1403, 1355}, { 1404, 1356}, { 1405, 1357}, { 1406, 1358},
  26.852 { 1407, 1359}, { 1408, 1360}, { 1409, 1361}, { 1410, 1362}, { 1411, 1363}, { 1412, 1364}, { 1413, 1365},
  26.853 { 1414, 1366}, { 7681, 7680}, { 7683, 7682}, { 7685, 7684}, { 7687, 7686}, { 7689, 7688}, { 7691, 7690},
  26.854 { 7693, 7692}, { 7695, 7694}, { 7697, 7696}, { 7699, 7698}, { 7701, 7700}, { 7703, 7702}, { 7705, 7704},
  26.855 { 7707, 7706}, { 7709, 7708}, { 7711, 7710}, { 7713, 7712}, { 7715, 7714}, { 7717, 7716}, { 7719, 7718},
  26.856 { 7721, 7720}, { 7723, 7722}, { 7725, 7724}, { 7727, 7726}, { 7729, 7728}, { 7731, 7730}, { 7733, 7732},
  26.857 { 7735, 7734}, { 7737, 7736}, { 7739, 7738}, { 7741, 7740}, { 7743, 7742}, { 7745, 7744}, { 7747, 7746},
  26.858 { 7749, 7748}, { 7751, 7750}, { 7753, 7752}, { 7755, 7754}, { 7757, 7756}, { 7759, 7758}, { 7761, 7760},
  26.859 { 7763, 7762}, { 7765, 7764}, { 7767, 7766}, { 7769, 7768}, { 7771, 7770}, { 7773, 7772}, { 7775, 7774},
  26.860 { 7777, 7776}, { 7779, 7778}, { 7781, 7780}, { 7783, 7782}, { 7785, 7784}, { 7787, 7786}, { 7789, 7788},
  26.861 { 7791, 7790}, { 7793, 7792}, { 7795, 7794}, { 7797, 7796}, { 7799, 7798}, { 7801, 7800}, { 7803, 7802},
  26.862 { 7805, 7804}, { 7807, 7806}, { 7809, 7808}, { 7811, 7810}, { 7813, 7812}, { 7815, 7814}, { 7817, 7816},
  26.863 { 7819, 7818}, { 7821, 7820}, { 7823, 7822}, { 7825, 7824}, { 7827, 7826}, { 7829, 7828}, { 7841, 7840},
  26.864 { 7843, 7842}, { 7845, 7844}, { 7847, 7846}, { 7849, 7848}, { 7851, 7850}, { 7853, 7852}, { 7855, 7854},
  26.865 { 7857, 7856}, { 7859, 7858}, { 7861, 7860}, { 7863, 7862}, { 7865, 7864}, { 7867, 7866}, { 7869, 7868},
  26.866 { 7871, 7870}, { 7873, 7872}, { 7875, 7874}, { 7877, 7876}, { 7879, 7878}, { 7881, 7880}, { 7883, 7882},
  26.867 { 7885, 7884}, { 7887, 7886}, { 7889, 7888}, { 7891, 7890}, { 7893, 7892}, { 7895, 7894}, { 7897, 7896},
  26.868 { 7899, 7898}, { 7901, 7900}, { 7903, 7902}, { 7905, 7904}, { 7907, 7906}, { 7909, 7908}, { 7911, 7910},
  26.869 { 7913, 7912}, { 7915, 7914}, { 7917, 7916}, { 7919, 7918}, { 7921, 7920}, { 7923, 7922}, { 7925, 7924},
  26.870 { 7927, 7926}, { 7929, 7928}, { 7936, 7944}, { 7937, 7945}, { 7938, 7946}, { 7939, 7947}, { 7940, 7948},
  26.871 { 7941, 7949}, { 7942, 7950}, { 7943, 7951}, { 7952, 7960}, { 7953, 7961}, { 7954, 7962}, { 7955, 7963},
  26.872 { 7956, 7964}, { 7957, 7965}, { 7968, 7976}, { 7969, 7977}, { 7970, 7978}, { 7971, 7979}, { 7972, 7980},
  26.873 { 7973, 7981}, { 7974, 7982}, { 7975, 7983}, { 7984, 7992}, { 7985, 7993}, { 7986, 7994}, { 7987, 7995},
  26.874 { 7988, 7996}, { 7989, 7997}, { 7990, 7998}, { 7991, 7999}, { 8000, 8008}, { 8001, 8009}, { 8002, 8010},
  26.875 { 8003, 8011}, { 8004, 8012}, { 8005, 8013}, { 8017, 8025}, { 8019, 8027}, { 8021, 8029}, { 8023, 8031},
  26.876 { 8032, 8040}, { 8033, 8041}, { 8034, 8042}, { 8035, 8043}, { 8036, 8044}, { 8037, 8045}, { 8038, 8046},
  26.877 { 8039, 8047}, { 8048, 8122}, { 8049, 8123}, { 8050, 8136}, { 8051, 8137}, { 8052, 8138}, { 8053, 8139},
  26.878 { 8054, 8154}, { 8055, 8155}, { 8056, 8184}, { 8057, 8185}, { 8058, 8170}, { 8059, 8171}, { 8060, 8186},
  26.879 { 8061, 8187}, { 8112, 8120}, { 8113, 8121}, { 8144, 8152}, { 8145, 8153}, { 8160, 8168}, { 8161, 8169},
  26.880 { 8165, 8172}, { 8560, 8544}, { 8561, 8545}, { 8562, 8546}, { 8563, 8547}, { 8564, 8548}, { 8565, 8549},
  26.881 { 8566, 8550}, { 8567, 8551}, { 8568, 8552}, { 8569, 8553}, { 8570, 8554}, { 8571, 8555}, { 8572, 8556},
  26.882 { 8573, 8557}, { 8574, 8558}, { 8575, 8559}, { 9424, 9398}, { 9425, 9399}, { 9426, 9400}, { 9427, 9401},
  26.883 { 9428, 9402}, { 9429, 9403}, { 9430, 9404}, { 9431, 9405}, { 9432, 9406}, { 9433, 9407}, { 9434, 9408},
  26.884 { 9435, 9409}, { 9436, 9410}, { 9437, 9411}, { 9438, 9412}, { 9439, 9413}, { 9440, 9414}, { 9441, 9415},
  26.885 { 9442, 9416}, { 9443, 9417}, { 9444, 9418}, { 9445, 9419}, { 9446, 9420}, { 9447, 9421}, { 9448, 9422},
  26.886 { 9449, 9423}, {65345,65313}, {65346,65314}, {65347,65315}, {65348,65316}, {65349,65317}, {65350,65318},
  26.887 {65351,65319}, {65352,65320}, {65353,65321}, {65354,65322}, {65355,65323}, {65356,65324}, {65357,65325},
  26.888 {65358,65326}, {65359,65327}, {65360,65328}, {65361,65329}, {65362,65330}, {65363,65331}, {65364,65332},
  26.889 {65365,65333}, {65366,65334}, {65367,65335}, {65368,65336}, {65369,65337}, {65370,65338}, {65535,    0}};
  26.890 
  26.891 static const GUnicodePairType UnicodeToLowerTable[] = {
  26.892 {   65,   97}, {   66,   98}, {   67,   99}, {   68,  100}, {   69,  101}, {   70,  102}, {   71,  103},
  26.893 {   72,  104}, {   73,  105}, {   74,  106}, {   75,  107}, {   76,  108}, {   77,  109}, {   78,  110},
  26.894 {   79,  111}, {   80,  112}, {   81,  113}, {   82,  114}, {   83,  115}, {   84,  116}, {   85,  117},
  26.895 {   86,  118}, {   87,  119}, {   88,  120}, {   89,  121}, {   90,  122}, {  192,  224}, {  193,  225},
  26.896 {  194,  226}, {  195,  227}, {  196,  228}, {  197,  229}, {  198,  230}, {  199,  231}, {  200,  232},
  26.897 {  201,  233}, {  202,  234}, {  203,  235}, {  204,  236}, {  205,  237}, {  206,  238}, {  207,  239},
  26.898 {  208,  240}, {  209,  241}, {  210,  242}, {  211,  243}, {  212,  244}, {  213,  245}, {  214,  246},
  26.899 {  216,  248}, {  217,  249}, {  218,  250}, {  219,  251}, {  220,  252}, {  221,  253}, {  222,  254},
  26.900 {  256,  257}, {  258,  259}, {  260,  261}, {  262,  263}, {  264,  265}, {  266,  267}, {  268,  269},
  26.901 {  270,  271}, {  272,  273}, {  274,  275}, {  276,  277}, {  278,  279}, {  280,  281}, {  282,  283},
  26.902 {  284,  285}, {  286,  287}, {  288,  289}, {  290,  291}, {  292,  293}, {  294,  295}, {  296,  297},
  26.903 {  298,  299}, {  300,  301}, {  302,  303}, {  304,  105}, {  306,  307}, {  308,  309}, {  310,  311}, {  313,  314},
  26.904 {  315,  316}, {  317,  318}, {  319,  320}, {  321,  322}, {  323,  324}, {  325,  326}, {  327,  328},
  26.905 {  330,  331}, {  332,  333}, {  334,  335}, {  336,  337}, {  338,  339}, {  340,  341}, {  342,  343},
  26.906 {  344,  345}, {  346,  347}, {  348,  349}, {  350,  351}, {  352,  353}, {  354,  355}, {  356,  357},
  26.907 {  358,  359}, {  360,  361}, {  362,  363}, {  364,  365}, {  366,  367}, {  368,  369}, {  370,  371},
  26.908 {  372,  373}, {  374,  375}, {  376,  255}, {  377,  378}, {  379,  380}, {  381,  382}, {  385,  595},
  26.909 {  386,  387}, {  388,  389}, {  390,  596}, {  391,  392}, {  393,  598}, {  394,  599}, {  395,  396},
  26.910 {  398,  477}, {  399,  601}, {  400,  603}, {  401,  402}, {  403,  608}, {  404,  611}, {  406,  617},
  26.911 {  407,  616}, {  408,  409}, {  412,  623}, {  413,  626}, {  415,  629}, {  416,  417}, {  418,  419},
  26.912 {  420,  421}, {  423,  424}, {  425,  643}, {  428,  429}, {  430,  648}, {  431,  432}, {  433,  650},
  26.913 {  434,  651}, {  435,  436}, {  437,  438}, {  439,  658}, {  440,  441}, {  444,  445}, {  452,  454},
  26.914 {  455,  457}, {  458,  460}, {  461,  462}, {  463,  464}, {  465,  466}, {  467,  468}, {  469,  470},
  26.915 {  471,  472}, {  473,  474}, {  475,  476}, {  478,  479}, {  480,  481}, {  482,  483}, {  484,  485},
  26.916 {  486,  487}, {  488,  489}, {  490,  491}, {  492,  493}, {  494,  495}, {  497,  499}, {  500,  501},
  26.917 {  506,  507}, {  508,  509}, {  510,  511}, {  512,  513}, {  514,  515}, {  516,  517}, {  518,  519},
  26.918 {  520,  521}, {  522,  523}, {  524,  525}, {  526,  527}, {  528,  529}, {  530,  531}, {  532,  533},
  26.919 {  534,  535}, {  902,  940}, {  904,  941}, {  905,  942}, {  906,  943}, {  908,  972}, {  910,  973},
  26.920 {  911,  974}, {  913,  945}, {  914,  946}, {  915,  947}, {  916,  948}, {  917,  949}, {  918,  950},
  26.921 {  919,  951}, {  920,  952}, {  921,  953}, {  922,  954}, {  923,  955}, {  924,  956}, {  925,  957},
  26.922 {  926,  958}, {  927,  959}, {  928,  960}, {  929,  961}, {  931,  963}, {  932,  964}, {  933,  965},
  26.923 {  934,  966}, {  935,  967}, {  936,  968}, {  937,  969}, {  938,  970}, {  939,  971}, {  994,  995},
  26.924 {  996,  997}, {  998,  999}, { 1000, 1001}, { 1002, 1003}, { 1004, 1005}, { 1006, 1007}, { 1024, 1104}, { 1025, 1105},
  26.925 { 1026, 1106}, { 1027, 1107}, { 1028, 1108}, { 1029, 1109}, { 1030, 1110}, { 1031, 1111}, { 1032, 1112},
  26.926 { 1033, 1113}, { 1034, 1114}, { 1035, 1115}, { 1036, 1116}, { 1037, 1117}, { 1038, 1118}, { 1039, 1119}, { 1040, 1072},
  26.927 { 1041, 1073}, { 1042, 1074}, { 1043, 1075}, { 1044, 1076}, { 1045, 1077}, { 1046, 1078}, { 1047, 1079},
  26.928 { 1048, 1080}, { 1049, 1081}, { 1050, 1082}, { 1051, 1083}, { 1052, 1084}, { 1053, 1085}, { 1054, 1086},
  26.929 { 1055, 1087}, { 1056, 1088}, { 1057, 1089}, { 1058, 1090}, { 1059, 1091}, { 1060, 1092}, { 1061, 1093},
  26.930 { 1062, 1094}, { 1063, 1095}, { 1064, 1096}, { 1065, 1097}, { 1066, 1098}, { 1067, 1099}, { 1068, 1100},
  26.931 { 1069, 1101}, { 1070, 1102}, { 1071, 1103}, { 1120, 1121}, { 1122, 1123}, { 1124, 1125}, { 1126, 1127},
  26.932 { 1128, 1129}, { 1130, 1131}, { 1132, 1133}, { 1134, 1135}, { 1136, 1137}, { 1138, 1139}, { 1140, 1141},
  26.933 { 1142, 1143}, { 1144, 1145}, { 1146, 1147}, { 1148, 1149}, { 1150, 1151}, { 1152, 1153}, { 1168, 1169},
  26.934 { 1170, 1171}, { 1172, 1173}, { 1174, 1175}, { 1176, 1177}, { 1178, 1179}, { 1180, 1181}, { 1182, 1183},
  26.935 { 1184, 1185}, { 1186, 1187}, { 1188, 1189}, { 1190, 1191}, { 1192, 1193}, { 1194, 1195}, { 1196, 1197},
  26.936 { 1198, 1199}, { 1200, 1201}, { 1202, 1203}, { 1204, 1205}, { 1206, 1207}, { 1208, 1209}, { 1210, 1211},
  26.937 { 1212, 1213}, { 1214, 1215}, { 1217, 1218}, { 1219, 1220}, { 1223, 1224}, { 1227, 1228}, { 1232, 1233},
  26.938 { 1234, 1235}, { 1236, 1237}, { 1238, 1239}, { 1240, 1241}, { 1242, 1243}, { 1244, 1245}, { 1246, 1247},
  26.939 { 1248, 1249}, { 1250, 1251}, { 1252, 1253}, { 1254, 1255}, { 1256, 1257}, { 1258, 1259}, { 1262, 1263},
  26.940 { 1264, 1265}, { 1266, 1267}, { 1268, 1269}, { 1272, 1273}, { 1329, 1377}, { 1330, 1378}, { 1331, 1379},
  26.941 { 1332, 1380}, { 1333, 1381}, { 1334, 1382}, { 1335, 1383}, { 1336, 1384}, { 1337, 1385}, { 1338, 1386},
  26.942 { 1339, 1387}, { 1340, 1388}, { 1341, 1389}, { 1342, 1390}, { 1343, 1391}, { 1344, 1392}, { 1345, 1393},
  26.943 { 1346, 1394}, { 1347, 1395}, { 1348, 1396}, { 1349, 1397}, { 1350, 1398}, { 1351, 1399}, { 1352, 1400},
  26.944 { 1353, 1401}, { 1354, 1402}, { 1355, 1403}, { 1356, 1404}, { 1357, 1405}, { 1358, 1406}, { 1359, 1407},
  26.945 { 1360, 1408}, { 1361, 1409}, { 1362, 1410}, { 1363, 1411}, { 1364, 1412}, { 1365, 1413}, { 1366, 1414},
  26.946 { 4256, 4304}, { 4257, 4305}, { 4258, 4306}, { 4259, 4307}, { 4260, 4308}, { 4261, 4309}, { 4262, 4310},
  26.947 { 4263, 4311}, { 4264, 4312}, { 4265, 4313}, { 4266, 4314}, { 4267, 4315}, { 4268, 4316}, { 4269, 4317},
  26.948 { 4270, 4318}, { 4271, 4319}, { 4272, 4320}, { 4273, 4321}, { 4274, 4322}, { 4275, 4323}, { 4276, 4324},
  26.949 { 4277, 4325}, { 4278, 4326}, { 4279, 4327}, { 4280, 4328}, { 4281, 4329}, { 4282, 4330}, { 4283, 4331},
  26.950 { 4284, 4332}, { 4285, 4333}, { 4286, 4334}, { 4287, 4335}, { 4288, 4336}, { 4289, 4337}, { 4290, 4338},
  26.951 { 4291, 4339}, { 4292, 4340}, { 4293, 4341}, { 7680, 7681}, { 7682, 7683}, { 7684, 7685}, { 7686, 7687},
  26.952 { 7688, 7689}, { 7690, 7691}, { 7692, 7693}, { 7694, 7695}, { 7696, 7697}, { 7698, 7699}, { 7700, 7701},
  26.953 { 7702, 7703}, { 7704, 7705}, { 7706, 7707}, { 7708, 7709}, { 7710, 7711}, { 7712, 7713}, { 7714, 7715},
  26.954 { 7716, 7717}, { 7718, 7719}, { 7720, 7721}, { 7722, 7723}, { 7724, 7725}, { 7726, 7727}, { 7728, 7729},
  26.955 { 7730, 7731}, { 7732, 7733}, { 7734, 7735}, { 7736, 7737}, { 7738, 7739}, { 7740, 7741}, { 7742, 7743},
  26.956 { 7744, 7745}, { 7746, 7747}, { 7748, 7749}, { 7750, 7751}, { 7752, 7753}, { 7754, 7755}, { 7756, 7757},
  26.957 { 7758, 7759}, { 7760, 7761}, { 7762, 7763}, { 7764, 7765}, { 7766, 7767}, { 7768, 7769}, { 7770, 7771},
  26.958 { 7772, 7773}, { 7774, 7775}, { 7776, 7777}, { 7778, 7779}, { 7780, 7781}, { 7782, 7783}, { 7784, 7785},
  26.959 { 7786, 7787}, { 7788, 7789}, { 7790, 7791}, { 7792, 7793}, { 7794, 7795}, { 7796, 7797}, { 7798, 7799},
  26.960 { 7800, 7801}, { 7802, 7803}, { 7804, 7805}, { 7806, 7807}, { 7808, 7809}, { 7810, 7811}, { 7812, 7813},
  26.961 { 7814, 7815}, { 7816, 7817}, { 7818, 7819}, { 7820, 7821}, { 7822, 7823}, { 7824, 7825}, { 7826, 7827},
  26.962 { 7828, 7829}, { 7840, 7841}, { 7842, 7843}, { 7844, 7845}, { 7846, 7847}, { 7848, 7849}, { 7850, 7851},
  26.963 { 7852, 7853}, { 7854, 7855}, { 7856, 7857}, { 7858, 7859}, { 7860, 7861}, { 7862, 7863}, { 7864, 7865},
  26.964 { 7866, 7867}, { 7868, 7869}, { 7870, 7871}, { 7872, 7873}, { 7874, 7875}, { 7876, 7877}, { 7878, 7879},
  26.965 { 7880, 7881}, { 7882, 7883}, { 7884, 7885}, { 7886, 7887}, { 7888, 7889}, { 7890, 7891}, { 7892, 7893},
  26.966 { 7894, 7895}, { 7896, 7897}, { 7898, 7899}, { 7900, 7901}, { 7902, 7903}, { 7904, 7905}, { 7906, 7907},
  26.967 { 7908, 7909}, { 7910, 7911}, { 7912, 7913}, { 7914, 7915}, { 7916, 7917}, { 7918, 7919}, { 7920, 7921},
  26.968 { 7922, 7923}, { 7924, 7925}, { 7926, 7927}, { 7928, 7929}, { 7944, 7936}, { 7945, 7937}, { 7946, 7938},
  26.969 { 7947, 7939}, { 7948, 7940}, { 7949, 7941}, { 7950, 7942}, { 7951, 7943}, { 7960, 7952}, { 7961, 7953},
  26.970 { 7962, 7954}, { 7963, 7955}, { 7964, 7956}, { 7965, 7957}, { 7976, 7968}, { 7977, 7969}, { 7978, 7970},
  26.971 { 7979, 7971}, { 7980, 7972}, { 7981, 7973}, { 7982, 7974}, { 7983, 7975}, { 7992, 7984}, { 7993, 7985},
  26.972 { 7994, 7986}, { 7995, 7987}, { 7996, 7988}, { 7997, 7989}, { 7998, 7990}, { 7999, 7991}, { 8008, 8000},
  26.973 { 8009, 8001}, { 8010, 8002}, { 8011, 8003}, { 8012, 8004}, { 8013, 8005}, { 8025, 8017}, { 8027, 8019},
  26.974 { 8029, 8021}, { 8031, 8023}, { 8040, 8032}, { 8041, 8033}, { 8042, 8034}, { 8043, 8035}, { 8044, 8036},
  26.975 { 8045, 8037}, { 8046, 8038}, { 8047, 8039}, { 8120, 8112}, { 8121, 8113}, { 8122, 8048}, { 8123, 8049},
  26.976 { 8136, 8050}, { 8137, 8051}, { 8138, 8052}, { 8139, 8053}, { 8152, 8144}, { 8153, 8145}, { 8154, 8054},
  26.977 { 8155, 8055}, { 8168, 8160}, { 8169, 8161}, { 8170, 8058}, { 8171, 8059}, { 8172, 8165}, { 8184, 8056},
  26.978 { 8185, 8057}, { 8186, 8060}, { 8187, 8061}, { 8544, 8560}, { 8545, 8561}, { 8546, 8562}, { 8547, 8563},
  26.979 { 8548, 8564}, { 8549, 8565}, { 8550, 8566}, { 8551, 8567}, { 8552, 8568}, { 8553, 8569}, { 8554, 8570},
  26.980 { 8555, 8571}, { 8556, 8572}, { 8557, 8573}, { 8558, 8574}, { 8559, 8575}, { 9398, 9424}, { 9399, 9425},
  26.981 { 9400, 9426}, { 9401, 9427}, { 9402, 9428}, { 9403, 9429}, { 9404, 9430}, { 9405, 9431}, { 9406, 9432},
  26.982 { 9407, 9433}, { 9408, 9434}, { 9409, 9435}, { 9410, 9436}, { 9411, 9437}, { 9412, 9438}, { 9413, 9439},
  26.983 { 9414, 9440}, { 9415, 9441}, { 9416, 9442}, { 9417, 9443}, { 9418, 9444}, { 9419, 9445}, { 9420, 9446},
  26.984 { 9421, 9447}, { 9422, 9448}, { 9423, 9449}, {65313,65345}, {65314,65346}, {65315,65347}, {65316,65348},
  26.985 {65317,65349}, {65318,65350}, {65319,65351}, {65320,65352}, {65321,65353}, {65322,65354}, {65323,65355},
  26.986 {65324,65356}, {65325,65357}, {65326,65358}, {65327,65359}, {65328,65360}, {65329,65361}, {65330,65362},
  26.987 {65331,65363}, {65332,65364}, {65333,65365}, {65334,65366}, {65335,65367}, {65336,65368}, {65337,65369},
  26.988 {65338,65370}, {65535,    0}};
  26.989 
  26.990 int OVR_CDECL OVR_towupper(wchar_t charCode)
  26.991 {
  26.992     // Don't use UnicodeUpperBits! It differs from UnicodeToUpperBits.
  26.993     if (UnicodeCharIs(UnicodeToUpperBits, charCode))
  26.994     {
  26.995         // To protect from memory overrun in case the character is not found
  26.996         // we use one extra fake element in the table {65536, 0}.
  26.997         UPInt idx = Alg::LowerBoundSliced(
  26.998             UnicodeToUpperTable,
  26.999             0,
 26.1000             sizeof(UnicodeToUpperTable) / sizeof(UnicodeToUpperTable[0]) - 1,
 26.1001             (UInt16)charCode,
 26.1002             CmpUnicodeKey);
 26.1003         return UnicodeToUpperTable[idx].Value;
 26.1004     }
 26.1005     return charCode;
 26.1006 }
 26.1007 
 26.1008 int OVR_CDECL OVR_towlower(wchar_t charCode)
 26.1009 {
 26.1010     // Don't use UnicodeLowerBits! It differs from UnicodeToLowerBits.
 26.1011     if (UnicodeCharIs(UnicodeToLowerBits, charCode))
 26.1012     {
 26.1013         // To protect from memory overrun in case the character is not found
 26.1014         // we use one extra fake element in the table {65536, 0}.
 26.1015         UPInt idx = Alg::LowerBoundSliced(
 26.1016             UnicodeToLowerTable,
 26.1017             0,
 26.1018             sizeof(UnicodeToLowerTable) / sizeof(UnicodeToLowerTable[0]) - 1,
 26.1019             (UInt16)charCode,
 26.1020             CmpUnicodeKey);
 26.1021         return UnicodeToLowerTable[idx].Value;
 26.1022     }
 26.1023     return charCode;
 26.1024 }
 26.1025 
 26.1026 #endif //OVR_NO_WCTYPE
 26.1027 
 26.1028 } // OVR
 26.1029 \ No newline at end of file
    27.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    27.2 +++ b/libovr/Src/Kernel/OVR_Std.h	Sat Sep 14 16:14:59 2013 +0300
    27.3 @@ -0,0 +1,1 @@
    27.4 +/************************************************************************************
    27.5 
    27.6 PublicHeader:   OVR.h
    27.7 Filename    :   OVR_Std.h
    27.8 Content     :   Standard C function interface
    27.9 Created     :   September 19, 2012
   27.10 Notes       : 
   27.11 
   27.12 Copyright   :   Copyright 2012 Oculus VR, Inc. All Rights reserved.
   27.13 
   27.14 Use of this software is subject to the terms of the Oculus license
   27.15 agreement provided at the time of installation or download, or which
   27.16 otherwise accompanies this software in either electronic or hard copy form.
   27.17 
   27.18 ************************************************************************************/
   27.19 
   27.20 #ifndef OVR_Std_h
   27.21 #define OVR_Std_h
   27.22 
   27.23 #include "OVR_Types.h"
   27.24 #include <stdarg.h> // for va_list args
   27.25 #include <string.h>
   27.26 #include <stdio.h>
   27.27 #include <stdlib.h>
   27.28 #include <ctype.h>
   27.29 
   27.30 #if !defined(OVR_OS_WINCE) && defined(OVR_CC_MSVC) && (OVR_CC_MSVC >= 1400)
   27.31 #define OVR_MSVC_SAFESTRING
   27.32 #include <errno.h>
   27.33 #endif
   27.34 
   27.35 // Wide-char funcs
   27.36 #include <wchar.h>
   27.37 #include <wctype.h>
   27.38 
   27.39 namespace OVR {
   27.40 
   27.41 #if defined(OVR_OS_WIN32)
   27.42 inline char* OVR_CDECL OVR_itoa(int val, char *dest, UPInt destsize, int radix)
   27.43 {
   27.44 #if defined(OVR_MSVC_SAFESTRING)
   27.45     _itoa_s(val, dest, destsize, radix);
   27.46     return dest;
   27.47 #else
   27.48     OVR_UNUSED(destsize);
   27.49     return itoa(val, dest, radix);
   27.50 #endif
   27.51 }
   27.52 #else // OVR_OS_WIN32
   27.53 inline char* OVR_itoa(int val, char* dest, unsigned int len, int radix)
   27.54 {
   27.55     if (val == 0)
   27.56     {
   27.57         if (len > 1)
   27.58         {
   27.59             dest[0] = '0';
   27.60             dest[1] = '\0';  
   27.61         }
   27.62         return dest;
   27.63     }
   27.64 
   27.65     int cur = val;
   27.66     unsigned int i    = 0; 
   27.67     unsigned int sign = 0;
   27.68 
   27.69     if (val < 0)
   27.70     {
   27.71         val = -val;
   27.72         sign = 1;
   27.73     }
   27.74 
   27.75     while ((val != 0) && (i < (len - 1 - sign)))        
   27.76     {
   27.77         cur    = val % radix;
   27.78         val   /= radix;
   27.79 
   27.80         if (radix == 16)
   27.81         {
   27.82             switch(cur)
   27.83             {
   27.84             case 10:
   27.85                 dest[i] = 'a';
   27.86                 break;
   27.87             case 11:
   27.88                 dest[i] = 'b';
   27.89                 break;
   27.90             case 12:
   27.91                 dest[i] = 'c';
   27.92                 break;
   27.93             case 13:
   27.94                 dest[i] = 'd';
   27.95                 break;
   27.96             case 14:
   27.97                 dest[i] = 'e';
   27.98                 break;
   27.99             case 15:
  27.100                 dest[i] = 'f';
  27.101                 break;
  27.102             default:
  27.103                 dest[i] = (char)('0' + cur);
  27.104                 break;
  27.105             }
  27.106         } 
  27.107         else
  27.108         {
  27.109             dest[i] = (char)('0' + cur);
  27.110         }
  27.111         ++i;
  27.112     }
  27.113 
  27.114     if (sign)
  27.115     {
  27.116         dest[i++] = '-';
  27.117     }
  27.118 
  27.119     for (unsigned int j = 0; j < i / 2; ++j)
  27.120     {
  27.121         char tmp        = dest[j];
  27.122         dest[j]         = dest[i - 1 - j];
  27.123         dest[i - 1 - j] = tmp;
  27.124     }
  27.125     dest[i] = '\0';
  27.126 
  27.127     return dest;
  27.128 }
  27.129 
  27.130 #endif
  27.131 
  27.132 
  27.133 // String functions
  27.134 
  27.135 inline UPInt OVR_CDECL OVR_strlen(const char* str)
  27.136 {
  27.137     return strlen(str);
  27.138 }
  27.139 
  27.140 inline char* OVR_CDECL OVR_strcpy(char* dest, UPInt destsize, const char* src)
  27.141 {
  27.142 #if defined(OVR_MSVC_SAFESTRING)
  27.143     strcpy_s(dest, destsize, src);
  27.144     return dest;
  27.145 #else
  27.146     OVR_UNUSED(destsize);
  27.147     return strcpy(dest, src);
  27.148 #endif
  27.149 }
  27.150 
  27.151 inline char* OVR_CDECL OVR_strncpy(char* dest, UPInt destsize, const char* src, UPInt count)
  27.152 {
  27.153 #if defined(OVR_MSVC_SAFESTRING)
  27.154     strncpy_s(dest, destsize, src, count);
  27.155     return dest;
  27.156 #else
  27.157     OVR_UNUSED(destsize);
  27.158     return strncpy(dest, src, count);
  27.159 #endif
  27.160 }
  27.161 
  27.162 inline char * OVR_CDECL OVR_strcat(char* dest, UPInt destsize, const char* src)
  27.163 {
  27.164 #if defined(OVR_MSVC_SAFESTRING)
  27.165     strcat_s(dest, destsize, src);
  27.166     return dest;
  27.167 #else
  27.168     OVR_UNUSED(destsize);
  27.169     return strcat(dest, src);
  27.170 #endif
  27.171 }
  27.172 
  27.173 inline int OVR_CDECL OVR_strcmp(const char* dest, const char* src)
  27.174 {
  27.175     return strcmp(dest, src);
  27.176 }
  27.177 
  27.178 inline const char* OVR_CDECL OVR_strchr(const char* str, char c)
  27.179 {
  27.180     return strchr(str, c);
  27.181 }
  27.182 
  27.183 inline char* OVR_CDECL OVR_strchr(char* str, char c)
  27.184 {
  27.185     return strchr(str, c);
  27.186 }
  27.187 
  27.188 inline const char* OVR_strrchr(const char* str, char c)
  27.189 {
  27.190     UPInt len = OVR_strlen(str);
  27.191     for (UPInt i=len; i>0; i--)     
  27.192         if (str[i]==c) 
  27.193             return str+i;
  27.194     return 0;
  27.195 }
  27.196 
  27.197 inline const UByte* OVR_CDECL OVR_memrchr(const UByte* str, UPInt size, UByte c)
  27.198 {
  27.199     for (SPInt i = (SPInt)size - 1; i >= 0; i--)     
  27.200     {
  27.201         if (str[i] == c) 
  27.202             return str + i;
  27.203     }
  27.204     return 0;
  27.205 }
  27.206 
  27.207 inline char* OVR_CDECL OVR_strrchr(char* str, char c)
  27.208 {
  27.209     UPInt len = OVR_strlen(str);
  27.210     for (UPInt i=len; i>0; i--)     
  27.211         if (str[i]==c) 
  27.212             return str+i;
  27.213     return 0;
  27.214 }
  27.215 
  27.216 
  27.217 double OVR_CDECL OVR_strtod(const char* string, char** tailptr);
  27.218 
  27.219 inline long OVR_CDECL OVR_strtol(const char* string, char** tailptr, int radix)
  27.220 {
  27.221     return strtol(string, tailptr, radix);
  27.222 }
  27.223 
  27.224 inline long OVR_CDECL OVR_strtoul(const char* string, char** tailptr, int radix)
  27.225 {
  27.226     return strtoul(string, tailptr, radix);
  27.227 }
  27.228 
  27.229 inline int OVR_CDECL OVR_strncmp(const char* ws1, const char* ws2, UPInt size)
  27.230 {
  27.231     return strncmp(ws1, ws2, size);
  27.232 }
  27.233 
  27.234 inline UInt64 OVR_CDECL OVR_strtouq(const char *nptr, char **endptr, int base)
  27.235 {
  27.236 #if defined(OVR_CC_MSVC) && !defined(OVR_OS_WINCE)
  27.237     return _strtoui64(nptr, endptr, base);
  27.238 #else
  27.239     return strtoull(nptr, endptr, base);
  27.240 #endif
  27.241 }
  27.242 
  27.243 inline SInt64 OVR_CDECL OVR_strtoq(const char *nptr, char **endptr, int base)
  27.244 {
  27.245 #if defined(OVR_CC_MSVC) && !defined(OVR_OS_WINCE)
  27.246     return _strtoi64(nptr, endptr, base);
  27.247 #else
  27.248     return strtoll(nptr, endptr, base);
  27.249 #endif
  27.250 }
  27.251 
  27.252 
  27.253 inline SInt64 OVR_CDECL OVR_atoq(const char* string)
  27.254 {
  27.255 #if defined(OVR_CC_MSVC) && !defined(OVR_OS_WINCE)
  27.256     return _atoi64(string);
  27.257 #else
  27.258     return atoll(string);
  27.259 #endif
  27.260 }
  27.261 
  27.262 inline UInt64 OVR_CDECL OVR_atouq(const char* string)
  27.263 {
  27.264   return OVR_strtouq(string, NULL, 10);
  27.265 }
  27.266 
  27.267 
  27.268 // Implemented in GStd.cpp in platform-specific manner.
  27.269 int OVR_CDECL OVR_stricmp(const char* dest, const char* src);
  27.270 int OVR_CDECL OVR_strnicmp(const char* dest, const char* src, UPInt count);
  27.271 
  27.272 inline UPInt OVR_CDECL OVR_sprintf(char *dest, UPInt destsize, const char* format, ...)
  27.273 {
  27.274     va_list argList;
  27.275     va_start(argList,format);
  27.276     UPInt ret;
  27.277 #if defined(OVR_CC_MSVC)
  27.278     #if defined(OVR_MSVC_SAFESTRING)
  27.279         ret = _vsnprintf_s(dest, destsize, _TRUNCATE, format, argList);
  27.280         OVR_ASSERT(ret != -1);
  27.281     #else
  27.282         OVR_UNUSED(destsize);
  27.283         ret = _vsnprintf(dest, destsize - 1, format, argList); // -1 for space for the null character
  27.284         OVR_ASSERT(ret != -1);
  27.285         dest[destsize-1] = 0;
  27.286     #endif
  27.287 #else
  27.288     OVR_UNUSED(destsize);
  27.289     ret = vsprintf(dest, format, argList);
  27.290     OVR_ASSERT(ret < destsize);
  27.291 #endif
  27.292     va_end(argList);
  27.293     return ret;
  27.294 }
  27.295 
  27.296 inline UPInt OVR_CDECL OVR_vsprintf(char *dest, UPInt destsize, const char * format, va_list argList)
  27.297 {
  27.298     UPInt ret;
  27.299 #if defined(OVR_CC_MSVC)
  27.300     #if defined(OVR_MSVC_SAFESTRING)
  27.301         dest[0] = '\0';
  27.302         int rv = vsnprintf_s(dest, destsize, _TRUNCATE, format, argList);
  27.303         if (rv == -1)
  27.304         {
  27.305             dest[destsize - 1] = '\0';
  27.306             ret = destsize - 1;
  27.307         }
  27.308         else
  27.309             ret = (UPInt)rv;
  27.310     #else
  27.311         OVR_UNUSED(destsize);
  27.312         int rv = _vsnprintf(dest, destsize - 1, format, argList);
  27.313         OVR_ASSERT(rv != -1);
  27.314         ret = (UPInt)rv;
  27.315         dest[destsize-1] = 0;
  27.316     #endif
  27.317 #else
  27.318     OVR_UNUSED(destsize);
  27.319     ret = (UPInt)vsprintf(dest, format, argList);
  27.320     OVR_ASSERT(ret < destsize);
  27.321 #endif
  27.322     return ret;
  27.323 }
  27.324 
  27.325 // Returns the number of characters in the formatted string.
  27.326 inline UPInt OVR_CDECL OVR_vscprintf(const char * format, va_list argList)
  27.327 {
  27.328     UPInt ret;
  27.329 #if defined(OVR_CC_MSVC)
  27.330     ret = (UPInt) _vscprintf(format, argList);
  27.331 #else    
  27.332     ret = (UPInt) vsnprintf(NULL, 0, format, argList);
  27.333 #endif
  27.334     return ret;       
  27.335 }
  27.336 
  27.337 
  27.338 wchar_t* OVR_CDECL OVR_wcscpy(wchar_t* dest, UPInt destsize, const wchar_t* src);
  27.339 wchar_t* OVR_CDECL OVR_wcsncpy(wchar_t* dest, UPInt destsize, const wchar_t* src, UPInt count);
  27.340 wchar_t* OVR_CDECL OVR_wcscat(wchar_t* dest, UPInt destsize, const wchar_t* src);
  27.341 UPInt    OVR_CDECL OVR_wcslen(const wchar_t* str);
  27.342 int      OVR_CDECL OVR_wcscmp(const wchar_t* a, const wchar_t* b);
  27.343 int      OVR_CDECL OVR_wcsicmp(const wchar_t* a, const wchar_t* b);
  27.344 
  27.345 inline int OVR_CDECL OVR_wcsicoll(const wchar_t* a, const wchar_t* b)
  27.346 {
  27.347 #if defined(OVR_OS_WIN32)
  27.348 #if defined(OVR_CC_MSVC) && (OVR_CC_MSVC >= 1400)
  27.349     return ::_wcsicoll(a, b);
  27.350 #else
  27.351     return ::wcsicoll(a, b);
  27.352 #endif
  27.353 #else
  27.354     // not supported, use regular wcsicmp
  27.355     return OVR_wcsicmp(a, b);
  27.356 #endif
  27.357 }
  27.358 
  27.359 inline int OVR_CDECL OVR_wcscoll(const wchar_t* a, const wchar_t* b)
  27.360 {
  27.361 #if defined(OVR_OS_WIN32) || defined(OVR_OS_LINUX)
  27.362     return wcscoll(a, b);
  27.363 #else
  27.364     // not supported, use regular wcscmp
  27.365     return OVR_wcscmp(a, b);
  27.366 #endif
  27.367 }
  27.368 
  27.369 #ifndef OVR_NO_WCTYPE
  27.370 
  27.371 inline int OVR_CDECL UnicodeCharIs(const UInt16* table, wchar_t charCode)
  27.372 {
  27.373     unsigned offset = table[charCode >> 8];
  27.374     if (offset == 0) return 0;
  27.375     if (offset == 1) return 1;
  27.376     return (table[offset + ((charCode >> 4) & 15)] & (1 << (charCode & 15))) != 0;
  27.377 }
  27.378 
  27.379 extern const UInt16 UnicodeAlnumBits[];
  27.380 extern const UInt16 UnicodeAlphaBits[];
  27.381 extern const UInt16 UnicodeDigitBits[];
  27.382 extern const UInt16 UnicodeSpaceBits[];
  27.383 extern const UInt16 UnicodeXDigitBits[];
  27.384 
  27.385 // Uncomment if necessary
  27.386 //extern const UInt16 UnicodeCntrlBits[];
  27.387 //extern const UInt16 UnicodeGraphBits[];
  27.388 //extern const UInt16 UnicodeLowerBits[];
  27.389 //extern const UInt16 UnicodePrintBits[];
  27.390 //extern const UInt16 UnicodePunctBits[];
  27.391 //extern const UInt16 UnicodeUpperBits[];
  27.392 
  27.393 inline int OVR_CDECL OVR_iswalnum (wchar_t charCode) { return UnicodeCharIs(UnicodeAlnumBits,  charCode); }
  27.394 inline int OVR_CDECL OVR_iswalpha (wchar_t charCode) { return UnicodeCharIs(UnicodeAlphaBits,  charCode); }
  27.395 inline int OVR_CDECL OVR_iswdigit (wchar_t charCode) { return UnicodeCharIs(UnicodeDigitBits,  charCode); }
  27.396 inline int OVR_CDECL OVR_iswspace (wchar_t charCode) { return UnicodeCharIs(UnicodeSpaceBits,  charCode); }
  27.397 inline int OVR_CDECL OVR_iswxdigit(wchar_t charCode) { return UnicodeCharIs(UnicodeXDigitBits, charCode); }
  27.398 
  27.399 // Uncomment if necessary
  27.400 //inline int OVR_CDECL OVR_iswcntrl (wchar_t charCode) { return UnicodeCharIs(UnicodeCntrlBits,  charCode); }
  27.401 //inline int OVR_CDECL OVR_iswgraph (wchar_t charCode) { return UnicodeCharIs(UnicodeGraphBits,  charCode); }
  27.402 //inline int OVR_CDECL OVR_iswlower (wchar_t charCode) { return UnicodeCharIs(UnicodeLowerBits,  charCode); }
  27.403 //inline int OVR_CDECL OVR_iswprint (wchar_t charCode) { return UnicodeCharIs(UnicodePrintBits,  charCode); }
  27.404 //inline int OVR_CDECL OVR_iswpunct (wchar_t charCode) { return UnicodeCharIs(UnicodePunctBits,  charCode); }
  27.405 //inline int OVR_CDECL OVR_iswupper (wchar_t charCode) { return UnicodeCharIs(UnicodeUpperBits,  charCode); }
  27.406 
  27.407 int OVR_CDECL OVR_towupper(wchar_t charCode);
  27.408 int OVR_CDECL OVR_towlower(wchar_t charCode);
  27.409 
  27.410 #else // OVR_NO_WCTYPE
  27.411 
  27.412 inline int OVR_CDECL OVR_iswspace(wchar_t c)
  27.413 {
  27.414     return iswspace(c);
  27.415 }
  27.416 
  27.417 inline int OVR_CDECL OVR_iswdigit(wchar_t c)
  27.418 {
  27.419     return iswdigit(c);
  27.420 }
  27.421 
  27.422 inline int OVR_CDECL OVR_iswxdigit(wchar_t c)
  27.423 {
  27.424     return iswxdigit(c);
  27.425 }
  27.426 
  27.427 inline int OVR_CDECL OVR_iswalpha(wchar_t c)
  27.428 {
  27.429     return iswalpha(c);
  27.430 }
  27.431 
  27.432 inline int OVR_CDECL OVR_iswalnum(wchar_t c)
  27.433 {
  27.434     return iswalnum(c);
  27.435 }
  27.436 
  27.437 inline wchar_t OVR_CDECL OVR_towlower(wchar_t c)
  27.438 {
  27.439     return (wchar_t)towlower(c);
  27.440 }
  27.441 
  27.442 inline wchar_t OVR_towupper(wchar_t c)
  27.443 {
  27.444     return (wchar_t)towupper(c);
  27.445 }
  27.446 
  27.447 #endif // OVR_NO_WCTYPE
  27.448 
  27.449 // ASCII versions of tolower and toupper. Don't use "char"
  27.450 inline int OVR_CDECL OVR_tolower(int c)
  27.451 {
  27.452     return (c >= 'A' && c <= 'Z') ? c - 'A' + 'a' : c;
  27.453 }
  27.454 
  27.455 inline int OVR_CDECL OVR_toupper(int c)
  27.456 {
  27.457     return (c >= 'a' && c <= 'z') ? c - 'a' + 'A' : c;
  27.458 }
  27.459 
  27.460 
  27.461 
  27.462 inline double OVR_CDECL OVR_wcstod(const wchar_t* string, wchar_t** tailptr)
  27.463 {
  27.464 #if defined(OVR_OS_OTHER)
  27.465     OVR_UNUSED(tailptr);
  27.466     char buffer[64];
  27.467     char* tp = NULL;
  27.468     UPInt max = OVR_wcslen(string);
  27.469     if (max > 63) max = 63;
  27.470     unsigned char c = 0;
  27.471     for (UPInt i=0; i < max; i++)
  27.472     {
  27.473         c = (unsigned char)string[i];
  27.474         buffer[i] = ((c) < 128 ? (char)c : '!');
  27.475     }
  27.476     buffer[max] = 0;
  27.477     return OVR_strtod(buffer, &tp);
  27.478 #else
  27.479     return wcstod(string, tailptr);
  27.480 #endif
  27.481 }
  27.482 
  27.483 inline long OVR_CDECL OVR_wcstol(const wchar_t* string, wchar_t** tailptr, int radix)
  27.484 {
  27.485 #if defined(OVR_OS_OTHER)
  27.486     OVR_UNUSED(tailptr);
  27.487     char buffer[64];
  27.488     char* tp = NULL;
  27.489     UPInt max = OVR_wcslen(string);
  27.490     if (max > 63) max = 63;
  27.491     unsigned char c = 0;
  27.492     for (UPInt i=0; i < max; i++)
  27.493     {
  27.494         c = (unsigned char)string[i];
  27.495         buffer[i] = ((c) < 128 ? (char)c : '!');
  27.496     }
  27.497     buffer[max] = 0;
  27.498     return strtol(buffer, &tp, radix);
  27.499 #else
  27.500     return wcstol(string, tailptr, radix);
  27.501 #endif
  27.502 }
  27.503 
  27.504 } // OVR
  27.505 
  27.506 #endif // OVR_Std_h
  27.507 \ No newline at end of file
    28.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    28.2 +++ b/libovr/Src/Kernel/OVR_String.cpp	Sat Sep 14 16:14:59 2013 +0300
    28.3 @@ -0,0 +1,1 @@
    28.4 +/************************************************************************************
    28.5 
    28.6 Filename    :   OVR_String.cpp
    28.7 Content     :   String UTF8 string implementation with copy-on-write semantics
    28.8                 (thread-safe for assignment but not modification).
    28.9 Created     :   September 19, 2012
   28.10 Notes       : 
   28.11 
   28.12 Copyright   :   Copyright 2012 Oculus VR, Inc. All Rights reserved.
   28.13 
   28.14 Use of this software is subject to the terms of the Oculus license
   28.15 agreement provided at the time of installation or download, or which
   28.16 otherwise accompanies this software in either electronic or hard copy form.
   28.17 
   28.18 ************************************************************************************/
   28.19 
   28.20 #include "OVR_String.h"
   28.21 
   28.22 #include <stdlib.h>
   28.23 #include <ctype.h>
   28.24 
   28.25 #ifdef OVR_OS_QNX
   28.26 # include <strings.h>
   28.27 #endif
   28.28 
   28.29 namespace OVR {
   28.30 
   28.31 #define String_LengthIsSize (UPInt(1) << String::Flag_LengthIsSizeShift)
   28.32 
   28.33 String::DataDesc String::NullData = {String_LengthIsSize, 1, {0} };
   28.34 
   28.35 
   28.36 String::String()
   28.37 {
   28.38     pData = &NullData;
   28.39     pData->AddRef();
   28.40 };
   28.41 
   28.42 String::String(const char* pdata)
   28.43 {
   28.44     // Obtain length in bytes; it doesn't matter if _data is UTF8.
   28.45     UPInt size = pdata ? OVR_strlen(pdata) : 0; 
   28.46     pData = AllocDataCopy1(size, 0, pdata, size);
   28.47 };
   28.48 
   28.49 String::String(const char* pdata1, const char* pdata2, const char* pdata3)
   28.50 {
   28.51     // Obtain length in bytes; it doesn't matter if _data is UTF8.
   28.52     UPInt size1 = pdata1 ? OVR_strlen(pdata1) : 0; 
   28.53     UPInt size2 = pdata2 ? OVR_strlen(pdata2) : 0; 
   28.54     UPInt size3 = pdata3 ? OVR_strlen(pdata3) : 0; 
   28.55 
   28.56     DataDesc *pdataDesc = AllocDataCopy2(size1 + size2 + size3, 0,
   28.57                                          pdata1, size1, pdata2, size2);
   28.58     memcpy(pdataDesc->Data + size1 + size2, pdata3, size3);   
   28.59     pData = pdataDesc;    
   28.60 }
   28.61 
   28.62 String::String(const char* pdata, UPInt size)
   28.63 {
   28.64     OVR_ASSERT((size == 0) || (pdata != 0));
   28.65     pData = AllocDataCopy1(size, 0, pdata, size);
   28.66 };
   28.67 
   28.68 
   28.69 String::String(const InitStruct& src, UPInt size)
   28.70 {
   28.71     pData = AllocData(size, 0);
   28.72     src.InitString(GetData()->Data, size);
   28.73 }
   28.74 
   28.75 String::String(const String& src)
   28.76 {    
   28.77     pData = src.GetData();
   28.78     pData->AddRef();
   28.79 }
   28.80 
   28.81 String::String(const StringBuffer& src)
   28.82 {
   28.83     pData = AllocDataCopy1(src.GetSize(), 0, src.ToCStr(), src.GetSize());
   28.84 }
   28.85 
   28.86 String::String(const wchar_t* data)
   28.87 {
   28.88     pData = &NullData;
   28.89     pData->AddRef();
   28.90     // Simplified logic for wchar_t constructor.
   28.91     if (data)    
   28.92         *this = data;    
   28.93 }
   28.94 
   28.95 
   28.96 String::DataDesc* String::AllocData(UPInt size, UPInt lengthIsSize)
   28.97 {
   28.98     String::DataDesc* pdesc;
   28.99 
  28.100     if (size == 0)
  28.101     {
  28.102         pdesc = &NullData;
  28.103         pdesc->AddRef();
  28.104         return pdesc;
  28.105     }
  28.106 
  28.107     pdesc = (DataDesc*)OVR_ALLOC(sizeof(DataDesc)+ size);
  28.108     pdesc->Data[size] = 0;
  28.109     pdesc->RefCount = 1;
  28.110     pdesc->Size     = size | lengthIsSize;  
  28.111     return pdesc;
  28.112 }
  28.113 
  28.114 
  28.115 String::DataDesc* String::AllocDataCopy1(UPInt size, UPInt lengthIsSize,
  28.116                                          const char* pdata, UPInt copySize)
  28.117 {
  28.118     String::DataDesc* pdesc = AllocData(size, lengthIsSize);
  28.119     memcpy(pdesc->Data, pdata, copySize);
  28.120     return pdesc;
  28.121 }
  28.122 
  28.123 String::DataDesc* String::AllocDataCopy2(UPInt size, UPInt lengthIsSize,
  28.124                                          const char* pdata1, UPInt copySize1,
  28.125                                          const char* pdata2, UPInt copySize2)
  28.126 {
  28.127     String::DataDesc* pdesc = AllocData(size, lengthIsSize);
  28.128     memcpy(pdesc->Data, pdata1, copySize1);
  28.129     memcpy(pdesc->Data + copySize1, pdata2, copySize2);
  28.130     return pdesc;
  28.131 }
  28.132 
  28.133 
  28.134 UPInt String::GetLength() const 
  28.135 {
  28.136     // Optimize length accesses for non-UTF8 character strings. 
  28.137     DataDesc* pdata = GetData();
  28.138     UPInt     length, size = pdata->GetSize();
  28.139     
  28.140     if (pdata->LengthIsSize())
  28.141         return size;    
  28.142     
  28.143     length = (UPInt)UTF8Util::GetLength(pdata->Data, (UPInt)size);
  28.144     
  28.145     if (length == size)
  28.146         pdata->Size |= String_LengthIsSize;
  28.147     
  28.148     return length;
  28.149 }
  28.150 
  28.151 
  28.152 //static UInt32 String_CharSearch(const char* buf, )
  28.153 
  28.154 
  28.155 UInt32 String::GetCharAt(UPInt index) const 
  28.156 {  
  28.157     SPInt       i = (SPInt) index;
  28.158     DataDesc*   pdata = GetData();
  28.159     const char* buf = pdata->Data;
  28.160     UInt32      c;
  28.161     
  28.162     if (pdata->LengthIsSize())
  28.163     {
  28.164         OVR_ASSERT(index < pdata->GetSize());
  28.165         buf += i;
  28.166         return UTF8Util::DecodeNextChar_Advance0(&buf);
  28.167     }
  28.168 
  28.169     c = UTF8Util::GetCharAt(index, buf, pdata->GetSize());
  28.170     return c;
  28.171 }
  28.172 
  28.173 UInt32 String::GetFirstCharAt(UPInt index, const char** offset) const
  28.174 {
  28.175     DataDesc*   pdata = GetData();
  28.176     SPInt       i = (SPInt) index;
  28.177     const char* buf = pdata->Data;
  28.178     const char* end = buf + pdata->GetSize();
  28.179     UInt32      c;
  28.180 
  28.181     do 
  28.182     {
  28.183         c = UTF8Util::DecodeNextChar_Advance0(&buf);
  28.184         i--;
  28.185 
  28.186         if (buf >= end)
  28.187         {
  28.188             // We've hit the end of the string; don't go further.
  28.189             OVR_ASSERT(i == 0);
  28.190             return c;
  28.191         }
  28.192     } while (i >= 0);
  28.193 
  28.194     *offset = buf;
  28.195 
  28.196     return c;
  28.197 }
  28.198 
  28.199 UInt32 String::GetNextChar(const char** offset) const
  28.200 {
  28.201     return UTF8Util::DecodeNextChar(offset);
  28.202 }
  28.203 
  28.204 
  28.205 
  28.206 void String::AppendChar(UInt32 ch)
  28.207 {
  28.208     DataDesc*   pdata = GetData();
  28.209     UPInt       size = pdata->GetSize();
  28.210     char        buff[8];
  28.211     SPInt       encodeSize = 0;
  28.212 
  28.213     // Converts ch into UTF8 string and fills it into buff.   
  28.214     UTF8Util::EncodeChar(buff, &encodeSize, ch);
  28.215     OVR_ASSERT(encodeSize >= 0);
  28.216 
  28.217     SetData(AllocDataCopy2(size + (UPInt)encodeSize, 0,
  28.218                            pdata->Data, size, buff, (UPInt)encodeSize));
  28.219     pdata->Release();
  28.220 }
  28.221 
  28.222 
  28.223 void String::AppendString(const wchar_t* pstr, SPInt len)
  28.224 {
  28.225     if (!pstr)
  28.226         return;
  28.227 
  28.228     DataDesc*   pdata = GetData();
  28.229     UPInt       oldSize = pdata->GetSize();    
  28.230     UPInt       encodeSize = (UPInt)UTF8Util::GetEncodeStringSize(pstr, len);
  28.231 
  28.232     DataDesc*   pnewData = AllocDataCopy1(oldSize + (UPInt)encodeSize, 0,
  28.233                                           pdata->Data, oldSize);
  28.234     UTF8Util::EncodeString(pnewData->Data + oldSize,  pstr, len);
  28.235 
  28.236     SetData(pnewData);
  28.237     pdata->Release();
  28.238 }
  28.239 
  28.240 
  28.241 void String::AppendString(const char* putf8str, SPInt utf8StrSz)
  28.242 {
  28.243     if (!putf8str || !utf8StrSz)
  28.244         return;
  28.245     if (utf8StrSz == -1)
  28.246         utf8StrSz = (SPInt)OVR_strlen(putf8str);
  28.247 
  28.248     DataDesc*   pdata = GetData();
  28.249     UPInt       oldSize = pdata->GetSize();
  28.250 
  28.251     SetData(AllocDataCopy2(oldSize + (UPInt)utf8StrSz, 0,
  28.252                            pdata->Data, oldSize, putf8str, (UPInt)utf8StrSz));
  28.253     pdata->Release();
  28.254 }
  28.255 
  28.256 void    String::AssignString(const InitStruct& src, UPInt size)
  28.257 {
  28.258     DataDesc*   poldData = GetData();
  28.259     DataDesc*   pnewData = AllocData(size, 0);
  28.260     src.InitString(pnewData->Data, size);
  28.261     SetData(pnewData);
  28.262     poldData->Release();
  28.263 }
  28.264 
  28.265 void    String::AssignString(const char* putf8str, UPInt size)
  28.266 {
  28.267     DataDesc* poldData = GetData();
  28.268     SetData(AllocDataCopy1(size, 0, putf8str, size));
  28.269     poldData->Release();
  28.270 }
  28.271 
  28.272 void    String::operator = (const char* pstr)
  28.273 {
  28.274     AssignString(pstr, pstr ? OVR_strlen(pstr) : 0);
  28.275 }
  28.276 
  28.277 void    String::operator = (const wchar_t* pwstr)
  28.278 {
  28.279     DataDesc*   poldData = GetData();
  28.280     UPInt       size = pwstr ? (UPInt)UTF8Util::GetEncodeStringSize(pwstr) : 0;
  28.281 
  28.282     DataDesc*   pnewData = AllocData(size, 0);
  28.283     UTF8Util::EncodeString(pnewData->Data, pwstr);
  28.284     SetData(pnewData);
  28.285     poldData->Release();
  28.286 }
  28.287 
  28.288 
  28.289 void    String::operator = (const String& src)
  28.290 {     
  28.291     DataDesc*    psdata = src.GetData();
  28.292     DataDesc*    pdata = GetData();    
  28.293 
  28.294     SetData(psdata);
  28.295     psdata->AddRef();
  28.296     pdata->Release();
  28.297 }
  28.298 
  28.299 
  28.300 void    String::operator = (const StringBuffer& src)
  28.301 { 
  28.302     DataDesc* polddata = GetData();    
  28.303     SetData(AllocDataCopy1(src.GetSize(), 0, src.ToCStr(), src.GetSize()));
  28.304     polddata->Release();
  28.305 }
  28.306 
  28.307 void    String::operator += (const String& src)
  28.308 {
  28.309     DataDesc   *pourData = GetData(),
  28.310                *psrcData = src.GetData();
  28.311     UPInt       ourSize  = pourData->GetSize(),
  28.312                 srcSize  = psrcData->GetSize();
  28.313     UPInt       lflag    = pourData->GetLengthFlag() & psrcData->GetLengthFlag();
  28.314 
  28.315     SetData(AllocDataCopy2(ourSize + srcSize, lflag,
  28.316                            pourData->Data, ourSize, psrcData->Data, srcSize));
  28.317     pourData->Release();
  28.318 }
  28.319 
  28.320 
  28.321 String   String::operator + (const char* str) const
  28.322 {   
  28.323     String tmp1(*this);
  28.324     tmp1 += (str ? str : "");
  28.325     return tmp1;
  28.326 }
  28.327 
  28.328 String   String::operator + (const String& src) const
  28.329 { 
  28.330     String tmp1(*this);
  28.331     tmp1 += src;
  28.332     return tmp1;
  28.333 }
  28.334 
  28.335 void    String::Remove(UPInt posAt, SPInt removeLength)
  28.336 {
  28.337     DataDesc*   pdata = GetData();
  28.338     UPInt       oldSize = pdata->GetSize();    
  28.339     // Length indicates the number of characters to remove. 
  28.340     UPInt       length = GetLength();
  28.341 
  28.342     // If index is past the string, nothing to remove.
  28.343     if (posAt >= length)
  28.344         return;
  28.345     // Otherwise, cap removeLength to the length of the string.
  28.346     if ((posAt + removeLength) > length)
  28.347         removeLength = length - posAt;
  28.348 
  28.349     // Get the byte position of the UTF8 char at position posAt.
  28.350     SPInt bytePos    = UTF8Util::GetByteIndex(posAt, pdata->Data, oldSize);
  28.351     SPInt removeSize = UTF8Util::GetByteIndex(removeLength, pdata->Data + bytePos, oldSize-bytePos);
  28.352 
  28.353     SetData(AllocDataCopy2(oldSize - removeSize, pdata->GetLengthFlag(),
  28.354                            pdata->Data, bytePos,
  28.355                            pData->Data + bytePos + removeSize, (oldSize - bytePos - removeSize)));
  28.356     pdata->Release();
  28.357 }
  28.358 
  28.359 
  28.360 String   String::Substring(UPInt start, UPInt end) const
  28.361 {
  28.362     UPInt length = GetLength();
  28.363     if ((start >= length) || (start >= end))
  28.364         return String();   
  28.365 
  28.366     DataDesc* pdata = GetData();
  28.367     
  28.368     // If size matches, we know the exact index range.
  28.369     if (pdata->LengthIsSize())
  28.370         return String(pdata->Data + start, end - start);
  28.371     
  28.372     // Get position of starting character.
  28.373     SPInt byteStart = UTF8Util::GetByteIndex(start, pdata->Data, pdata->GetSize());
  28.374     SPInt byteSize  = UTF8Util::GetByteIndex(end - start, pdata->Data + byteStart, pdata->GetSize()-byteStart);
  28.375     return String(pdata->Data + byteStart, (UPInt)byteSize);
  28.376 }
  28.377 
  28.378 void String::Clear()
  28.379 {   
  28.380     NullData.AddRef();
  28.381     GetData()->Release();
  28.382     SetData(&NullData);
  28.383 }
  28.384 
  28.385 
  28.386 String   String::ToUpper() const 
  28.387 {       
  28.388     UInt32      c;
  28.389     const char* psource = GetData()->Data;
  28.390     const char* pend = psource + GetData()->GetSize();
  28.391     String      str;
  28.392     SPInt       bufferOffset = 0;
  28.393     char        buffer[512];
  28.394     
  28.395     while(psource < pend)
  28.396     {
  28.397         do {            
  28.398             c = UTF8Util::DecodeNextChar_Advance0(&psource);
  28.399             UTF8Util::EncodeChar(buffer, &bufferOffset, OVR_towupper(wchar_t(c)));
  28.400         } while ((psource < pend) && (bufferOffset < SPInt(sizeof(buffer)-8)));
  28.401 
  28.402         // Append string a piece at a time.
  28.403         str.AppendString(buffer, bufferOffset);
  28.404         bufferOffset = 0;
  28.405     }
  28.406 
  28.407     return str;
  28.408 }
  28.409 
  28.410 String   String::ToLower() const 
  28.411 {
  28.412     UInt32      c;
  28.413     const char* psource = GetData()->Data;
  28.414     const char* pend = psource + GetData()->GetSize();
  28.415     String      str;
  28.416     SPInt       bufferOffset = 0;
  28.417     char        buffer[512];
  28.418 
  28.419     while(psource < pend)
  28.420     {
  28.421         do {
  28.422             c = UTF8Util::DecodeNextChar_Advance0(&psource);
  28.423             UTF8Util::EncodeChar(buffer, &bufferOffset, OVR_towlower(wchar_t(c)));
  28.424         } while ((psource < pend) && (bufferOffset < SPInt(sizeof(buffer)-8)));
  28.425 
  28.426         // Append string a piece at a time.
  28.427         str.AppendString(buffer, bufferOffset);
  28.428         bufferOffset = 0;
  28.429     }
  28.430 
  28.431     return str;
  28.432 }
  28.433 
  28.434 
  28.435 
  28.436 String& String::Insert(const char* substr, UPInt posAt, SPInt strSize)
  28.437 {
  28.438     DataDesc* poldData   = GetData();
  28.439     UPInt     oldSize    = poldData->GetSize();
  28.440     UPInt     insertSize = (strSize < 0) ? OVR_strlen(substr) : (UPInt)strSize;    
  28.441     UPInt     byteIndex  =  (poldData->LengthIsSize()) ?
  28.442                             posAt : (UPInt)UTF8Util::GetByteIndex(posAt, poldData->Data, oldSize);
  28.443 
  28.444     OVR_ASSERT(byteIndex <= oldSize);
  28.445     
  28.446     DataDesc* pnewData = AllocDataCopy2(oldSize + insertSize, 0,
  28.447                                         poldData->Data, byteIndex, substr, insertSize);
  28.448     memcpy(pnewData->Data + byteIndex + insertSize,
  28.449            poldData->Data + byteIndex, oldSize - byteIndex);
  28.450     SetData(pnewData);
  28.451     poldData->Release();
  28.452     return *this;
  28.453 }
  28.454 
  28.455 /*
  28.456 String& String::Insert(const UInt32* substr, UPInt posAt, SPInt len)
  28.457 {
  28.458     for (SPInt i = 0; i < len; ++i)
  28.459     {
  28.460         UPInt charw = InsertCharAt(substr[i], posAt);
  28.461         posAt += charw;
  28.462     }
  28.463     return *this;
  28.464 }
  28.465 */
  28.466 
  28.467 UPInt String::InsertCharAt(UInt32 c, UPInt posAt)
  28.468 {
  28.469     char    buf[8];
  28.470     SPInt   index = 0;
  28.471     UTF8Util::EncodeChar(buf, &index, c);
  28.472     OVR_ASSERT(index >= 0);
  28.473     buf[(UPInt)index] = 0;
  28.474 
  28.475     Insert(buf, posAt, index);
  28.476     return (UPInt)index;
  28.477 }
  28.478 
  28.479 
  28.480 int String::CompareNoCase(const char* a, const char* b)
  28.481 {
  28.482     return OVR_stricmp(a, b);
  28.483 }
  28.484 
  28.485 int String::CompareNoCase(const char* a, const char* b, SPInt len)
  28.486 {
  28.487     if (len)
  28.488     {
  28.489         SPInt f,l;
  28.490         SPInt slen = len;
  28.491         const char *s = b;
  28.492         do {
  28.493             f = (SPInt)OVR_tolower((int)(*(a++)));
  28.494             l = (SPInt)OVR_tolower((int)(*(b++)));
  28.495         } while (--len && f && (f == l) && *b != 0);
  28.496 
  28.497         if (f == l && (len != 0 || *b != 0))
  28.498         {
  28.499             f = (SPInt)slen;
  28.500             l = (SPInt)OVR_strlen(s);
  28.501             return int(f - l);
  28.502         }
  28.503 
  28.504         return int(f - l);
  28.505     }
  28.506     else
  28.507         return (0-(int)OVR_strlen(b));
  28.508 }
  28.509 
  28.510 // ***** Implement hash static functions
  28.511 
  28.512 // Hash function
  28.513 UPInt String::BernsteinHashFunction(const void* pdataIn, UPInt size, UPInt seed)
  28.514 {
  28.515     const UByte*    pdata   = (const UByte*) pdataIn;
  28.516     UPInt           h       = seed;
  28.517     while (size > 0)
  28.518     {
  28.519         size--;
  28.520         h = ((h << 5) + h) ^ (unsigned) pdata[size];
  28.521     }
  28.522 
  28.523     return h;
  28.524 }
  28.525 
  28.526 // Hash function, case-insensitive
  28.527 UPInt String::BernsteinHashFunctionCIS(const void* pdataIn, UPInt size, UPInt seed)
  28.528 {
  28.529     const UByte*    pdata = (const UByte*) pdataIn;
  28.530     UPInt           h = seed;
  28.531     while (size > 0)
  28.532     {
  28.533         size--;
  28.534         h = ((h << 5) + h) ^ OVR_tolower(pdata[size]);
  28.535     }
  28.536 
  28.537     // Alternative: "sdbm" hash function, suggested at same web page above.
  28.538     // h = 0;
  28.539     // for bytes { h = (h << 16) + (h << 6) - hash + *p; }
  28.540     return h;
  28.541 }
  28.542 
  28.543 
  28.544 
  28.545 // ***** String Buffer used for Building Strings
  28.546 
  28.547 
  28.548 #define OVR_SBUFF_DEFAULT_GROW_SIZE 512
  28.549 // Constructors / Destructor.
  28.550 StringBuffer::StringBuffer()
  28.551     : pData(NULL), Size(0), BufferSize(0), GrowSize(OVR_SBUFF_DEFAULT_GROW_SIZE), LengthIsSize(false)
  28.552 {
  28.553 }
  28.554 
  28.555 StringBuffer::StringBuffer(UPInt growSize)
  28.556     : pData(NULL), Size(0), BufferSize(0), GrowSize(OVR_SBUFF_DEFAULT_GROW_SIZE), LengthIsSize(false)
  28.557 {
  28.558     SetGrowSize(growSize);
  28.559 }
  28.560 
  28.561 StringBuffer::StringBuffer(const char* data)
  28.562     : pData(NULL), Size(0), BufferSize(0), GrowSize(OVR_SBUFF_DEFAULT_GROW_SIZE), LengthIsSize(false)
  28.563 {
  28.564     *this = data;
  28.565 }
  28.566 
  28.567 StringBuffer::StringBuffer(const char* data, UPInt dataSize)
  28.568     : pData(NULL), Size(0), BufferSize(0), GrowSize(OVR_SBUFF_DEFAULT_GROW_SIZE), LengthIsSize(false)
  28.569 {
  28.570     AppendString(data, dataSize);
  28.571 }
  28.572 
  28.573 StringBuffer::StringBuffer(const String& src)
  28.574     : pData(NULL), Size(0), BufferSize(0), GrowSize(OVR_SBUFF_DEFAULT_GROW_SIZE), LengthIsSize(false)
  28.575 {
  28.576     AppendString(src.ToCStr(), src.GetSize());
  28.577 }
  28.578 
  28.579 StringBuffer::StringBuffer(const StringBuffer& src)
  28.580     : pData(NULL), Size(0), BufferSize(src.GetGrowSize()), GrowSize(OVR_SBUFF_DEFAULT_GROW_SIZE), LengthIsSize(false)
  28.581 {
  28.582     AppendString(src.ToCStr(), src.GetSize());
  28.583     LengthIsSize = src.LengthIsSize;
  28.584 }
  28.585 
  28.586 StringBuffer::StringBuffer(const wchar_t* data)
  28.587     : pData(NULL), Size(0), BufferSize(0), GrowSize(OVR_SBUFF_DEFAULT_GROW_SIZE), LengthIsSize(false)
  28.588 {
  28.589     *this = data;
  28.590 }
  28.591 
  28.592 StringBuffer::~StringBuffer()
  28.593 {
  28.594     if (pData)
  28.595         OVR_FREE(pData);
  28.596 }
  28.597 void StringBuffer::SetGrowSize(UPInt growSize) 
  28.598 { 
  28.599     if (growSize <= 16)
  28.600         GrowSize = 16;
  28.601     else
  28.602     {
  28.603         UByte bits = Alg::UpperBit(UInt32(growSize-1));
  28.604         UPInt size = 1<<bits;
  28.605         GrowSize = size == growSize ? growSize : size;
  28.606     }
  28.607 }
  28.608 
  28.609 UPInt StringBuffer::GetLength() const
  28.610 {
  28.611     UPInt length, size = GetSize();
  28.612     if (LengthIsSize)
  28.613         return size;
  28.614 
  28.615     length = (UPInt)UTF8Util::GetLength(pData, (UPInt)GetSize());
  28.616 
  28.617     if (length == GetSize())
  28.618         LengthIsSize = true;
  28.619     return length;
  28.620 }
  28.621 
  28.622 void    StringBuffer::Reserve(UPInt _size)
  28.623 {
  28.624     if (_size >= BufferSize) // >= because of trailing zero! (!AB)
  28.625     {
  28.626         BufferSize = (_size + 1 + GrowSize - 1)& ~(GrowSize-1);
  28.627         if (!pData)
  28.628             pData = (char*)OVR_ALLOC(BufferSize);
  28.629         else 
  28.630             pData = (char*)OVR_REALLOC(pData, BufferSize);
  28.631     }
  28.632 }
  28.633 void    StringBuffer::Resize(UPInt _size)
  28.634 {
  28.635     Reserve(_size);
  28.636     LengthIsSize = false;
  28.637     Size = _size;
  28.638     if (pData)
  28.639         pData[Size] = 0;
  28.640 }
  28.641 
  28.642 void StringBuffer::Clear()
  28.643 {
  28.644     Resize(0);
  28.645     /*
  28.646     if (pData != pEmptyNullData)
  28.647     {
  28.648         OVR_FREE(pHeap, pData);
  28.649         pData = pEmptyNullData;
  28.650         Size = BufferSize = 0;
  28.651         LengthIsSize = false;
  28.652     }
  28.653     */
  28.654 }
  28.655 // Appends a character
  28.656 void     StringBuffer::AppendChar(UInt32 ch)
  28.657 {
  28.658     char    buff[8];
  28.659     UPInt   origSize = GetSize();
  28.660 
  28.661     // Converts ch into UTF8 string and fills it into buff. Also increments index according to the number of bytes
  28.662     // in the UTF8 string.
  28.663     SPInt   srcSize = 0;
  28.664     UTF8Util::EncodeChar(buff, &srcSize, ch);
  28.665     OVR_ASSERT(srcSize >= 0);
  28.666     
  28.667     UPInt size = origSize + srcSize;
  28.668     Resize(size);
  28.669     memcpy(pData + origSize, buff, srcSize);
  28.670 }
  28.671 
  28.672 // Append a string
  28.673 void     StringBuffer::AppendString(const wchar_t* pstr, SPInt len)
  28.674 {
  28.675     if (!pstr)
  28.676         return;
  28.677 
  28.678     SPInt   srcSize     = UTF8Util::GetEncodeStringSize(pstr, len);
  28.679     UPInt   origSize    = GetSize();
  28.680     UPInt   size        = srcSize + origSize;
  28.681 
  28.682     Resize(size);
  28.683     UTF8Util::EncodeString(pData + origSize,  pstr, len);
  28.684 }
  28.685 
  28.686 void      StringBuffer::AppendString(const char* putf8str, SPInt utf8StrSz)
  28.687 {
  28.688     if (!putf8str || !utf8StrSz)
  28.689         return;
  28.690     if (utf8StrSz == -1)
  28.691         utf8StrSz = (SPInt)OVR_strlen(putf8str);
  28.692 
  28.693     UPInt   origSize    = GetSize();
  28.694     UPInt   size        = utf8StrSz + origSize;
  28.695 
  28.696     Resize(size);
  28.697     memcpy(pData + origSize, putf8str, utf8StrSz);
  28.698 }
  28.699 
  28.700 
  28.701 void      StringBuffer::operator = (const char* pstr)
  28.702 {
  28.703     pstr = pstr ? pstr : "";
  28.704     UPInt size = OVR_strlen(pstr);
  28.705     Resize(size);
  28.706     memcpy(pData, pstr, size);
  28.707 }
  28.708 
  28.709 void      StringBuffer::operator = (const wchar_t* pstr)
  28.710 {
  28.711     pstr = pstr ? pstr : L"";
  28.712     UPInt size = (UPInt)UTF8Util::GetEncodeStringSize(pstr);
  28.713     Resize(size);
  28.714     UTF8Util::EncodeString(pData, pstr);
  28.715 }
  28.716 
  28.717 void      StringBuffer::operator = (const String& src)
  28.718 {
  28.719     Resize(src.GetSize());
  28.720     memcpy(pData, src.ToCStr(), src.GetSize());
  28.721 }
  28.722 
  28.723 
  28.724 // Inserts substr at posAt
  28.725 void      StringBuffer::Insert(const char* substr, UPInt posAt, SPInt len)
  28.726 {
  28.727     UPInt     oldSize    = Size;
  28.728     UPInt     insertSize = (len < 0) ? OVR_strlen(substr) : (UPInt)len;    
  28.729     UPInt     byteIndex  = LengthIsSize ? posAt : 
  28.730                            (UPInt)UTF8Util::GetByteIndex(posAt, pData, (SPInt)Size);
  28.731 
  28.732     OVR_ASSERT(byteIndex <= oldSize);
  28.733     Reserve(oldSize + insertSize);
  28.734 
  28.735     memmove(pData + byteIndex + insertSize, pData + byteIndex, oldSize - byteIndex + 1);
  28.736     memcpy (pData + byteIndex, substr, insertSize);
  28.737     LengthIsSize = false;
  28.738     Size = oldSize + insertSize;
  28.739     pData[Size] = 0;
  28.740 }
  28.741 
  28.742 // Inserts character at posAt
  28.743 UPInt     StringBuffer::InsertCharAt(UInt32 c, UPInt posAt)
  28.744 {
  28.745     char    buf[8];
  28.746     SPInt   len = 0;
  28.747     UTF8Util::EncodeChar(buf, &len, c);
  28.748     OVR_ASSERT(len >= 0);
  28.749     buf[(UPInt)len] = 0;
  28.750 
  28.751     Insert(buf, posAt, len);
  28.752     return (UPInt)len;
  28.753 }
  28.754 
  28.755 } // OVR
  28.756 \ No newline at end of file
    29.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    29.2 +++ b/libovr/Src/Kernel/OVR_String.h	Sat Sep 14 16:14:59 2013 +0300
    29.3 @@ -0,0 +1,1 @@
    29.4 +/************************************************************************************
    29.5 
    29.6 PublicHeader:   OVR.h
    29.7 Filename    :   OVR_String.h
    29.8 Content     :   String UTF8 string implementation with copy-on-write semantics
    29.9                 (thread-safe for assignment but not modification).
   29.10 Created     :   September 19, 2012
   29.11 Notes       : 
   29.12 
   29.13 Copyright   :   Copyright 2012 Oculus VR, Inc. All Rights reserved.
   29.14 
   29.15 Use of this software is subject to the terms of the Oculus license
   29.16 agreement provided at the time of installation or download, or which
   29.17 otherwise accompanies this software in either electronic or hard copy form.
   29.18 
   29.19 ************************************************************************************/
   29.20 
   29.21 #ifndef OVR_String_h
   29.22 #define OVR_String_h
   29.23 
   29.24 #include "OVR_Types.h"
   29.25 #include "OVR_Allocator.h"
   29.26 #include "OVR_UTF8Util.h"
   29.27 #include "OVR_Atomic.h"
   29.28 #include "OVR_Std.h"
   29.29 #include "OVR_Alg.h"
   29.30 
   29.31 namespace OVR {
   29.32 
   29.33 // ***** Classes
   29.34 
   29.35 class String;
   29.36 class StringBuffer;
   29.37 
   29.38 
   29.39 //-----------------------------------------------------------------------------------
   29.40 // ***** String Class 
   29.41 
   29.42 // String is UTF8 based string class with copy-on-write implementation
   29.43 // for assignment.
   29.44 
   29.45 class String
   29.46 {
   29.47 protected:
   29.48 
   29.49     enum FlagConstants
   29.50     {
   29.51         //Flag_GetLength      = 0x7FFFFFFF,
   29.52         // This flag is set if GetLength() == GetSize() for a string.
   29.53         // Avoid extra scanning is Substring and indexing logic.
   29.54         Flag_LengthIsSizeShift   = (sizeof(UPInt)*8 - 1)
   29.55     };
   29.56 
   29.57 
   29.58     // Internal structure to hold string data
   29.59     struct DataDesc
   29.60     {
   29.61         // Number of bytes. Will be the same as the number of chars if the characters
   29.62         // are ascii, may not be equal to number of chars in case string data is UTF8.
   29.63         UPInt   Size;       
   29.64         volatile SInt32 RefCount;
   29.65         char    Data[1];
   29.66 
   29.67         void    AddRef()
   29.68         {
   29.69             AtomicOps<SInt32>::ExchangeAdd_NoSync(&RefCount, 1);
   29.70         }
   29.71         // Decrement ref count. This needs to be thread-safe, since
   29.72         // a different thread could have also decremented the ref count.
   29.73         // For example, if u start off with a ref count = 2. Now if u
   29.74         // decrement the ref count and check against 0 in different
   29.75         // statements, a different thread can also decrement the ref count
   29.76         // in between our decrement and checking against 0 and will find
   29.77         // the ref count = 0 and delete the object. This will lead to a crash
   29.78         // when context switches to our thread and we'll be trying to delete
   29.79         // an already deleted object. Hence decrementing the ref count and
   29.80         // checking against 0 needs to made an atomic operation.
   29.81         void    Release()
   29.82         {
   29.83             if ((AtomicOps<SInt32>::ExchangeAdd_NoSync(&RefCount, -1) - 1) == 0)
   29.84                 OVR_FREE(this);
   29.85         }
   29.86 
   29.87         static UPInt GetLengthFlagBit()     { return UPInt(1) << Flag_LengthIsSizeShift; }
   29.88         UPInt       GetSize() const         { return Size & ~GetLengthFlagBit() ; }
   29.89         UPInt       GetLengthFlag()  const  { return Size & GetLengthFlagBit(); }
   29.90         bool        LengthIsSize() const    { return GetLengthFlag() != 0; }
   29.91     };
   29.92 
   29.93     // Heap type of the string is encoded in the lower bits.
   29.94     enum HeapType
   29.95     {
   29.96         HT_Global   = 0,    // Heap is global.
   29.97         HT_Local    = 1,    // SF::String_loc: Heap is determined based on string's address.
   29.98         HT_Dynamic  = 2,    // SF::String_temp: Heap is stored as a part of the class.
   29.99         HT_Mask     = 3
  29.100     };
  29.101 
  29.102     union {
  29.103         DataDesc* pData;
  29.104         UPInt     HeapTypeBits;
  29.105     };
  29.106     typedef union {
  29.107         DataDesc* pData;
  29.108         UPInt     HeapTypeBits;
  29.109     } DataDescUnion;
  29.110 
  29.111     inline HeapType    GetHeapType() const { return (HeapType) (HeapTypeBits & HT_Mask); }
  29.112 
  29.113     inline DataDesc*   GetData() const
  29.114     {
  29.115         DataDescUnion u;
  29.116         u.pData    = pData;
  29.117         u.HeapTypeBits = (u.HeapTypeBits & ~(UPInt)HT_Mask);
  29.118         return u.pData;
  29.119     }
  29.120     
  29.121     inline void        SetData(DataDesc* pdesc)
  29.122     {
  29.123         HeapType ht = GetHeapType();
  29.124         pData = pdesc;
  29.125         OVR_ASSERT((HeapTypeBits & HT_Mask) == 0);
  29.126         HeapTypeBits |= ht;        
  29.127     }
  29.128 
  29.129     
  29.130     DataDesc*   AllocData(UPInt size, UPInt lengthIsSize);
  29.131     DataDesc*   AllocDataCopy1(UPInt size, UPInt lengthIsSize,
  29.132                                const char* pdata, UPInt copySize);
  29.133     DataDesc*   AllocDataCopy2(UPInt size, UPInt lengthIsSize,
  29.134                                const char* pdata1, UPInt copySize1,
  29.135                                const char* pdata2, UPInt copySize2);
  29.136 
  29.137     // Special constructor to avoid data initalization when used in derived class.
  29.138     struct NoConstructor { };
  29.139     String(const NoConstructor&) { }
  29.140 
  29.141 public:
  29.142 
  29.143     // For initializing string with dynamic buffer
  29.144     struct InitStruct
  29.145     {
  29.146         virtual ~InitStruct() { }
  29.147         virtual void InitString(char* pbuffer, UPInt size) const = 0;
  29.148     };
  29.149 
  29.150 
  29.151     // Constructors / Destructors.
  29.152     String();
  29.153     String(const char* data);
  29.154     String(const char* data1, const char* pdata2, const char* pdata3 = 0);
  29.155     String(const char* data, UPInt buflen);
  29.156     String(const String& src);
  29.157     String(const StringBuffer& src);
  29.158     String(const InitStruct& src, UPInt size);
  29.159     explicit String(const wchar_t* data);      
  29.160 
  29.161     // Destructor (Captain Obvious guarantees!)
  29.162     ~String()
  29.163     {
  29.164         GetData()->Release();
  29.165     }
  29.166 
  29.167     // Declaration of NullString
  29.168     static DataDesc NullData;
  29.169 
  29.170 
  29.171     // *** General Functions
  29.172 
  29.173     void        Clear();
  29.174 
  29.175     // For casting to a pointer to char.
  29.176     operator const char*() const        { return GetData()->Data; }
  29.177     // Pointer to raw buffer.
  29.178     const char* ToCStr() const          { return GetData()->Data; }
  29.179 
  29.180     // Returns number of bytes
  29.181     UPInt       GetSize() const         { return GetData()->GetSize() ; }
  29.182     // Tells whether or not the string is empty
  29.183     bool        IsEmpty() const         { return GetSize() == 0; }
  29.184 
  29.185     // Returns  number of characters
  29.186     UPInt       GetLength() const;
  29.187 
  29.188     // Returns  character at the specified index
  29.189     UInt32      GetCharAt(UPInt index) const;
  29.190     UInt32      GetFirstCharAt(UPInt index, const char** offset) const;
  29.191     UInt32      GetNextChar(const char** offset) const;
  29.192 
  29.193     // Appends a character
  29.194     void        AppendChar(UInt32 ch);
  29.195 
  29.196     // Append a string
  29.197     void        AppendString(const wchar_t* pstr, SPInt len = -1);
  29.198     void        AppendString(const char* putf8str, SPInt utf8StrSz = -1);
  29.199 
  29.200     // Assigned a string with dynamic data (copied through initializer).
  29.201     void        AssignString(const InitStruct& src, UPInt size);
  29.202     // Assigns string with known size.
  29.203     void        AssignString(const char* putf8str, UPInt size);
  29.204 
  29.205     //  Resize the string to the new size
  29.206 //  void        Resize(UPInt _size);
  29.207 
  29.208     // Removes the character at posAt
  29.209     void        Remove(UPInt posAt, SPInt len = 1);
  29.210 
  29.211     // Returns a String that's a substring of this.
  29.212     //  -start is the index of the first UTF8 character you want to include.
  29.213     //  -end is the index one past the last UTF8 character you want to include.
  29.214     String   Substring(UPInt start, UPInt end) const;
  29.215 
  29.216     // Case-conversion
  29.217     String   ToUpper() const;
  29.218     String   ToLower() const;
  29.219 
  29.220     // Inserts substr at posAt
  29.221     String&    Insert (const char* substr, UPInt posAt, SPInt len = -1);
  29.222 
  29.223     // Inserts character at posAt
  29.224     UPInt       InsertCharAt(UInt32 c, UPInt posAt);
  29.225 
  29.226     // Inserts substr at posAt, which is an index of a character (not byte).
  29.227     // Of size is specified, it is in bytes.
  29.228 //  String&    Insert(const UInt32* substr, UPInt posAt, SPInt size = -1);
  29.229 
  29.230     // Get Byte index of the character at position = index
  29.231     UPInt       GetByteIndex(UPInt index) const { return (UPInt)UTF8Util::GetByteIndex(index, GetData()->Data); }
  29.232 
  29.233     // Utility: case-insensitive string compare.  stricmp() & strnicmp() are not
  29.234     // ANSI or POSIX, do not seem to appear in Linux.
  29.235     static int OVR_STDCALL   CompareNoCase(const char* a, const char* b);
  29.236     static int OVR_STDCALL   CompareNoCase(const char* a, const char* b, SPInt len);
  29.237 
  29.238     // Hash function, case-insensitive
  29.239     static UPInt OVR_STDCALL BernsteinHashFunctionCIS(const void* pdataIn, UPInt size, UPInt seed = 5381);
  29.240 
  29.241     // Hash function, case-sensitive
  29.242     static UPInt OVR_STDCALL BernsteinHashFunction(const void* pdataIn, UPInt size, UPInt seed = 5381);
  29.243 
  29.244 
  29.245     // ***** File path parsing helper functions.
  29.246     // Implemented in OVR_String_FilePath.cpp.
  29.247 
  29.248     // Absolute paths can star with:
  29.249     //  - protocols:        'file://', 'http://'
  29.250     //  - windows drive:    'c:\'
  29.251     //  - UNC share name:   '\\share'
  29.252     //  - unix root         '/'
  29.253     static bool HasAbsolutePath(const char* path);
  29.254     static bool HasExtension(const char* path);
  29.255     static bool HasProtocol(const char* path);
  29.256 
  29.257     bool    HasAbsolutePath() const { return HasAbsolutePath(ToCStr()); }
  29.258     bool    HasExtension() const    { return HasExtension(ToCStr()); }
  29.259     bool    HasProtocol() const     { return HasProtocol(ToCStr()); }
  29.260 
  29.261     String  GetProtocol() const;    // Returns protocol, if any, with trailing '://'.
  29.262     String  GetPath() const;        // Returns path with trailing '/'.
  29.263     String  GetFilename() const;    // Returns filename, including extension.
  29.264     String  GetExtension() const;   // Returns extension with a dot.
  29.265 
  29.266     void    StripProtocol();        // Strips front protocol, if any, from the string.
  29.267     void    StripExtension();       // Strips off trailing extension.
  29.268     
  29.269 
  29.270     // Operators
  29.271     // Assignment
  29.272     void        operator =  (const char* str);
  29.273     void        operator =  (const wchar_t* str);
  29.274     void        operator =  (const String& src);
  29.275     void        operator =  (const StringBuffer& src);
  29.276 
  29.277     // Addition
  29.278     void        operator += (const String& src);
  29.279     void        operator += (const char* psrc)       { AppendString(psrc); }
  29.280     void        operator += (const wchar_t* psrc)    { AppendString(psrc); }
  29.281     void        operator += (char  ch)               { AppendChar(ch); }
  29.282     String      operator +  (const char* str) const;
  29.283     String      operator +  (const String& src)  const;
  29.284 
  29.285     // Comparison
  29.286     bool        operator == (const String& str) const
  29.287     {
  29.288         return (OVR_strcmp(GetData()->Data, str.GetData()->Data)== 0);
  29.289     }
  29.290 
  29.291     bool        operator != (const String& str) const
  29.292     {
  29.293         return !operator == (str);
  29.294     }
  29.295 
  29.296     bool        operator == (const char* str) const
  29.297     {
  29.298         return OVR_strcmp(GetData()->Data, str) == 0;
  29.299     }
  29.300 
  29.301     bool        operator != (const char* str) const
  29.302     {
  29.303         return !operator == (str);
  29.304     }
  29.305 
  29.306     bool        operator <  (const char* pstr) const
  29.307     {
  29.308         return OVR_strcmp(GetData()->Data, pstr) < 0;
  29.309     }
  29.310 
  29.311     bool        operator <  (const String& str) const
  29.312     {
  29.313         return *this < str.GetData()->Data;
  29.314     }
  29.315 
  29.316     bool        operator >  (const char* pstr) const
  29.317     {
  29.318         return OVR_strcmp(GetData()->Data, pstr) > 0;
  29.319     }
  29.320 
  29.321     bool        operator >  (const String& str) const
  29.322     {
  29.323         return *this > str.GetData()->Data;
  29.324     }
  29.325 
  29.326     int CompareNoCase(const char* pstr) const
  29.327     {
  29.328         return CompareNoCase(GetData()->Data, pstr);
  29.329     }
  29.330     int CompareNoCase(const String& str) const
  29.331     {
  29.332         return CompareNoCase(GetData()->Data, str.ToCStr());
  29.333     }
  29.334 
  29.335     // Accesses raw bytes
  29.336     const char&     operator [] (int index) const
  29.337     {
  29.338         OVR_ASSERT(index >= 0 && (UPInt)index < GetSize());
  29.339         return GetData()->Data[index];
  29.340     }
  29.341     const char&     operator [] (UPInt index) const
  29.342     {
  29.343         OVR_ASSERT(index < GetSize());
  29.344         return GetData()->Data[index];
  29.345     }
  29.346 
  29.347 
  29.348     // Case insensitive keys are used to look up insensitive string in hash tables
  29.349     // for SWF files with version before SWF 7.
  29.350     struct NoCaseKey
  29.351     {   
  29.352         const String* pStr;
  29.353         NoCaseKey(const String &str) : pStr(&str){};
  29.354     };
  29.355 
  29.356     bool    operator == (const NoCaseKey& strKey) const
  29.357     {
  29.358         return (CompareNoCase(ToCStr(), strKey.pStr->ToCStr()) == 0);
  29.359     }
  29.360     bool    operator != (const NoCaseKey& strKey) const
  29.361     {
  29.362         return !(CompareNoCase(ToCStr(), strKey.pStr->ToCStr()) == 0);
  29.363     }
  29.364 
  29.365     // Hash functor used for strings.
  29.366     struct HashFunctor
  29.367     {    
  29.368         UPInt  operator()(const String& data) const
  29.369         {
  29.370             UPInt  size = data.GetSize();
  29.371             return String::BernsteinHashFunction((const char*)data, size);
  29.372         }        
  29.373     };
  29.374     // Case-insensitive hash functor used for strings. Supports additional
  29.375     // lookup based on NoCaseKey.
  29.376     struct NoCaseHashFunctor
  29.377     {    
  29.378         UPInt  operator()(const String& data) const
  29.379         {
  29.380             UPInt  size = data.GetSize();
  29.381             return String::BernsteinHashFunctionCIS((const char*)data, size);
  29.382         }
  29.383         UPInt  operator()(const NoCaseKey& data) const
  29.384         {       
  29.385             UPInt  size = data.pStr->GetSize();
  29.386             return String::BernsteinHashFunctionCIS((const char*)data.pStr->ToCStr(), size);
  29.387         }
  29.388     };
  29.389 
  29.390 };
  29.391 
  29.392 
  29.393 //-----------------------------------------------------------------------------------
  29.394 // ***** String Buffer used for Building Strings
  29.395 
  29.396 class StringBuffer
  29.397 {
  29.398     char*           pData;
  29.399     UPInt           Size;
  29.400     UPInt           BufferSize;
  29.401     UPInt           GrowSize;    
  29.402     mutable bool    LengthIsSize;    
  29.403 
  29.404 public:
  29.405 
  29.406     // Constructors / Destructor.    
  29.407     StringBuffer();
  29.408     explicit StringBuffer(UPInt growSize);
  29.409     StringBuffer(const char* data);
  29.410     StringBuffer(const char* data, UPInt buflen);
  29.411     StringBuffer(const String& src);
  29.412     StringBuffer(const StringBuffer& src);
  29.413     explicit StringBuffer(const wchar_t* data);
  29.414     ~StringBuffer();
  29.415     
  29.416 
  29.417     // Modify grow size used for growing/shrinking the buffer.
  29.418     UPInt       GetGrowSize() const         { return GrowSize; }
  29.419     void        SetGrowSize(UPInt growSize);
  29.420     
  29.421 
  29.422     // *** General Functions
  29.423     // Does not release memory, just sets Size to 0
  29.424     void        Clear();
  29.425 
  29.426     // For casting to a pointer to char.
  29.427     operator const char*() const        { return (pData) ? pData : ""; }
  29.428     // Pointer to raw buffer.
  29.429     const char* ToCStr() const          { return (pData) ? pData : ""; }
  29.430 
  29.431     // Returns number of bytes.
  29.432     UPInt       GetSize() const         { return Size ; }
  29.433     // Tells whether or not the string is empty.
  29.434     bool        IsEmpty() const         { return GetSize() == 0; }
  29.435 
  29.436     // Returns  number of characters
  29.437     UPInt       GetLength() const;
  29.438 
  29.439     // Returns  character at the specified index
  29.440     UInt32      GetCharAt(UPInt index) const;
  29.441     UInt32      GetFirstCharAt(UPInt index, const char** offset) const;
  29.442     UInt32      GetNextChar(const char** offset) const;
  29.443 
  29.444 
  29.445     //  Resize the string to the new size
  29.446     void        Resize(UPInt _size);
  29.447     void        Reserve(UPInt _size);
  29.448 
  29.449     // Appends a character
  29.450     void        AppendChar(UInt32 ch);
  29.451 
  29.452     // Append a string
  29.453     void        AppendString(const wchar_t* pstr, SPInt len = -1);
  29.454     void        AppendString(const char* putf8str, SPInt utf8StrSz = -1);
  29.455     void        AppendFormat(const char* format, ...);
  29.456 
  29.457     // Assigned a string with dynamic data (copied through initializer).
  29.458     //void        AssignString(const InitStruct& src, UPInt size);
  29.459 
  29.460     // Inserts substr at posAt
  29.461     void        Insert (const char* substr, UPInt posAt, SPInt len = -1);
  29.462     // Inserts character at posAt
  29.463     UPInt       InsertCharAt(UInt32 c, UPInt posAt);
  29.464 
  29.465     // Assignment
  29.466     void        operator =  (const char* str);
  29.467     void        operator =  (const wchar_t* str);
  29.468     void        operator =  (const String& src);
  29.469 
  29.470     // Addition
  29.471     void        operator += (const String& src)      { AppendString(src.ToCStr(),src.GetSize()); }
  29.472     void        operator += (const char* psrc)       { AppendString(psrc); }
  29.473     void        operator += (const wchar_t* psrc)    { AppendString(psrc); }
  29.474     void        operator += (char  ch)               { AppendChar(ch); }
  29.475     //String   operator +  (const char* str) const ;
  29.476     //String   operator +  (const String& src)  const ;
  29.477 
  29.478     // Accesses raw bytes
  29.479     char&       operator [] (int index)
  29.480     {
  29.481         OVR_ASSERT(((UPInt)index) < GetSize());
  29.482         return pData[index];
  29.483     }
  29.484     char&       operator [] (UPInt index)
  29.485     {
  29.486         OVR_ASSERT(index < GetSize());
  29.487         return pData[index];
  29.488     }
  29.489 
  29.490     const char&     operator [] (int index) const 
  29.491     {
  29.492         OVR_ASSERT(((UPInt)index) < GetSize());
  29.493         return pData[index];
  29.494     }
  29.495     const char&     operator [] (UPInt index) const
  29.496     {
  29.497         OVR_ASSERT(index < GetSize());
  29.498         return pData[index];
  29.499     }
  29.500 };
  29.501 
  29.502 
  29.503 //
  29.504 // Wrapper for string data. The data must have a guaranteed 
  29.505 // lifespan throughout the usage of the wrapper. Not intended for 
  29.506 // cached usage. Not thread safe.
  29.507 //
  29.508 class StringDataPtr
  29.509 {
  29.510 public:
  29.511     StringDataPtr() : pStr(NULL), Size(0) {}
  29.512     StringDataPtr(const StringDataPtr& p)
  29.513         : pStr(p.pStr), Size(p.Size) {}
  29.514     StringDataPtr(const char* pstr, UPInt sz)
  29.515         : pStr(pstr), Size(sz) {}
  29.516     StringDataPtr(const char* pstr)
  29.517         : pStr(pstr), Size((pstr != NULL) ? OVR_strlen(pstr) : 0) {}
  29.518     explicit StringDataPtr(const String& str)
  29.519         : pStr(str.ToCStr()), Size(str.GetSize()) {}
  29.520     template <typename T, int N> 
  29.521     StringDataPtr(const T (&v)[N])
  29.522         : pStr(v), Size(N) {}
  29.523 
  29.524 public:
  29.525     const char* ToCStr() const { return pStr; }
  29.526     UPInt       GetSize() const { return Size; }
  29.527     bool        IsEmpty() const { return GetSize() == 0; }
  29.528 
  29.529     // value is a prefix of this string
  29.530     // Character's values are not compared.
  29.531     bool        IsPrefix(const StringDataPtr& value) const
  29.532     {
  29.533         return ToCStr() == value.ToCStr() && GetSize() >= value.GetSize();
  29.534     }
  29.535     // value is a suffix of this string
  29.536     // Character's values are not compared.
  29.537     bool        IsSuffix(const StringDataPtr& value) const
  29.538     {
  29.539         return ToCStr() <= value.ToCStr() && (End()) == (value.End());
  29.540     }
  29.541 
  29.542     // Find first character.
  29.543     // init_ind - initial index.
  29.544     SPInt       FindChar(char c, UPInt init_ind = 0) const 
  29.545     {
  29.546         for (UPInt i = init_ind; i < GetSize(); ++i)
  29.547             if (pStr[i] == c)
  29.548                 return static_cast<SPInt>(i);
  29.549 
  29.550         return -1; 
  29.551     }
  29.552 
  29.553     // Find last character.
  29.554     // init_ind - initial index.
  29.555     SPInt       FindLastChar(char c, UPInt init_ind = ~0) const 
  29.556     {
  29.557         if (init_ind == (UPInt)~0 || init_ind > GetSize())
  29.558             init_ind = GetSize();
  29.559         else
  29.560             ++init_ind;
  29.561 
  29.562         for (UPInt i = init_ind; i > 0; --i)
  29.563             if (pStr[i - 1] == c)
  29.564                 return static_cast<SPInt>(i - 1);
  29.565 
  29.566         return -1; 
  29.567     }
  29.568 
  29.569     // Create new object and trim size bytes from the left.
  29.570     StringDataPtr  GetTrimLeft(UPInt size) const
  29.571     {
  29.572         // Limit trim size to the size of the string.
  29.573         size = Alg::PMin(GetSize(), size);
  29.574 
  29.575         return StringDataPtr(ToCStr() + size, GetSize() - size);
  29.576     }
  29.577     // Create new object and trim size bytes from the right.
  29.578     StringDataPtr  GetTrimRight(UPInt size) const
  29.579     {
  29.580         // Limit trim to the size of the string.
  29.581         size = Alg::PMin(GetSize(), size);
  29.582 
  29.583         return StringDataPtr(ToCStr(), GetSize() - size);
  29.584     }
  29.585 
  29.586     // Create new object, which contains next token.
  29.587     // Useful for parsing.
  29.588     StringDataPtr GetNextToken(char separator = ':') const
  29.589     {
  29.590         UPInt cur_pos = 0;
  29.591         const char* cur_str = ToCStr();
  29.592 
  29.593         for (; cur_pos < GetSize() && cur_str[cur_pos]; ++cur_pos)
  29.594         {
  29.595             if (cur_str[cur_pos] == separator)
  29.596             {
  29.597                 break;
  29.598             }
  29.599         }
  29.600 
  29.601         return StringDataPtr(ToCStr(), cur_pos);
  29.602     }
  29.603 
  29.604     // Trim size bytes from the left.
  29.605     StringDataPtr& TrimLeft(UPInt size)
  29.606     {
  29.607         // Limit trim size to the size of the string.
  29.608         size = Alg::PMin(GetSize(), size);
  29.609         pStr += size;
  29.610         Size -= size;
  29.611 
  29.612         return *this;
  29.613     }
  29.614     // Trim size bytes from the right.
  29.615     StringDataPtr& TrimRight(UPInt size)
  29.616     {
  29.617         // Limit trim to the size of the string.
  29.618         size = Alg::PMin(GetSize(), size);
  29.619         Size -= size;
  29.620 
  29.621         return *this;
  29.622     }
  29.623 
  29.624     const char* Begin() const { return ToCStr(); }
  29.625     const char* End() const { return ToCStr() + GetSize(); }
  29.626 
  29.627     // Hash functor used string data pointers
  29.628     struct HashFunctor
  29.629     {    
  29.630         UPInt operator()(const StringDataPtr& data) const
  29.631         {
  29.632             return String::BernsteinHashFunction(data.ToCStr(), data.GetSize());
  29.633         }        
  29.634     };
  29.635 
  29.636     bool operator== (const StringDataPtr& data) const 
  29.637     {
  29.638         re