1 ///////////////////////////////////////////////////////////////////////////
2 //
3 // FILE: textbuf.cpp
4 // TextBuffer class methods
5 //
6 // Part of: Scid (Shane's Chess Information Database)
7 // Version: 2.7
8 //
9 // Notice: Copyright (c) 1999-2001 Shane Hudson. All rights reserved.
10 //
11 // Author: Shane Hudson (sgh@users.sourceforge.net)
12 //
13 ///////////////////////////////////////////////////////////////////////////
14
15 #include "textbuf.h"
16 #include "misc.h"
17
18 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
19 //### TextBuffer::Init(): Initialise the textbuffer.
20 void
Init(void)21 TextBuffer::Init (void)
22 {
23 BufferSize = Column = IndentColumn = LineCount = ByteCount = 0;
24 LineIsEmpty = 1;
25 Buffer = Current = NULL;
26 WrapColumn = 80;
27 ConvertNewlines = true;
28 HasTranslations = false;
29 PausedTranslations = false;
30 }
31
32 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
33 //### TextBuffer::Free(): Free the TextBuffer.
34 void
Free(void)35 TextBuffer::Free (void)
36 {
37 if (Buffer != NULL) {
38 #ifdef WINCE
39 my_Tcl_Free( Buffer);
40 #else
41 delete[] Buffer;
42 #endif
43 Buffer = NULL;
44 BufferSize = 0;
45 }
46 }
47
48 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
49 //### TextBuffer::Empty(): Empty the TextBuffer.
50 void
Empty(void)51 TextBuffer::Empty (void)
52 {
53 ASSERT(Buffer != NULL);
54 ByteCount = Column = LineCount = 0; LineIsEmpty = 1;
55 Current = Buffer;
56 *Current = 0;
57 ConvertNewlines = true;
58 HasTranslations = false;
59 }
60
61 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
62 // TextBuffer::AddTranslation():
63 // Adds a translation for a character.
64 // The translation string will be printed in place of that character.
65 void
AddTranslation(char ch,const char * str)66 TextBuffer::AddTranslation (char ch, const char * str)
67 {
68 if (! HasTranslations) {
69 HasTranslations = true;
70 for (uint i=0; i < 256; i++) {
71 Translation [i] = NULL;
72 }
73 }
74 Translation [(byte) ch] = str;
75 }
76
77 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
78 //### TextBuffer::SetBufferSize(): Set the buffer size.
79 void
SetBufferSize(uint length)80 TextBuffer::SetBufferSize (uint length)
81 {
82 #ifdef WINCE
83 if (Buffer != NULL) { my_Tcl_Free( Buffer); }
84 Buffer = my_Tcl_Alloc(sizeof(char[length]));
85 #else
86 if (Buffer != NULL) { delete[] Buffer; }
87 Buffer = new char[length];
88 #endif
89 BufferSize = length;
90 ByteCount = Column = LineCount = 0; LineIsEmpty = 1;
91 Current = Buffer;
92 *Current = 0;
93 }
94
95 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
96 //### TextBuffer::NewLine(): Add a newline.
97 errorT
NewLine()98 TextBuffer::NewLine ()
99 {
100 ASSERT (Current != NULL);
101 if (ByteCount >= BufferSize) { return ERROR_BufferFull; }
102 *Current++ = '\n';
103 LineCount++; ByteCount++; LineIsEmpty = 1;
104 Column = 0;
105 while (Column < IndentColumn) {
106 if (ByteCount >= BufferSize) { return ERROR_BufferFull; }
107 *Current++ = ' '; Column++; ByteCount++;
108 }
109 *Current = 0;
110 return OK;
111 }
112
113 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
114 //### TextBuffer::Indent(): Indent to the current Indentation level..
115 errorT
Indent()116 TextBuffer::Indent ()
117 {
118 ASSERT (Current != NULL);
119 if (!LineIsEmpty) {
120 return NewLine();
121 } else {
122 while (Column < IndentColumn) {
123 if (ByteCount >= BufferSize) { return ERROR_BufferFull; }
124 *Current++ = ' '; Column++; ByteCount++;
125 }
126 *Current = 0;
127 }
128 return OK;
129 }
130
131 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
132 //### TextBuffer::PrintLine(): Print a string then newline. Does not
133 // check for the line going past WrapColumn.
134 errorT
PrintLine(const char * str)135 TextBuffer::PrintLine (const char * str)
136 {
137 ASSERT(Current != NULL);
138 while (*str != 0) {
139 if (ByteCount > BufferSize) { return ERROR_BufferFull; }
140 AddChar (*str);
141 str++;
142 }
143 return NewLine();
144 }
145
146 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
147 //### TextBuffer::PrintWord(): Prints a word, wrapping if necessary.
148 // It does NOT add a space, since that is left to the caller to
149 // provide in the string.
150 errorT
PrintWord(const char * str)151 TextBuffer::PrintWord (const char * str)
152 {
153 ASSERT(Current != NULL);
154 uint length = strLength (str);
155 if (Column + length >= WrapColumn) { NewLine(); }
156 if (ByteCount + length >= BufferSize) { return ERROR_BufferFull; }
157 while (*str != 0) {
158 char ch = *str;
159 AddChar (ch);
160 str++;
161 Column++;
162 }
163 *Current = 0; // add trailing end-of-string to buffer
164 LineIsEmpty = 0;
165 return OK;
166 }
167
168 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
169 //### TextBuffer::PrintSpace(): Prints a space OR a newline character,
170 // but not both.
171 errorT
PrintSpace(void)172 TextBuffer::PrintSpace (void)
173 {
174 if (ByteCount + 1 >= BufferSize) { return ERROR_BufferFull; }
175 if (Column + 1 >= WrapColumn) {
176 NewLine();
177 } else {
178 *Current = ' '; Current++; ByteCount++; Column++; LineIsEmpty = 0;
179 }
180 return OK;
181 }
182
183 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
184 //### TextBuffer::PrintChar(): prints a single char, adding a newline
185 // first if necessary.
186 errorT
PrintChar(char b)187 TextBuffer::PrintChar (char b)
188 {
189 if (Column + 1 >= WrapColumn) { NewLine(); }
190 if (ByteCount + 1 >= BufferSize) { return ERROR_BufferFull; }
191 AddChar (b);
192 Column++; LineIsEmpty = 0;
193 return OK;
194 }
195
196 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
197 //### TextBuffer::PrintString(): Print a string, wrapping at spaces.
198 // Also converts newlines in the string into spaces.
199 errorT
PrintString(const char * str)200 TextBuffer::PrintString (const char * str)
201 {
202 errorT err;
203 char currentWord[1024]; // should be long enough for a word
204 while (*str != 0) {
205 char * b = currentWord;
206 *b = 0;
207 // get next word and print it:
208 while (*str != ' ' && *str != '\n' && *str != '\0') {
209 *b = *str; b++; str++;
210 }
211 // end of word/line/text reached
212 *b = 0;
213 err = PrintWord (currentWord);
214 if (err != OK) { return err; }
215 if (*str == 0) { return OK; }
216 if (*str == '\n' && !ConvertNewlines) {
217 err = NewLine();
218 } else {
219 err = PrintSpace();
220 }
221 if (err != OK) { return err; }
222 str++;
223 }
224 return OK;
225 }
226
227 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
228 //### TextBuffer::PrintInt(): Print a decimal number followed by string
229 // as a word (so it appends a space at the end and wraps if
230 // necessary).
231 errorT
PrintInt(uint i,const char * str)232 TextBuffer::PrintInt (uint i, const char * str)
233 {
234 char temp[255];
235 sprintf(temp, "%d%s", i, str);
236 return PrintWord(temp);
237 }
238
239 ///////////////////////////////////////////////////////////////////////////
240 // EOF: textbuf.cpp
241 ///////////////////////////////////////////////////////////////////////////
242