[Tizen] Unify dnetmemoryenumlib terms to match the codebase (#291)
[platform/upstream/coreclr.git] / src / utilcode / outstring.cpp
1 // Licensed to the .NET Foundation under one or more agreements.
2 // The .NET Foundation licenses this file to you under the MIT license.
3 // See the LICENSE file in the project root for more information.
4
5 /*****************************************************************/
6 /*                         OutString.cpp                         */
7 /*****************************************************************/
8 /* A simple, lightweight, character output stream, with very few
9    external dependancies (like sprintf ... ) */
10
11 /*  
12    Date :  2/1/99                               */
13 /*****************************************************************/
14
15 #include "stdafx.h"
16 #include "outstring.h"
17
18
19 /*****************************************************************/
20 //  print out 'count' instances of the character 'c'
21 OutString& OutString::pad(size_t count, char c) {
22         if (cur+count > end)
23                 Realloc(count);
24         memset(cur, c, count);
25         cur = cur + count;
26         return(*this);
27 }
28
29 /*****************************************************************/
30 // prints out a decimal representation
31 OutString& OutString::operator<<(double d) {
32
33         if (d == 0.0) {
34                 *this << "0.0";
35                 return *this;
36         }
37
38         if (d < 0) {
39                 d = -d;
40                 *this << '-';
41         }
42
43                 // compute the exponent
44         int exponent = 0;
45         while (d > 10.0)  {
46                 d /= 10;
47                 exponent++;
48                 if (exponent > 500) {           // avoids a possible infinite loop
49             *this << "INF";             
50                         return *this;
51                 }
52         }
53         while (d < 1.0)  {
54                 d *= 10;
55                 --exponent;
56                 if (exponent < -500) {          // avoids a possible infinite loop
57                         *this << "0.0";         
58                         return *this;
59                 }
60         }
61
62         // we now have a normalized d (between 1 and 10)
63         double delta = .5E-10;          
64         d += delta;             // round to the precision we are displaying
65
66         unsigned trailingZeros = 0;
67         for(unsigned i = 0; i < 10; i++) {
68                 int digit = (int) d;
69                 d = (d - digit) * 10;           // ISSUE: does roundoff ever bite us here?
70         
71                 if (digit == 0)         // defer printing traiing zeros
72                         trailingZeros++;
73                 else {
74                         if (trailingZeros > 0) {
75                                 this->pad(trailingZeros, '0');
76                                 trailingZeros = 0;
77                         }
78                 *this << (char) ('0' + digit);
79                 }
80                 if (i == 0)
81                         *this << '.';
82         
83         }
84         if (exponent != 0) {
85                 *this << 'E';
86                 *this << exponent;
87         }
88         return(*this);
89 }
90
91 /*****************************************************************/
92 // prints out a decimal representation
93 OutString& OutString::dec(int i, size_t minWidth) {
94         char buff[12];                  // big enough for any number (10 digits, - sign, null term)
95         char* ptr = &buff[11];
96         *ptr = 0;
97
98         unsigned val = i;
99         if (i < 0)
100                 val = -i;       // note this happens to also work for minint!
101
102         for(;;) {
103                 if (val < 10) {
104                         *--ptr = '0' + val;
105                         break;
106                         }
107                 *--ptr = '0' + (val % 10);
108                 val = val / 10;
109                 }
110
111         if (i < 0)
112                 *--ptr = '-';
113         
114         size_t len = &buff[11] - ptr;   // length of string
115         if (len < minWidth)
116                 pad(minWidth-len, ' ');
117         
118         *this << ptr;
119         return(*this);
120 }
121
122 /*****************************************************************/
123 OutString& OutString::hex(unsigned __int64 i, int minWidth, unsigned flags) {
124
125         unsigned hi = unsigned(i >> 32);
126         unsigned low = unsigned(i);
127         
128         if (hi != 0) {
129                 minWidth -= 8;
130                 hex(hi, minWidth, flags);               // print upper bits
131                 flags = zeroFill;
132                 minWidth = 8;
133         }
134         return hex(low, minWidth, flags);       // print lower bits
135 }
136
137 /*****************************************************************/
138 OutString& OutString::hex(unsigned i, int minWidth, unsigned flags) {
139         char buff[12];                  // big enough for any number 
140         char* ptr = &buff[11];
141         *ptr = 0;
142
143     static const char digits[] = "0123456789ABCDEF";
144
145         for(;;) {
146                 if (i < 16) {
147                         *--ptr = digits[i];
148                         break;
149                         }
150                 *--ptr = digits[(i % 16)];
151                 i = i / 16;
152                 }
153
154         size_t len = &buff[11] - ptr;                   // length of string
155         if (flags & put0x) {
156         if (flags & zeroFill)
157                     *this << "0x";
158         else
159             *--ptr = 'x', *--ptr = '0';
160                 len += 2;
161                 }
162
163         if (len < (size_t)minWidth)
164                 pad(minWidth-len, (flags & zeroFill) ? '0' : ' ');
165         
166         *this << ptr;
167         return(*this);
168 }
169
170 /*****************************************************************/
171 void OutString::Realloc(size_t neededSpace)  {
172     size_t oldSize = cur-start;
173         size_t newSize = (oldSize + neededSpace) * 3 / 2 + 32;
174         char* oldBuff = start;
175         start = new char[newSize+1];
176         memcpy(start, oldBuff, oldSize);
177         cur = &start[oldSize];
178         end = &start[newSize];
179         delete [] oldBuff;
180 }
181