oculus1
changeset 1:e2f9e4603129
added LibOVR and started a simple vr wrapper.
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