Initial Patch of Auction House bot rev. 135
[auctionmangos.git] / dep / src / g3dlite / format.cpp
blob6def987c21b6d343fb5ad511a51c6f59ad03de96
1 /**
2 @file format.cpp
4 @author Morgan McGuire, graphics3d.com
6 @created 2000-09-09
7 @edited 2006-04-30
8 */
10 #include "G3D/format.h"
11 #include "G3D/platform.h"
12 #include "G3D/System.h"
14 #ifdef G3D_WIN32
15 #include <math.h>
16 #define vsnprintf _vsnprintf
17 #define NEWLINE "\r\n"
18 #else
19 #include <stdarg.h>
20 #define NEWLINE "\n"
21 #endif
23 #ifdef _MSC_VER
24 // disable: "C++ exception handler used"
25 # pragma warning (push)
26 # pragma warning (disable : 4530)
27 #endif // _MSC_VER
29 // If your platform does not have vsnprintf, you can find a
30 // implementation at http://www.ijs.si/software/snprintf/
32 namespace G3D {
34 std::string format(const char* fmt,...) {
35 va_list argList;
36 va_start(argList,fmt);
37 std::string result = vformat(fmt, argList);
38 va_end(argList);
40 return result;
43 #if defined(G3D_WIN32) && (_MSC_VER >= 1300)
44 // Both MSVC6 and 7 seem to use the non-standard vsnprintf
45 // so we are using vscprintf to determine buffer size, however
46 // only MSVC7 headers include vscprintf for some reason.
47 std::string vformat(const char *fmt, va_list argPtr) {
48 // We draw the line at a 1MB string.
49 const int maxSize = 1000000;
51 // If the string is less than 161 characters,
52 // allocate it on the stack because this saves
53 // the malloc/free time.
54 const int bufSize = 161;
55 char stackBuffer[bufSize];
57 int actualSize = _vscprintf(fmt, argPtr) + 1;
59 if (actualSize > bufSize) {
61 // Now use the heap.
62 char* heapBuffer = NULL;
64 if (actualSize < maxSize) {
66 heapBuffer = (char*)System::malloc(maxSize + 1);
67 vsnprintf(heapBuffer, maxSize, fmt, argPtr);
68 heapBuffer[maxSize] = '\0';
69 } else {
70 heapBuffer = (char*)System::malloc(actualSize);
71 vsprintf(heapBuffer, fmt, argPtr);
74 std::string formattedString(heapBuffer);
75 System::free(heapBuffer);
76 return formattedString;
77 } else {
79 vsprintf(stackBuffer, fmt, argPtr);
80 return std::string(stackBuffer);
84 #elif defined(G3D_WIN32) && (_MSC_VER < 1300)
86 std::string vformat(const char *fmt, va_list argPtr) {
87 // We draw the line at a 1MB string.
88 const int maxSize = 1000000;
90 // If the string is less than 161 characters,
91 // allocate it on the stack because this saves
92 // the malloc/free time.
93 const int bufSize = 161;
94 char stackBuffer[bufSize];
96 int actualWritten = vsnprintf(stackBuffer, bufSize, fmt, argPtr);
98 // Not a big enough buffer, bufSize characters written
99 if (actualWritten == -1) {
101 int heapSize = 512;
102 double powSize = 1.0;
103 char* heapBuffer = (char*)System::malloc(heapSize);
105 while ((vsnprintf(heapBuffer, heapSize, fmt, argPtr) == -1) &&
106 (heapSize < maxSize)) {
108 heapSize = iCeil(heapSize * ::pow((double)2.0, powSize++));
109 heapBuffer = (char*)System::realloc(heapBuffer, heapSize);
112 heapBuffer[heapSize-1] = '\0';
114 std::string heapString(heapBuffer);
115 System::free(heapBuffer);
117 return heapString;
118 } else {
120 return std::string(stackBuffer);
124 #else
126 // glibc 2.1 has been updated to the C99 standard
127 std::string vformat(const char* fmt, va_list argPtr) {
128 // If the string is less than 161 characters,
129 // allocate it on the stack because this saves
130 // the malloc/free time. The number 161 is chosen
131 // to support two lines of text on an 80 character
132 // console (plus the null terminator).
133 const int bufSize = 161;
134 char stackBuffer[bufSize];
136 int numChars = vsnprintf(stackBuffer, bufSize, fmt, argPtr);
138 if (numChars >= bufSize) {
139 // We didn't allocate a big enough string.
140 char* heapBuffer = (char*)System::malloc((numChars + 1) * sizeof(char));
142 assert(heapBuffer);
143 int numChars2 = vsnprintf(heapBuffer, numChars + 1, fmt, argPtr);
144 assert(numChars2 == numChars);
146 std::string result(heapBuffer);
148 System::free(heapBuffer);
150 return result;
152 } else {
154 return std::string(stackBuffer);
159 #endif
161 } // namespace
163 #ifdef G3D_WIN32
164 # undef vsnprintf
165 #endif
167 #ifdef _MSC_VER
168 # pragma warning (pop)
169 #endif
171 #undef NEWLINE