static DskIOResult dsk_memory_sink_write_buffer (DskOctetSink *sink, DskBuffer *buffer, DskError **error) { DskMemorySink *msink = DSK_MEMORY_SINK (sink); unsigned max_xfer = msink->max_buffer_size - msink->buffer.size; DSK_UNUSED (error); if (msink->buffer.size >= msink->max_buffer_size) return DSK_IO_RESULT_AGAIN; dsk_buffer_transfer (&msink->buffer, buffer, max_xfer); dsk_hook_set_idle_notify (&msink->buffer_nonempty, DSK_TRUE); return DSK_IO_RESULT_SUCCESS; }
static DskIOResult dsk_memory_sink_write (DskOctetSink *sink, unsigned max_len, const void *data_out, unsigned *n_written_out, DskError **error) { DskMemorySink *msink = DSK_MEMORY_SINK (sink); DSK_UNUSED (error); if (msink->buffer.size >= msink->max_buffer_size) return DSK_IO_RESULT_AGAIN; if (msink->buffer.size + max_len <= msink->max_buffer_size) *n_written_out = max_len; else *n_written_out = msink->max_buffer_size - msink->buffer.size; dsk_buffer_append (&msink->buffer, *n_written_out, data_out); dsk_hook_set_idle_notify (&msink->buffer_nonempty, DSK_TRUE); return DSK_IO_RESULT_SUCCESS; }
void dsk_memory_sink_drained (DskMemorySink *sink) { if (sink->buffer.size == 0) dsk_hook_set_idle_notify (&sink->buffer_nonempty, DSK_FALSE); }
static void dsk_memory_sink_init (DskMemorySink *sink) { dsk_hook_init (&sink->buffer_nonempty, sink); dsk_hook_set_idle_notify (&sink->base_instance.writable_hook, DSK_TRUE); }
void update_hooks_with_buffer (DskWebsocket *websocket) { uint8_t header[9]; uint64_t len; if (websocket->is_shutdown || websocket->is_deferred_shutdown) return; restart_processing: if (websocket->to_discard > 0) { if (websocket->to_discard > websocket->incoming.size) { websocket->to_discard -= websocket->incoming.size; dsk_buffer_reset (&websocket->incoming); goto unset_packet_readable; } else { dsk_buffer_discard (&websocket->incoming, websocket->to_discard); websocket->to_discard = 0; goto restart_processing; } } if (websocket->incoming.size < 9) goto unset_packet_readable; dsk_buffer_peek (&websocket->incoming, 9, header); len = dsk_uint64be_parse (header + 1); if (len > websocket->max_length) { switch (websocket->too_long_mode) { case DSK_WEBSOCKET_MODE_DROP: websocket->to_discard -= len + 9; goto restart_processing; case DSK_WEBSOCKET_MODE_RETURN_ERROR: goto set_packet_readable; return; case DSK_WEBSOCKET_MODE_SHUTDOWN: goto error_do_shutdown; } } else if (websocket->incoming.size >= 9 + len) goto set_packet_readable; else goto unset_packet_readable; set_packet_readable: dsk_hook_set_idle_notify (&websocket->readable, DSK_TRUE); if (websocket->read_trap != NULL) { dsk_hook_trap_destroy (websocket->read_trap); websocket->read_trap = NULL; } return; unset_packet_readable: dsk_hook_set_idle_notify (&websocket->readable, DSK_FALSE); ensure_has_read_trap (websocket); return; error_do_shutdown: dsk_hook_set_idle_notify (&websocket->readable, DSK_FALSE); if (websocket->read_trap != NULL) { dsk_hook_trap_destroy (websocket->read_trap); websocket->read_trap = NULL; } dsk_websocket_shutdown (websocket); }