TextGenerator.cs 2.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. using System;
  2. using System.Collections.Generic;
  3. using System.IO;
  4. using System.Text;
  5. namespace Google.ProtocolBuffers {
  6. /// <summary>
  7. /// Helper class to control indentation
  8. /// </summary>
  9. internal class TextGenerator {
  10. /// <summary>
  11. /// Writer to write formatted text to.
  12. /// </summary>
  13. private readonly TextWriter writer;
  14. /// <summary>
  15. /// Keeps track of whether the next piece of text should be indented
  16. /// </summary>
  17. bool atStartOfLine = true;
  18. /// <summary>
  19. /// Keeps track of the current level of indentation
  20. /// </summary>
  21. readonly StringBuilder indent = new StringBuilder();
  22. /// <summary>
  23. /// Creates a generator writing to the given writer.
  24. /// </summary>
  25. internal TextGenerator(TextWriter writer) {
  26. this.writer = writer;
  27. }
  28. /// <summary>
  29. /// Indents text by two spaces. After calling Indent(), two spaces
  30. /// will be inserted at the beginning of each line of text. Indent() may
  31. /// be called multiple times to produce deeper indents.
  32. /// </summary>
  33. internal void Indent() {
  34. indent.Append(" ");
  35. }
  36. /// <summary>
  37. /// Reduces the current indent level by two spaces.
  38. /// </summary>
  39. internal void Outdent() {
  40. if (indent.Length == 0) {
  41. throw new InvalidOperationException("Too many calls to Outdent()");
  42. }
  43. indent.Length -= 2;
  44. }
  45. /// <summary>
  46. /// Prints the given text to the output stream, indenting at line boundaries.
  47. /// </summary>
  48. /// <param name="text"></param>
  49. public void Print(string text) {
  50. int pos = 0;
  51. for (int i = 0; i < text.Length; i++) {
  52. if (text[i] == '\n') {
  53. // TODO(jonskeet): Use Environment.NewLine?
  54. Write(text.Substring(pos, i - pos + 1));
  55. pos = i + 1;
  56. atStartOfLine = true;
  57. }
  58. }
  59. Write(text.Substring(pos));
  60. }
  61. private void Write(string data) {
  62. if (atStartOfLine) {
  63. atStartOfLine = false;
  64. writer.Write(indent);
  65. }
  66. writer.Write(data);
  67. }
  68. }
  69. }