| 51 | } |
| 52 | |
| 53 | size_t websocket_parser_execute(websocket_parser *parser, const websocket_parser_settings *settings, const char *data, size_t len) { |
| 54 | const char * p; |
| 55 | const char * end = data + len; |
| 56 | size_t frame_offset = 0; |
| 57 | |
| 58 | for(p = data; p != end; p++) { |
| 59 | switch(parser->state) { |
| 60 | case s_start: |
| 61 | parser->offset = 0; |
| 62 | parser->length = 0; |
| 63 | parser->mask_offset = 0; |
| 64 | parser->flags = (websocket_flags) (CC & WS_OP_MASK); |
| 65 | if(CC & (1<<7)) { |
| 66 | parser->flags |= WS_FIN; |
| 67 | } |
| 68 | SET_STATE(s_head); |
| 69 | |
| 70 | frame_offset++; |
| 71 | break; |
| 72 | case s_head: |
| 73 | parser->length = (size_t)CC & 0x7F; |
| 74 | if(CC & 0x80) { |
| 75 | parser->flags |= WS_HAS_MASK; |
| 76 | } |
| 77 | if(parser->length >= 126) { |
| 78 | if(parser->length == 127) { |
| 79 | parser->require = 8; |
| 80 | } else { |
| 81 | parser->require = 2; |
| 82 | } |
| 83 | parser->length = 0; |
| 84 | SET_STATE(s_length); |
| 85 | } else if (parser->flags & WS_HAS_MASK) { |
| 86 | SET_STATE(s_mask); |
| 87 | parser->require = 4; |
| 88 | } else if (parser->length) { |
| 89 | SET_STATE(s_body); |
| 90 | parser->require = parser->length; |
| 91 | NOTIFY_CB(frame_header); |
| 92 | } else { |
| 93 | SET_STATE(s_start); |
| 94 | NOTIFY_CB(frame_header); |
| 95 | NOTIFY_CB(frame_end); |
| 96 | } |
| 97 | |
| 98 | frame_offset++; |
| 99 | break; |
| 100 | case s_length: |
| 101 | while(HAS_DATA() && parser->require) { |
| 102 | parser->length <<= 8; |
| 103 | parser->length |= (unsigned char)CC; |
| 104 | parser->require--; |
| 105 | frame_offset++; |
| 106 | p++; |
| 107 | } |
| 108 | p--; |
| 109 | if(!parser->require) { |
| 110 | if (parser->flags & WS_HAS_MASK) { |