1 module libs.marshal.text_demarshaller;
2 
3 import std.conv, std.algorithm;
4 import std.stdio;
5 
6 package interface ITextDemarshalerStorageStrategy 
7 {
8 package:
9 	string GetBuffer();
10 	void SetText(const(char)[] dat);
11 
12 	void Expect(string text);
13 	int  ChompWhitespace();
14 	void ReadValAndExpect(T)(out T val, string expect);
15 
16     void SetNewLineString(string value);
17 }
18 
19 public class InvalidFormattingException : Exception
20 {
21 	this(string s) { super(s); }
22 }
23 
24 package class TextDemarshallerStorageStrategy : ITextDemarshalerStorageStrategy
25 {
26 package:
27 	this() {}
28 
29 	this(string data)
30 	{
31 		SetText(data);
32 	}
33 
34 	final string GetBuffer()
35 	{
36 		return m_buffer.idup;
37 	}
38 	
39 	final void SetText(const(char)[] data)
40 	{
41 		m_buffer = data.dup;
42 		m_cursor = 0;
43 	} 
44 	
45 	final void Expect(string text)
46 	{
47 		if (m_buffer[m_cursor .. m_cursor + text.length] == text)
48 		{
49 			m_cursor += text.length;
50 		}
51 		else
52 		{
53 			throw new InvalidFormattingException("In Expect");
54 		}
55 	}
56 	
57 	final int ChompWhitespace()
58 	{
59 		int chars_chomped = 0;
60 		//TODO: more compact code for this?
61 		while (m_cursor + chars_chomped < m_buffer.length &&
62 			   (m_buffer[m_cursor + chars_chomped] == '\t' ||
63 			    m_buffer[m_cursor + chars_chomped] == ' '  ||
64 			    m_buffer[m_cursor + chars_chomped] == '\r' ||
65 			    m_buffer[m_cursor + chars_chomped] == '\n'))
66 		{
67 			++chars_chomped;
68 		}
69 		m_cursor += chars_chomped;
70 		return chars_chomped;
71 	}
72 	
73 	final void ReadValAndExpect(T)(out T val, string expect)
74 	{
75 		auto pos = find(m_buffer[m_cursor .. $], expect);
76 		if (pos != m_buffer[m_cursor .. $])
77 		{
78 			int len = &pos[0] - &m_buffer[m_cursor];
79 			val = to!T(m_buffer[m_cursor .. m_cursor + len]);
80 			m_cursor += len + expect.length;
81 		}
82 		else
83 		{
84 			throw new InvalidFormattingException("");
85 		}
86 	}
87 	
88     final void SetNewLineString(string value)
89 	{
90 		m_newline_string = value;
91 	}
92 	
93 private:
94 
95 	char[] m_buffer;
96 	string m_newline_string = "\r\n";
97 	int m_cursor = 0;
98 	
99 	unittest {
100 		TextDemarshallerStorageStrategy tm = new TextDemarshallerStorageStrategy;
101 		tm.SetText("   \t<a>66</a>\r\n");
102 
103 		assert(tm.ChompWhitespace() == 4); 
104 
105 		tm.Expect("<a>");
106 		
107 		int result;
108 		
109 		tm.ReadValAndExpect(result, "</a>");
110 		assert(result == 66);
111 
112 		tm.Expect("\r\n");
113 		//assert(tm.ChompWhitespace() == 2);
114 
115 	}
116 }