TextGenerator.cs 2.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. // Protocol Buffers - Google's data interchange format
  2. // Copyright 2008 Google Inc.
  3. // http://code.google.com/p/protobuf/
  4. //
  5. // Licensed under the Apache License, Version 2.0 (the "License");
  6. // you may not use this file except in compliance with the License.
  7. // You may obtain a copy of the License at
  8. //
  9. // http://www.apache.org/licenses/LICENSE-2.0
  10. //
  11. // Unless required by applicable law or agreed to in writing, software
  12. // distributed under the License is distributed on an "AS IS" BASIS,
  13. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. // See the License for the specific language governing permissions and
  15. // limitations under the License.
  16. using System;
  17. using System.IO;
  18. using System.Text;
  19. namespace Google.ProtocolBuffers {
  20. /// <summary>
  21. /// Helper class to control indentation
  22. /// </summary>
  23. internal sealed class TextGenerator {
  24. /// <summary>
  25. /// Writer to write formatted text to.
  26. /// </summary>
  27. private readonly TextWriter writer;
  28. /// <summary>
  29. /// Keeps track of whether the next piece of text should be indented
  30. /// </summary>
  31. bool atStartOfLine = true;
  32. /// <summary>
  33. /// Keeps track of the current level of indentation
  34. /// </summary>
  35. readonly StringBuilder indent = new StringBuilder();
  36. /// <summary>
  37. /// Creates a generator writing to the given writer.
  38. /// </summary>
  39. internal TextGenerator(TextWriter writer) {
  40. this.writer = writer;
  41. }
  42. /// <summary>
  43. /// Indents text by two spaces. After calling Indent(), two spaces
  44. /// will be inserted at the beginning of each line of text. Indent() may
  45. /// be called multiple times to produce deeper indents.
  46. /// </summary>
  47. internal void Indent() {
  48. indent.Append(" ");
  49. }
  50. /// <summary>
  51. /// Reduces the current indent level by two spaces.
  52. /// </summary>
  53. internal void Outdent() {
  54. if (indent.Length == 0) {
  55. throw new InvalidOperationException("Too many calls to Outdent()");
  56. }
  57. indent.Length -= 2;
  58. }
  59. /// <summary>
  60. /// Prints the given text to the output stream, indenting at line boundaries.
  61. /// </summary>
  62. /// <param name="text"></param>
  63. public void Print(string text) {
  64. int pos = 0;
  65. for (int i = 0; i < text.Length; i++) {
  66. if (text[i] == '\n') {
  67. // TODO(jonskeet): Use Environment.NewLine?
  68. Write(text.Substring(pos, i - pos + 1));
  69. pos = i + 1;
  70. atStartOfLine = true;
  71. }
  72. }
  73. Write(text.Substring(pos));
  74. }
  75. private void Write(string data) {
  76. if (data.Length == 0) {
  77. return;
  78. }
  79. if (atStartOfLine) {
  80. atStartOfLine = false;
  81. writer.Write(indent);
  82. }
  83. writer.Write(data);
  84. }
  85. }
  86. }