1 module hunt.imf.protocol.parser;
2 
3 import hunt.imf.protocol.packet;
4 
5 import std.bitmanip;
6 import std.stdint;
7 
8 class Parser
9 {
10     ubyte[Packet.HEADERLEN]             headerbuffer;
11     int32_t                             headerlen = 0;
12 
13     int32_t                             message_data_len;
14     ubyte[]                             message_data;
15     
16    
17 
18     ///
19     Packet[] consume(byte[] buffer)
20     {
21         Packet[] result;
22         size_t length = buffer.length;
23         size_t index = 0;
24         size_t used;
25         while(index < length)
26         {
27             /// in header.
28             size_t left = length - index;
29             if(headerlen < Packet.HEADERLEN)
30             { 
31                 if(left >= Packet.HEADERLEN - headerlen)
32                 {
33                     used = Packet.HEADERLEN - headerlen;
34                     for(size_t i = 0 ; i < used ; i++)
35                         headerbuffer[headerlen + i] = buffer[index + i];
36                     index += used;
37                     headerlen += used;
38                     
39                     message_data_len = bigEndianToNative!int32_t(headerbuffer[16 .. 20]);
40                     message_data.length = 0;
41                     
42                     if(message_data_len == 0)
43                     {
44                         long message_id = bigEndianToNative!long(headerbuffer[8 .. 16]);
45                         result ~= new Packet(message_id);
46                         headerlen = 0;
47                     }
48                     
49                 }
50                 else
51                 {
52                     for(size_t i = 0 ; i < left ; i++)
53                         headerbuffer[headerlen + i] = buffer[index + i];
54                     index += left;
55                     headerlen += left;
56                 }
57             }
58             else
59             {
60                 
61                 if( left >= message_data_len - message_data.length)
62                 {
63                     long message_id = bigEndianToNative!long(headerbuffer[8 .. 16]);
64                     used = message_data_len - message_data.length;
65                     message_data ~= buffer[index .. index + used];
66                     result ~= new Packet(message_id , message_data);
67                     headerlen = 0;
68                     index += used;
69                 }
70                 else
71                 {
72                     message_data ~= buffer[index .. index + left];
73                     index += left;
74                 }
75             }
76         }
77         return result;
78     }
79 
80 }