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 | /*****************************************************************/ |
7 | /* OutString.h */ |
8 | /*****************************************************************/ |
9 | /* A simple, lightweight, character output stream, with very few |
10 | external dependancies (like sprintf ... ) */ |
11 | |
12 | /* |
13 | Date : 2/1/99 */ |
14 | /*****************************************************************/ |
15 | |
16 | #ifndef _OutString_h |
17 | #define _OutString_h 1 |
18 | |
19 | #include "utilcode.h" // for overloaded new |
20 | #include <string.h> // for strlen, strcpy |
21 | |
22 | /*****************************************************************/ |
23 | // a light weight character 'output' stream |
24 | class OutString { |
25 | public: |
26 | enum FormatFlags { // used to control printing of numbers |
27 | none = 0, |
28 | put0x = 1, // put leading 0x on hexidecimal |
29 | zeroFill = 2, // zero fill (instead of space fill) |
30 | }; |
31 | |
32 | OutString() : start(0), end(0), cur(0) {} |
33 | |
34 | OutString(unsigned initialAlloc) { |
35 | cur = start = new char[initialAlloc+1]; // for null termination |
36 | end = &start[initialAlloc]; |
37 | } |
38 | |
39 | ~OutString() { delete start; } |
40 | |
41 | // shortcut for printing decimal |
42 | OutString& operator<<(int i) { return(dec(i)); } |
43 | |
44 | OutString& operator<<(double d); |
45 | |
46 | // FIX make this really unsigned |
47 | OutString& operator<<(unsigned i) { return(dec(i)); } |
48 | |
49 | // prints out the hexidecimal representation |
50 | OutString& dec(int i, size_t minWidth = 0); |
51 | |
52 | // prints out the hexidecimal representation |
53 | OutString& hex(unsigned i, int minWidth = 0, unsigned flags = none); |
54 | |
55 | OutString& hex(unsigned __int64 i, int minWidth = 0, unsigned flags = none); |
56 | |
57 | OutString& hex(int i, int minWidth = 0, unsigned flags = none) { |
58 | return hex(unsigned(i), minWidth, flags); |
59 | } |
60 | |
61 | OutString& hex(__int64 i, int minWidth = 0, unsigned flags = none) { |
62 | return hex((unsigned __int64) i, minWidth, flags); |
63 | } |
64 | |
65 | // print out 'count' instances of the character 'c' |
66 | OutString& pad(size_t count, char c); |
67 | |
68 | OutString& operator<<(char c) { |
69 | if (cur >= end) |
70 | Realloc(1); |
71 | *cur++ = c; |
72 | _ASSERTE(start <= cur && cur <= end); |
73 | return(*this); |
74 | } |
75 | |
76 | OutString& operator<<(const wchar_t* str) { |
77 | size_t len = wcslen(str); |
78 | if (cur+len > end) |
79 | Realloc(len); |
80 | while(str != 0) |
81 | *cur++ = (char) *str++; |
82 | _ASSERTE(start <= cur && cur <= end); |
83 | return(*this); |
84 | } |
85 | |
86 | OutString& prepend(const char c) { |
87 | char buff[2]; buff[0] = c; buff[1] = 0; |
88 | return(prepend(buff)); |
89 | } |
90 | |
91 | OutString& prepend(const char* str) { |
92 | size_t len = strlen(str); |
93 | if (cur+len > end) |
94 | Realloc(len); |
95 | memmove(start+len, start, cur-start); |
96 | memcpy(start, str, len); |
97 | cur = cur + len; |
98 | _ASSERTE(start <= cur && cur <= end); |
99 | return(*this); |
100 | } |
101 | |
102 | OutString& operator=(const OutString& str) { |
103 | clear(); |
104 | *this << str; |
105 | return(*this); |
106 | } |
107 | |
108 | OutString& operator<<(const OutString& str) { |
109 | write(str.start, str.cur-str.start); |
110 | return(*this); |
111 | } |
112 | |
113 | OutString& operator<<(const char* str) { |
114 | write(str, strlen(str)); |
115 | return(*this); |
116 | } |
117 | |
118 | void write(const char* str, size_t len) { |
119 | if (cur+len > end) |
120 | Realloc(len); |
121 | memcpy(cur, str, len); |
122 | cur = cur + len; |
123 | _ASSERTE(start <= cur && cur <= end); |
124 | } |
125 | |
126 | void swap(OutString& str) { |
127 | char* tmp = start; |
128 | start = str.start; |
129 | str.start = tmp; |
130 | tmp = end; |
131 | end = str.end; |
132 | str.end = tmp; |
133 | tmp = cur; |
134 | cur = str.cur; |
135 | str.cur = tmp; |
136 | _ASSERTE(start <= cur && cur <= end); |
137 | } |
138 | |
139 | void clear() { cur = start; } |
140 | size_t length() const { return(cur-start); } |
141 | |
142 | // return the null terminated string, OutString keeps ownership |
143 | const char* val() const { *cur = 0; return(start); } |
144 | |
145 | // grab string (caller must now delete) OutString is cleared |
146 | char* grab() { char* ret = start; *cur = 0; end = cur = start = 0; return(ret); } |
147 | |
148 | private: |
149 | void Realloc(size_t neededSpace); |
150 | |
151 | char *start; // start of the buffer |
152 | char *end; // points at the last place null terminator can go |
153 | char *cur; // points at a null terminator |
154 | }; |
155 | |
156 | #endif // _OutString_h |
157 | |
158 | |