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
24class OutString {
25public:
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
148private:
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