diff --git a/src/libguac/guacamole/protocol.h b/src/libguac/guacamole/protocol.h index 2a5b138b..f4e02880 100644 --- a/src/libguac/guacamole/protocol.h +++ b/src/libguac/guacamole/protocol.h @@ -435,6 +435,37 @@ int guac_protocol_send_pipe(guac_socket* socket, const guac_stream* stream, int guac_protocol_send_blob(guac_socket* socket, const guac_stream* stream, const void* data, int count); +/** + * Sends a series of blob instructions, splitting the given data across the + * number of instructions required to ensure the size of each blob does not + * exceed GUAC_PROTOCOL_BLOB_MAX_LENGTH. If the size of data provided is zero, + * no blob instructions are sent. + * + * If an error occurs sending any blob instruction, a non-zero value is + * returned, guac_error is set appropriately, and no further blobs are sent. + * + * @see GUAC_PROTOCOL_BLOB_MAX_LENGTH + * + * @param socket + * The guac_socket connection to use to send the blob instructions. + * + * @param stream + * The stream to associate with each blob sent. + * + * @param data + * The data which should be sent using the required number of blob + * instructions. + * + * @param count + * The number of bytes within the given buffer of data that must be + * written. + * + * @return + * Zero on success, non-zero on error. + */ +int guac_protocol_send_blobs(guac_socket* socket, const guac_stream* stream, + const void* data, int count); + /** * Sends an end instruction over the given guac_socket connection. * diff --git a/src/libguac/protocol.c b/src/libguac/protocol.c index 53b534de..ff73a558 100644 --- a/src/libguac/protocol.c +++ b/src/libguac/protocol.c @@ -215,6 +215,33 @@ int guac_protocol_send_blob(guac_socket* socket, const guac_stream* stream, } +int guac_protocol_send_blobs(guac_socket* socket, const guac_stream* stream, + const void* data, int count) { + + int ret_val = 0; + + /* Send blob instructions while data remains and instructions are being + * sent successfully */ + while (count > 0 && ret_val == 0) { + + /* Limit blob size to maximum allowed */ + int blob_size = count; + if (blob_size > GUAC_PROTOCOL_BLOB_MAX_LENGTH) + blob_size = GUAC_PROTOCOL_BLOB_MAX_LENGTH; + + /* Send next blob of data */ + ret_val = guac_protocol_send_blob(socket, stream, data, blob_size); + + /* Advance to next blob */ + data = (const char*) data + blob_size; + count -= blob_size; + + } + + return ret_val; + +} + int guac_protocol_send_body(guac_socket* socket, const guac_object* object, const guac_stream* stream, const char* mimetype, const char* name) { diff --git a/src/libguac/raw_encoder.c b/src/libguac/raw_encoder.c index 98024cd2..888bde79 100644 --- a/src/libguac/raw_encoder.c +++ b/src/libguac/raw_encoder.c @@ -121,25 +121,8 @@ static void raw_encoder_flush_handler(guac_audio_stream* audio) { guac_socket* socket = audio->client->socket; guac_stream* stream = audio->stream; - unsigned char* current = state->buffer; - int remaining = state->written; - /* Flush all data in buffer as blobs */ - while (remaining > 0) { - - /* Determine size of blob to be written */ - int chunk_size = remaining; - if (chunk_size > GUAC_PROTOCOL_BLOB_MAX_LENGTH) - chunk_size = GUAC_PROTOCOL_BLOB_MAX_LENGTH; - - /* Send audio data */ - guac_protocol_send_blob(socket, stream, current, chunk_size); - - /* Advance to next blob */ - current += chunk_size; - remaining -= chunk_size; - - } + guac_protocol_send_blobs(socket, stream, state->buffer, state->written); /* All data has been flushed */ state->written = 0;