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     bool isValid() const
35     {
36         return _opened && _valid && _sock.isAlive();
37     }
38     
39     void close()
40     {
41         if(_opened && _sock !is null && _sock.isAlive()) {
42             _sock.close();
43             _opened = false;
44         }
45     }
46 
47     void connect(InternetAddress addr)
48     {
49         _opened = true;
50         _sock.connect(addr);
51     }
52     auto send(string req)
53     {
54         return _sock.send(req);
55     }
56 
57     // Receives a Header from socket
58     char[] receiveHeader()
59     {
60         _line_buf.length = 0;
61         // Receive behind "\r\n"
62         for(auto c = getChar(); isValid() && '\r' != c; c = getChar()) {
63             _line_buf ~= c;
64         }
65 
66         // Receive char '\n'
67         if(isValid()) {
68             //_sock.receive(buf);
69             getChar();
70         }
71         
72         return _line_buf;
73     }
74     
75     // Receives a line from socket
76     char[] readLine()
77     {
78         _line_buf.length = 0;
79         // Receive behind '\n'
80         for(auto c = getChar(); isValid() && '\n' != c; c = getChar()) {
81             _line_buf ~= c;
82         }
83 
84         return _line_buf;
85     }
86     
87     // Receives num chars from socket
88     char[] read(size_t num)
89     {
90         _line_buf.length = 0;
91         size_t i = 0;
92         for(auto c = getChar(); i < num && isValid(); ++i, c = getChar()) {
93             _line_buf ~= c;
94         }
95         return _line_buf;
96     }
97 
98     // Receives all data from socket
99     string readAll()
100     {
101         _line_buf.length = 0;
102         string rez = "";
103 
104         while(isValid()) {
105             for(auto c = getChar(); isValid(); c = getChar()) {
106                 _line_buf ~= c;
107             }
108             rez ~= _line_buf;
109         }
110         return rez;
111     }
112 
113     char getChar()
114     {
115         char[1] buf;
116         _valid  = (_sock.receive(buf) != 0UL);
117         //_valid  = recv(_sock.handle(), buf.ptr, 1, cast(int) SocketFlags.NONE) != 0UL;
118         if(!_valid) close();
119         return buf[0];
120     }
121 
122 }