1 module drocks.sockhandler;
2 
3 //import std.stdio;
4 import std.socket : TcpSocket, InternetAddress, recv;
5 //import std.socket : recv, SocketFlags;
6 
7 public import drocks.exception : ClientException;
8 
9 // Define thread local static buffer
10 private static char[] _line_buf;
11 static this() {
12     _line_buf.reserve(128);
13 }
14 
15 class SockHandler
16 {
17 private:
18     TcpSocket _sock;
19     bool   _opened = false;
20     bool   _valid  = true;
21 
22 public:
23     this(TcpSocket sock)
24     {
25         _opened = true;
26         _sock   = sock;
27     }
28     this()
29     {
30         _opened = false;
31         _sock   = new TcpSocket();
32     }
33 
34     ~this()
35     {
36         this.close();
37     }
38 
39     bool isValid() const
40     {
41         return _opened && _valid && _sock.isAlive();
42     }
43     
44     void close()
45     {
46         if(_opened) {
47             _sock.close();
48             _opened = false;
49         }
50     }
51 
52     void connect(InternetAddress addr)
53     {
54         _opened = true;
55         _sock.connect(addr);
56     }
57     auto send(string req)
58     {
59         return _sock.send(req);
60     }
61 
62     // Receives a Header from socket
63     char[] receiveHeader()
64     {
65         _line_buf.length = 0;
66         // Receive behind "\r\n"
67         for(auto c = getChar(); isValid() && '\r' != c; c = getChar()) {
68             _line_buf ~= c;
69         }
70 
71         // Receive char '\n'
72         if(isValid()) {
73             //_sock.receive(buf);
74             getChar();
75         }
76         
77         return _line_buf;
78     }
79     
80     // Receives a line from socket
81     char[] readLine()
82     {
83         _line_buf.length = 0;
84         // Receive behind '\n'
85         for(auto c = getChar(); isValid() && '\n' != c; c = getChar()) {
86             _line_buf ~= c;
87         }
88 
89         return _line_buf;
90     }
91     
92     // Receives num chars from socket
93     char[] read(size_t num)
94     {
95         _line_buf.length = 0;
96         size_t i = 0;
97         for(auto c = getChar(); i < num && isValid(); ++i, c = getChar()) {
98             _line_buf ~= c;
99         }
100         return _line_buf;
101     }
102 
103     // Receives all data from socket
104     string readAll()
105     {
106         _line_buf.length = 0;
107         string rez = "";
108 
109         while(isValid()) {
110             for(auto c = getChar(); isValid(); c = getChar()) {
111                 _line_buf ~= c;
112             }
113             rez ~= _line_buf;
114         }
115         return rez;
116     }
117 
118     char getChar()
119     {
120         char[1] buf;
121         _valid  = (_sock.receive(buf) != 0UL);
122         //_valid  = recv(_sock.handle(), buf.ptr, 1, cast(int) SocketFlags.NONE) != 0UL;
123         if(!_valid) close();
124         return buf[0];
125     }
126 
127 }