1 module libs.marshal.text_marshaller; 2 3 package interface ITextMarshalerStorageStrategy 4 { 5 package: 6 string GetBuffer(); 7 void ClearBuffer(); 8 9 void AddText(string text); 10 void AddLine(string text); 11 12 void SetIndentation(uint value); 13 void IncrmentIndentation(); 14 void IncreaseIndentation(uint value); 15 void DecrementIndentation(); 16 void DecreaseIndentation(uint value); 17 18 void SetIndentationString(string value); 19 void SetNewLineString(string value); 20 } 21 22 package class TextMarshallerStorageStrategy : ITextMarshalerStorageStrategy 23 { 24 package: 25 final string GetBuffer() 26 { 27 return m_buffer.idup; 28 } 29 30 final void ClearBuffer() 31 { 32 m_buffer = []; 33 m_indententation_amounts = []; 34 } 35 36 final void AddText(string text) 37 { 38 m_buffer ~= text; 39 } 40 41 final void AddLine(string text) 42 { 43 m_buffer ~= repeat_string(m_indentation_string, m_current_indentation_count) ~ text ~ m_newline_string; 44 } 45 46 final void SetIndentation(uint value) 47 { 48 m_current_indentation_count = value; 49 m_indententation_amounts = []; 50 } 51 52 final void IncrementIndentation() 53 { 54 ++m_current_indentation_count; 55 m_indententation_amounts ~= 1; 56 } 57 58 final void IncreaseIndentation(uint value) 59 { 60 m_current_indentation_count += value; 61 m_indententation_amounts ~= value; 62 } 63 64 final void DecrementIndentation() 65 { 66 --m_current_indentation_count; 67 m_indententation_amounts ~= -1; 68 } 69 70 final void DecreaseIndentation(uint value) 71 { 72 m_current_indentation_count -= value; 73 m_indententation_amounts ~= -value; 74 } 75 76 final void UndoLastIndentation() 77 { 78 if (m_indententation_amounts.length > 0) 79 { 80 m_current_indentation_count -= m_indententation_amounts[$-1]; 81 m_indententation_amounts = m_indententation_amounts[0 .. $-1]; 82 } 83 } 84 85 final void SetIndentationString(string value) 86 { 87 m_indentation_string = value; 88 } 89 90 final void SetNewLineString(string value) 91 { 92 m_newline_string = value; 93 } 94 95 private: 96 static final pure string repeat_string(string string_to_repeat, int repetitions) 97 { 98 char[] retval; 99 retval.length = string_to_repeat.length * repetitions; 100 if (string_to_repeat == "") return ""; 101 for (int i = 0; i < repetitions; ++i) 102 { 103 retval[i*string_to_repeat.length .. (i+1)*string_to_repeat.length] = string_to_repeat; 104 } 105 return retval.idup; 106 } 107 108 int[] m_indententation_amounts = []; 109 char[] m_buffer; 110 uint m_current_indentation_count = 0; 111 string m_indentation_string = "\t"; 112 string m_newline_string = "\r\n"; 113 114 unittest { 115 assert(repeat_string("123", 3) == "123123123"); 116 assert(repeat_string("", 123456) == ""); 117 assert(repeat_string("a", 10) == "aaaaaaaaaa"); 118 assert(repeat_string("a", 0) == ""); 119 120 TextMarshallerStorageStrategy tm = new TextMarshallerStorageStrategy; 121 tm.AddLine("<a>"); 122 tm.IncrementIndentation(); 123 tm.AddLine("<b>test</b>"); 124 tm.DecrementIndentation(); 125 tm.AddLine("</a>"); 126 127 assert(tm.GetBuffer() == "<a>\r\n\t<b>test</b>\r\n</a>\r\n"); 128 129 tm.ClearBuffer(); 130 131 assert(tm.GetBuffer() == ""); 132 133 tm.IncreaseIndentation(10); 134 tm.IncreaseIndentation(5); 135 assert(tm.m_current_indentation_count == 15); 136 tm.UndoLastIndentation(); 137 assert(tm.m_current_indentation_count == 10); 138 tm.IncrementIndentation(); 139 assert(tm.m_current_indentation_count == 11); 140 tm.UndoLastIndentation(); 141 tm.UndoLastIndentation(); 142 assert(tm.m_current_indentation_count == 0); 143 144 //Can call this when there are no undos left and it doesn't crash 145 tm.UndoLastIndentation(); 146 tm.UndoLastIndentation(); 147 tm.UndoLastIndentation(); 148 149 150 151 } 152 }