1// tStandard.cpp 
2// 
3// Tacent functions and types that are standard across all platforms. Includes global functions like itoa which are not 
4// available on some platforms, but are common enough that they should be. 
5// 
6// Copyright (c) 2004-2006, 2015 Tristan Grimmer. 
7// Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby 
8// granted, provided that the above copyright notice and this permission notice appear in all copies. 
9// 
10// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL 
11// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 
12// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN 
13// AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 
14// PERFORMANCE OF THIS SOFTWARE. 
15 
16#include <stdlib.h> 
17#ifdef PLATFORM_WINDOWS 
18#include <Windows.h> 
19#endif 
20#include "Foundation/tStandard.h" 
21#include "Foundation/tString.h" 
22#pragma warning (disable: 4146) 
23#pragma warning (disable: 4018) 
24 
25 
26const char* tStd::SeparatorSubStr = "\x1a"
27const char* tStd::SeparatorFileStr = "\x1c"
28const char* tStd::SeparatorGroupStr = "\x1d"
29const char* tStd::SeparatorRecordStr = "\x1e"
30const char* tStd::SeparatorUnitStr = "\x1f"
31const char* tStd::SeparatorAStr = tStd::SeparatorUnitStr
32const char* tStd::SeparatorBStr = tStd::SeparatorRecordStr
33const char* tStd::SeparatorCStr = tStd::SeparatorGroupStr
34const char* tStd::SeparatorDStr = tStd::SeparatorFileStr
35const char* tStd::SeparatorEStr = tStd::SeparatorSubStr
36 
37 
38void* tStd::tMemmem(void* haystack, int haystackNumBytes, void* needle, int needleNumBytes
39
40 if ((haystackNumBytes <= 0) || (needleNumBytes <= 0) || (haystackNumBytes < needleNumBytes)) 
41 return nullptr
42 
43 // Serach for the pattern from the first haystack byte (0) to numNeedleBytes from the end. For example, if we are 
44 // seraching for 4 bytes in 8, there will be 5 mem compares of 4 bytes each. 
45 for (int i = 0; i <= haystackNumBytes-needleNumBytes; i++) 
46
47 if (tMemcmp((uint8*)haystack + i, needle, needleNumBytes) == 0
48 return (uint8*)haystack + i
49
50 
51 return nullptr
52
53 
54 
55float tStd::tStrtof(const char* s
56
57 char* hash = tStrchr(s, '#'); 
58 if (hash && (tStrlen(hash+1) == 8)) 
59
60 uint32 bin = tStd::tStrtoui32(hash+1, 16); 
61 return *((float*)(&bin)); 
62
63 
64 return float( tStrtod(s) ); 
65
66 
67 
68double tStd::tStrtod(const char* s
69
70 int l = tStrlen(s); 
71 if (!l
72 return 0.0
73 
74 char* hash = tStrchr(s, '#'); 
75 if (hash && (tStrlen(hash+1) == 16)) 
76
77 uint64 bin = tStrtoui64(hash+1, 16); 
78 return *((double*)&bin); 
79
80 
81 // This error checking is essential. Sometimes NANs are written in text format to a string. 
82 // Like "nan(snan)". We want these to evaluate to 0.0, not -1 or something else. We allow 
83 // 'e' and 'E' for numbers in exponential form like 3.09E08. 
84 for (int i = 0; i < l; i++) 
85
86 char ch = s[i]; 
87 if 
88
89 ((ch >= 'a') && (ch <= 'z') && (ch != 'e')) || 
90 ((ch >= 'A') && (ch <= 'Z') && (ch != 'E')) 
91
92 return 0.0
93
94 
95 // Will be 0.0 if there was a problem. 
96 return strtod(s, nullptr); 
97
98 
99 
100bool tStd::tStrtob(const char* str
101
102 tString lower(str); 
103 lower.ToLower(); 
104 
105 if 
106
107 (lower == "true") || (lower == "t") || 
108 (lower == "yes") || (lower == "y") || 
109 (lower == "on") || (lower == "1") || (lower == "+") || 
110 (lower == "enable") || (lower == "enabled") || (tStrtoi(str) != 0
111
112 return true
113 else 
114 return false
115
116 
117 
118void tStd::tStrrev(char* begin, char* end
119{  
120 char aux
121 while (end > begin
122 aux = *end, *end-- = *begin, *begin++ = aux
123
124