TrinityCore
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
G3D::TextOutput Class Reference

#include <TextOutput.h>

Classes

class  Settings
 

Public Member Functions

 TextOutput (const std::string &filename, const Settings &options=Settings())
 
 TextOutput (const Settings &options=Settings())
 
int line () const
 
void commit (bool flush=true)
 
void commitString (std::string &string)
 
void pushIndent ()
 
void popIndent ()
 
std::string commitString ()
 
void writeString (const std::string &string)
 
void writeBoolean (bool b)
 
void writeNumber (double n)
 
void writeNumber (int n)
 
void writeNewline ()
 
void writeNewlines (int numLines)
 
bool deleteSpace ()
 
void writeSymbol (const std::string &string)
 
void writeSymbol (char s)
 
void writeSymbols (const std::string &a, const std::string &b="", const std::string &c="", const std::string &d="", const std::string &e="", const std::string &f="")
 
void __cdecl printf (const char *fmt,...) G3D_CHECK_PRINTF_METHOD_ARGS
 
void __cdecl printf (const std::string fmt,...)
 
void __cdecl vprintf (const char *fmt, va_list argPtr) G3D_CHECK_VPRINTF_METHOD_ARGS
 

Private Member Functions

void setIndentLevel (int i)
 
void setOptions (const Settings &_opt)
 
void convertNewlines (const std::string &in, std::string &out)
 
void wordWrapIndentAppend (const std::string &str)
 
void indentAppend (char c)
 

Private Attributes

bool startingNewLine
 
int currentColumn
 
bool inDQuote
 
std::string filename
 
Array< char > data
 
Settings option
 
int indentLevel
 
int indentSpaces
 
std::string newline
 
int m_currentLine
 

Detailed Description

Convenient formatting of ASCII text written to a file.

The core writeString, writeNumber, and writeSymbol methods map to TextInput's methods. Number and Symbol each print an additional space that is used to separate adjacent tokens.

TextOutput::printf allows arbitrary text to be conveniently dumped en-masse. Use [de]serialize(bool, TextOutput) and other overloads to read/write primitive types in a standardized manner and

When a word-wrap line break occurs, all whitespace between words is replaced with a single newline (the newline may be two characters– see G3D::TextOutput::Options::NewlineStyle). Word wrapping occurs against the number of columns specified by Options::numColumns, minus the current indent level.

Indenting adds the specified number of spaces immediately after a newline. If a newline was followed by spaces in the original string, these are added to the indent spaces. Indenting will indent blank lines and will leave indents after the last newline of a file (if the indent level is non-zero at the end).

Serialization/Marshalling

Text serialization is accomplished using TextOutput by defining the pair of methods:

void serialize(TextOutput& to) const;
void deserialize(TextInput& ti);

See also G3D::TextInput.

BETA API

This API is subject to change in future versions.

Constructor & Destructor Documentation

G3D::TextOutput::TextOutput ( const std::string &  filename,
const Settings options = Settings() 
)
explicit
31  :
32  startingNewLine(true),
33  currentColumn(0),
34  inDQuote(false),
35  filename(fil),
36  indentLevel(0),
37  m_currentLine(0)
38 {
39 
40  setOptions(opt);
41 }
bool inDQuote
Definition: TextOutput.h:139
int m_currentLine
Definition: TextOutput.h:160
void setOptions(const Settings &_opt)
Definition: TextOutput.cpp:56
int indentLevel
Definition: TextOutput.h:149
std::string filename
Definition: TextOutput.h:142
bool startingNewLine
Definition: TextOutput.h:133
int currentColumn
Definition: TextOutput.h:136

+ Here is the call graph for this function:

G3D::TextOutput::TextOutput ( const Settings options = Settings())
explicit

Constructs a text output that can later be commited to a string instead of a file.

19  :
20  startingNewLine(true),
21  currentColumn(0),
22  inDQuote(false),
23  filename(""),
24  indentLevel(0),
25  m_currentLine(0)
26 {
27  setOptions(opt);
28 }
bool inDQuote
Definition: TextOutput.h:139
int m_currentLine
Definition: TextOutput.h:160
void setOptions(const Settings &_opt)
Definition: TextOutput.cpp:56
int indentLevel
Definition: TextOutput.h:149
std::string filename
Definition: TextOutput.h:142
bool startingNewLine
Definition: TextOutput.h:133
int currentColumn
Definition: TextOutput.h:136

+ Here is the call graph for this function:

Member Function Documentation

void G3D::TextOutput::commit ( bool  flush = true)

Commit to the filename specified on the constructor. Not called from the destructor; you must call it yourself.

Parameters
flushIf true (default) the file is ready for reading when the method returns, otherwise the method returns immediately and writes the file in the background.
419  {
420  std::string p = filenamePath(filename);
421  if (! FileSystem::exists(p, false)) {
423  }
424 
425  FILE* f = FileSystem::fopen(filename.c_str(), "wb");
426  debugAssertM(f, "Could not open \"" + filename + "\"");
427  fwrite(data.getCArray(), 1, data.size(), f);
428  if (flush) {
429  fflush(f);
430  }
432 }
T * getCArray()
Definition: Array.h:256
static void fclose(FILE *f)
Definition: FileSystem.h:290
std::string filenamePath(const std::string &filename)
Definition: fileutils.cpp:869
#define debugAssertM(exp, message)
Definition: debugAssert.h:161
static bool exists(const std::string &f, bool trustCache=true, bool caseSensitive=true)
Definition: FileSystem.h:401
int size() const
Definition: Array.h:430
std::string filename
Definition: TextOutput.h:142
Array< char > data
Definition: TextOutput.h:144
static FILE * fopen(const char *filename, const char *mode)
Definition: FileSystem.h:282
static void createDirectory(const std::string &path)
Definition: FileSystem.h:356

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void G3D::TextOutput::commitString ( std::string &  string)

Commits to this string

435  {
436  // Null terminate
437  data.push('\0');
438  out = data.getCArray();
439  data.pop();
440 }
void push(const T &value)
Definition: Array.h:770
T pop(bool shrinkUnderlyingArrayIfNecessary=true)
Definition: Array.h:837
T * getCArray()
Definition: Array.h:256
Array< char > data
Definition: TextOutput.h:144

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

std::string G3D::TextOutput::commitString ( )

Produces a new string that contains the output

443  {
444  std::string str;
445  commitString(str);
446  return str;
447 }
std::string commitString()
Definition: TextOutput.cpp:443
void G3D::TextOutput::convertNewlines ( const std::string &  in,
std::string &  out 
)
private

Converts to the desired newlines. Called from vprintf

193  {
194  // TODO: can be significantly optimized in cases where
195  // single characters are copied in order by walking through
196  // the array and copying substrings as needed.
197 
198  if (option.convertNewlines) {
199  out = "";
200  for (uint32 i = 0; i < in.size(); ++i) {
201  if (in[i] == '\n') {
202  // Unix newline
203  out += newline;
204  } else if ((in[i] == '\r') && (i + 1 < in.size()) && (in[i + 1] == '\n')) {
205  // Windows newline
206  out += newline;
207  ++i;
208  } else {
209  out += in[i];
210  }
211  }
212  } else {
213  out = in;
214  }
215 }
std::string newline
Definition: TextOutput.h:157
Settings option
Definition: TextOutput.h:146
uint32_t uint32
Definition: Define.h:150
bool convertNewlines
Definition: TextOutput.h:99

+ Here is the caller graph for this function:

bool G3D::TextOutput::deleteSpace ( )

If the most recently written character was a space, remove it and return true. Can be called repeatedly to back up over multiple spaces.

182  {
183  if ((currentColumn > 0) && (data.last() == ' ')) {
184  data.popDiscard();
185  --currentColumn;
186  return true;
187  } else {
188  return false;
189  }
190 }
const T & last() const
Definition: Array.h:923
void popDiscard(bool shrinkUnderlyingArrayIfNecessary=false)
Definition: Array.h:846
Array< char > data
Definition: TextOutput.h:144
int currentColumn
Definition: TextOutput.h:136

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void G3D::TextOutput::indentAppend ( char  c)
private

Appends the character to data, indenting whenever a newline is encountered. Called from wordWrapIndentAppend

380  {
381 
382  if (startingNewLine) {
383  for (int j = 0; j < indentSpaces; ++j) {
384  data.push(' ');
385  }
386  startingNewLine = false;
388  }
389 
390  data.push(c);
391 
392  // Don't increment the column count on return character
393  // newline is taken care of below.
394  if (c != '\r') {
395  ++currentColumn;
396  }
397 
398  if (c == '\"') {
399  inDQuote = ! inDQuote;
400  }
401 
402  startingNewLine = (c == '\n');
403  if (startingNewLine) {
404  currentColumn = 0;
405  ++m_currentLine;
406  }
407 }
void push(const T &value)
Definition: Array.h:770
bool inDQuote
Definition: TextOutput.h:139
int m_currentLine
Definition: TextOutput.h:160
int indentSpaces
Definition: TextOutput.h:154
bool startingNewLine
Definition: TextOutput.h:133
Array< char > data
Definition: TextOutput.h:144
int currentColumn
Definition: TextOutput.h:136

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

int G3D::TextOutput::line ( ) const
inline

Returns one plus the number of newlines written since the output was created.

182  {
183  return m_currentLine;
184  }
int m_currentLine
Definition: TextOutput.h:160

+ Here is the caller graph for this function:

void G3D::TextOutput::popIndent ( )
72  {
74 }
int indentLevel
Definition: TextOutput.h:149
void setIndentLevel(int i)
Definition: TextOutput.cpp:44

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void G3D::TextOutput::printf ( const char *  fmt,
  ... 
)

Normal printf conventions. Note that the output will be reformatted for word-wrapping and newlines

174  {
175  va_list argList;
176  va_start(argList, formatString);
177  this->vprintf(formatString, argList);
178  va_end(argList);
179 }
void __cdecl vprintf(const char *fmt, va_list argPtr) G3D_CHECK_VPRINTF_METHOD_ARGS
Definition: TextOutput.cpp:410

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void G3D::TextOutput::printf ( const std::string  fmt,
  ... 
)
166  {
167  va_list argList;
168  va_start(argList, formatString);
169  this->vprintf(formatString.c_str(), argList);
170  va_end(argList);
171 }
void __cdecl vprintf(const char *fmt, va_list argPtr) G3D_CHECK_VPRINTF_METHOD_ARGS
Definition: TextOutput.cpp:410

+ Here is the call graph for this function:

void G3D::TextOutput::pushIndent ( )

Increase indent level by 1

67  {
69 }
int indentLevel
Definition: TextOutput.h:149
void setIndentLevel(int i)
Definition: TextOutput.cpp:44

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void G3D::TextOutput::setIndentLevel ( int  i)
private
44  {
45  indentLevel = i;
46 
47  // If there were more pops than pushes, don't let that take us below 0 indent.
48  // Don't ever indent more than the number of columns.
49  indentSpaces =
51  0,
52  option.numColumns - 1);
53 }
Settings option
Definition: TextOutput.h:146
int spacesPerIndent
Definition: TextOutput.h:88
int numColumns
Definition: TextOutput.h:85
int indentSpaces
Definition: TextOutput.h:154
int indentLevel
Definition: TextOutput.h:149
int iClamp(int val, int low, int hi)
Definition: g3dmath.h:545

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void G3D::TextOutput::setOptions ( const Settings _opt)
private
56  {
57  option = _opt;
58 
60 
62 
64 }
std::string newline
Definition: TextOutput.h:157
NewlineStyle newlineStyle
Definition: TextOutput.h:95
Settings option
Definition: TextOutput.h:146
int numColumns
Definition: TextOutput.h:85
#define debugAssert(exp)
Definition: debugAssert.h:160
int indentLevel
Definition: TextOutput.h:149
void setIndentLevel(int i)
Definition: TextOutput.cpp:44

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void G3D::TextOutput::vprintf ( const char *  fmt,
va_list  argPtr 
)
410  {
411  const std::string& str = vformat(formatString, argPtr);
412 
413  std::string clean;
414  convertNewlines(str, clean);
415  wordWrapIndentAppend(clean);
416 }
std::string vformat(const char *fmt, va_list argPtr) G3D_CHECK_VPRINTF_ARGS
Definition: format.cpp:122
void wordWrapIndentAppend(const std::string &str)
Definition: TextOutput.cpp:232
void convertNewlines(const std::string &in, std::string &out)
Definition: TextOutput.cpp:193

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void G3D::TextOutput::wordWrapIndentAppend ( const std::string &  str)
private

Called from vprintf

232  {
233  // TODO: keep track of the last space character we saw so we don't
234  // have to always search.
235 
237  (currentColumn + (int)str.size() <= option.numColumns)) {
238  // No word-wrapping is needed
239 
240  // Add one character at a time.
241  // TODO: optimize for strings without newlines to add multiple
242  // characters.
243  for (uint32 i = 0; i < str.size(); ++i) {
244  indentAppend(str[i]);
245  }
246  return;
247  }
248 
249  // Number of columns to wrap against
250  int cols = option.numColumns - indentSpaces;
251 
252  // Copy forward until we exceed the column size,
253  // and then back up and try to insert newlines as needed.
254  for (uint32 i = 0; i < str.size(); ++i) {
255 
256  indentAppend(str[i]);
257  if ((str[i] == '\r') && (i + 1 < str.size()) && (str[i + 1] == '\n')) {
258  // \r\n, we need to hit the \n to enter word wrapping.
259  ++i;
260  indentAppend(str[i]);
261  }
262 
263  if (currentColumn >= cols) {
264  debugAssertM(str[i] != '\n' && str[i] != '\r',
265  "Should never enter word-wrapping on a newline character");
266 
267  // True when we're allowed to treat a space as a space.
268  bool unquotedSpace = option.allowWordWrapInsideDoubleQuotes || ! inDQuote;
269 
270  // Cases:
271  //
272  // 1. Currently in a series of spaces that ends with a newline
273  // strip all spaces and let the newline
274  // flow through.
275  //
276  // 2. Currently in a series of spaces that does not end with a newline
277  // strip all spaces and replace them with single newline
278  //
279  // 3. Not in a series of spaces
280  // search backwards for a space, then execute case 2.
281 
282  // Index of most recent space
283  size_t lastSpace = data.size() - 1;
284 
285  // How far back we had to look for a space
286  size_t k = 0;
287  size_t maxLookBackward = currentColumn - indentSpaces;
288 
289  // Search backwards (from current character), looking for a space.
290  while ((k < maxLookBackward) &&
291  (lastSpace > 0) &&
292  (! ((data[(int)lastSpace] == ' ') && unquotedSpace))) {
293  --lastSpace;
294  ++k;
295 
296  if ((data[(int)lastSpace] == '\"') && !option.allowWordWrapInsideDoubleQuotes) {
297  unquotedSpace = ! unquotedSpace;
298  }
299  }
300 
301  if (k == maxLookBackward) {
302  // We couldn't find a series of spaces
303 
305  // Strip the last character we wrote, force a newline,
306  // and replace the last character;
307  data.pop();
308  writeNewline();
309  indentAppend(str[i]);
310  } else {
311  // Must be Settings::WRAP_WITHOUT_BREAKING
312  //
313  // Don't write the newline; we'll come back to
314  // the word wrap code after writing another character
315  }
316  } else {
317  // We found a series of spaces. If they continue
318  // to the new string, strip spaces off both. Otherwise
319  // strip spaces from data only and insert a newline.
320 
321  // Find the start of the spaces. firstSpace is the index of the
322  // first non-space, looking backwards from lastSpace.
323  size_t firstSpace = lastSpace;
324  while ((k < maxLookBackward) &&
325  (firstSpace > 0) &&
326  (data[(int)firstSpace] == ' ')) {
327  --firstSpace;
328  ++k;
329  }
330 
331  if (k == maxLookBackward) {
332  ++firstSpace;
333  }
334 
335  if (lastSpace == (uint32)data.size() - 1) {
336  // Spaces continued up to the new string
337  data.resize(firstSpace + 1);
338  writeNewline();
339 
340  // Delete the spaces from the new string
341  while ((i < str.size() - 1) && (str[i + 1] == ' ')) {
342  ++i;
343  }
344  } else {
345  // Spaces were somewhere in the middle of the old string.
346  // replace them with a newline.
347 
348  // Copy over the characters that should be saved
349  Array<char> temp;
350  for (size_t j = lastSpace + 1; j < (uint32)data.size(); ++j) {
351  char c = data[(int)j];
352 
353  if (c == '\"') {
354  // Undo changes to quoting (they will be re-done
355  // when we paste these characters back on).
356  inDQuote = !inDQuote;
357  }
358  temp.append(c);
359  }
360 
361  // Remove those characters and replace with a newline.
362  data.resize(firstSpace + 1);
363  writeNewline();
364 
365  // Write them back
366  for (size_t j = 0; j < (uint32)temp.size(); ++j) {
367  indentAppend(temp[(int)j]);
368  }
369 
370  // We are now free to continue adding from the
371  // new string, which may or may not begin with spaces.
372 
373  } // if spaces included new string
374  } // if hit indent
375  } // if line exceeded
376  } // iterate over str
377 }
bool allowWordWrapInsideDoubleQuotes
Definition: TextOutput.h:82
T pop(bool shrinkUnderlyingArrayIfNecessary=true)
Definition: Array.h:837
bool inDQuote
Definition: TextOutput.h:139
void resize(size_t n, bool shrinkIfNecessary=true)
Definition: Array.h:490
Settings option
Definition: TextOutput.h:146
#define debugAssertM(exp, message)
Definition: debugAssert.h:161
WordWrapMode wordWrap
Definition: TextOutput.h:78
int numColumns
Definition: TextOutput.h:85
int indentSpaces
Definition: TextOutput.h:154
uint32_t uint32
Definition: Define.h:150
int size() const
Definition: Array.h:430
void writeNewline()
Definition: TextOutput.cpp:218
Array< char > data
Definition: TextOutput.h:144
void indentAppend(char c)
Definition: TextOutput.cpp:380
Definition: TextOutput.h:75
uint32_t uint32
Definition: g3dmath.h:168
Definition: TextOutput.h:75
int currentColumn
Definition: TextOutput.h:136

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void G3D::TextOutput::writeBoolean ( bool  b)
125  {
126  this->printf("%s ", b ? option.trueSymbol.c_str() : option.falseSymbol.c_str());
127 }
Settings option
Definition: TextOutput.h:146
std::string trueSymbol
Definition: TextOutput.h:102
std::string falseSymbol
Definition: TextOutput.h:105
void __cdecl printf(const char *fmt,...) G3D_CHECK_PRINTF_METHOD_ARGS
Definition: TextOutput.cpp:174

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void G3D::TextOutput::writeNewline ( )
218  {
219  for (uint32 i = 0; i < newline.size(); ++i) {
220  indentAppend(newline[i]);
221  }
222 }
std::string newline
Definition: TextOutput.h:157
uint32_t uint32
Definition: Define.h:150
void indentAppend(char c)
Definition: TextOutput.cpp:380

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void G3D::TextOutput::writeNewlines ( int  numLines)
225  {
226  for (int i = 0; i < numLines; ++i) {
227  writeNewline();
228  }
229 }
void writeNewline()
Definition: TextOutput.cpp:218

+ Here is the call graph for this function:

void G3D::TextOutput::writeNumber ( double  n)
129  {
130  this->printf("%g ", n);
131 }
void __cdecl printf(const char *fmt,...) G3D_CHECK_PRINTF_METHOD_ARGS
Definition: TextOutput.cpp:174

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void G3D::TextOutput::writeNumber ( int  n)
134  {
135  this->printf("%d ", n);
136 }
void __cdecl printf(const char *fmt,...) G3D_CHECK_PRINTF_METHOD_ARGS
Definition: TextOutput.cpp:174

+ Here is the call graph for this function:

void G3D::TextOutput::writeString ( const std::string &  string)

Writes a quoted string. Special characters in the string (e.g., \, \t, \n) are escaped so that TextInput will produce the identical string on reading.

112  {
113  // Never break a line in a string
115 
118  }
119  // Convert special characters to escape sequences
120  this->printf("\"%s\"", escape(string).c_str());
121  option.wordWrap = old;
122 }
bool allowWordWrapInsideDoubleQuotes
Definition: TextOutput.h:82
Settings option
Definition: TextOutput.h:146
WordWrapMode
Definition: TextOutput.h:75
WordWrapMode wordWrap
Definition: TextOutput.h:78
static std::string escape(const std::string &string)
Definition: TextOutput.cpp:77
Definition: TextOutput.h:75
void __cdecl printf(const char *fmt,...) G3D_CHECK_PRINTF_METHOD_ARGS
Definition: TextOutput.cpp:174

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void G3D::TextOutput::writeSymbol ( const std::string &  string)

The symbol is written without quotes. Symbols are required to begin with a letter or underscore and contain only letters, underscores, and numbers or be a C++ symbol (e.g. "{", "(", "++", etc.) so that they may be properly parsed by TextInput::readSymbol. Symbols are printed with a trailing space.

139  {
140  if (string.size() > 0) {
141  this->printf("%s ", string.c_str());
142  }
143 }
void __cdecl printf(const char *fmt,...) G3D_CHECK_PRINTF_METHOD_ARGS
Definition: TextOutput.cpp:174

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void G3D::TextOutput::writeSymbol ( char  s)
145  {
146  this->printf("%c ", c);
147 }
void __cdecl printf(const char *fmt,...) G3D_CHECK_PRINTF_METHOD_ARGS
Definition: TextOutput.cpp:174

+ Here is the call graph for this function:

void G3D::TextOutput::writeSymbols ( const std::string &  a,
const std::string &  b = "",
const std::string &  c = "",
const std::string &  d = "",
const std::string &  e = "",
const std::string &  f = "" 
)

Convenient idiom for writing multiple symbols in a row, e.g. writeSymbols("name", "="); The empty symbols are not written.

155  {
156 
157  writeSymbol(a);
158  writeSymbol(b);
159  writeSymbol(c);
160  writeSymbol(d);
161  writeSymbol(e);
162  writeSymbol(f);
163 }
void writeSymbol(const std::string &string)
Definition: TextOutput.cpp:139

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

Member Data Documentation

int G3D::TextOutput::currentColumn
private

Number of characters at the end of the buffer since the last newline

Array<char> G3D::TextOutput::data
private
std::string G3D::TextOutput::filename
private

Empty if there is none

int G3D::TextOutput::indentLevel
private

Number of indents to prepend before each line. Always set using setIndentLevel.

int G3D::TextOutput::indentSpaces
private

Actual number of spaces to indent.

bool G3D::TextOutput::inDQuote
private

True if we have seen an open " and no close ".

int G3D::TextOutput::m_currentLine
private

Starts at 1

std::string G3D::TextOutput::newline
private

the newline character(s)

Settings G3D::TextOutput::option
private
bool G3D::TextOutput::startingNewLine
private

Used by indentAndAppend to tell when we are writing the first character of a new line.

So that push/popIndent work correctly, we cannot indent immediately after writing a newline. Instead we must indent on writing the first character after that newline.


The documentation for this class was generated from the following files: