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