mirror of
https://github.com/faye/websocket-driver-ruby.git
synced 2025-11-01 13:59:38 +00:00
95 lines
2.9 KiB
C
95 lines
2.9 KiB
C
#include "parser.h"
|
|
#include "rb_util.h"
|
|
|
|
void Init_websocket_parser();
|
|
|
|
VALUE wsd_WebSocketParser_initialize(VALUE self, VALUE driver, VALUE options);
|
|
VALUE wsd_WebSocketParser_parse(VALUE self, VALUE chunk);
|
|
|
|
void wsd_Driver_on_message(VALUE driver, wsd_Message *message);
|
|
void wsd_Driver_on_frame(VALUE driver, wsd_Frame *frame);
|
|
|
|
static VALUE wsd_RWebSocketParser = Qnil;
|
|
|
|
void Init_websocket_parser()
|
|
{
|
|
wsd_RWebSocketParser = rb_define_class("WebSocketParser", rb_cObject);
|
|
rb_define_method(wsd_RWebSocketParser, "initialize", wsd_WebSocketParser_initialize, 2);
|
|
rb_define_method(wsd_RWebSocketParser, "parse", wsd_WebSocketParser_parse, 1);
|
|
}
|
|
|
|
VALUE wsd_WebSocketParser_initialize(VALUE self, VALUE driver, VALUE options)
|
|
{
|
|
wsd_Observer *observer = NULL;
|
|
VALUE ruby_parser;
|
|
|
|
observer = wsd_Observer_create(
|
|
(void *) driver,
|
|
(wsd_cb_on_message) wsd_Driver_on_message,
|
|
(wsd_cb_on_frame) wsd_Driver_on_frame);
|
|
|
|
if (observer == NULL) return Qnil;
|
|
|
|
wsd_Parser *parser = wsd_Parser_create(observer);
|
|
if (parser == NULL) return Qnil;
|
|
|
|
ruby_parser = Data_Wrap_Struct(rb_cObject, NULL, wsd_Parser_destroy, parser);
|
|
rb_iv_set(self, "@parser", ruby_parser);
|
|
|
|
return Qnil;
|
|
}
|
|
|
|
VALUE wsd_WebSocketParser_parse(VALUE self, VALUE chunk)
|
|
{
|
|
uint64_t length = RSTRING_LEN(chunk);
|
|
char *data = RSTRING_PTR(chunk);
|
|
|
|
wsd_Parser *parser;
|
|
Data_Get_Struct(rb_iv_get(self, "@parser"), wsd_Parser, parser);
|
|
if (parser == NULL) return Qnil;
|
|
|
|
wsd_Parser_parse(parser, length, (uint8_t *)data);
|
|
|
|
return Qnil;
|
|
}
|
|
|
|
|
|
void wsd_Driver_on_message(VALUE driver, wsd_Message *message)
|
|
{
|
|
VALUE opcode = INT2FIX(message->opcode);
|
|
VALUE rsv1 = message->rsv1 ? Qtrue : Qfalse;
|
|
VALUE rsv2 = message->rsv2 ? Qtrue : Qfalse;
|
|
VALUE rsv3 = message->rsv3 ? Qtrue : Qfalse;
|
|
|
|
uint8_t *data = NULL;
|
|
uint64_t copied = 0;
|
|
VALUE string;
|
|
|
|
data = calloc(message->length, sizeof(uint8_t));
|
|
if (data == NULL) return; // TODO signal error back to the parser
|
|
|
|
copied = wsd_Message_copy(message, data);
|
|
string = rb_str_new((char *)data, copied);
|
|
|
|
free(data);
|
|
|
|
VALUE argv[] = { opcode, rsv1, rsv2, rsv3, string };
|
|
wsd_safe_rb_funcall2(driver, rb_intern("emit_message"), 5, argv);
|
|
}
|
|
|
|
void wsd_Driver_on_frame(VALUE driver, wsd_Frame *frame)
|
|
{
|
|
char *msg = NULL;
|
|
|
|
printf("------------------------------------------------------------------------\n");
|
|
printf(" final: %d, rsv: [%d,%d,%d], opcode: %d, masked: %d, length: %" PRIu64 "\n",
|
|
frame->final, frame->rsv1, frame->rsv2, frame->rsv3,
|
|
frame->opcode, frame->masked, frame->length);
|
|
printf("------------------------------------------------------------------------\n");
|
|
|
|
msg = calloc(frame->length + 1, sizeof(char));
|
|
memcpy(msg, frame->payload, frame->length);
|
|
printf("[PAYLOAD] %s\n\n", msg);
|
|
free(msg);
|
|
}
|