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 }