From 9e88ae4f6023bdd1169fa8766fcd67a0d39f2e21 Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Mon, 24 Jun 2013 11:55:15 -0700 Subject: [PATCH] Implement file/blob/end subprotocol. --- src/libguac/Makefile.am | 2 +- src/libguac/guacamole/protocol.h | 48 ++++++------------------- src/libguac/protocol.c | 60 +++++++++++++++----------------- 3 files changed, 40 insertions(+), 70 deletions(-) diff --git a/src/libguac/Makefile.am b/src/libguac/Makefile.am index 088801e1..63e83497 100644 --- a/src/libguac/Makefile.am +++ b/src/libguac/Makefile.am @@ -74,5 +74,5 @@ libguac_la_SOURCES = \ unicode.c lib_LTLIBRARIES = libguac.la -libguac_la_LDFLAGS = -version-info 4:0:0 @PTHREAD_LIBS@ +libguac_la_LDFLAGS = -version-info 5:0:0 @PTHREAD_LIBS@ diff --git a/src/libguac/guacamole/protocol.h b/src/libguac/guacamole/protocol.h index a9c21ce0..ae454494 100644 --- a/src/libguac/guacamole/protocol.h +++ b/src/libguac/guacamole/protocol.h @@ -356,59 +356,30 @@ int guac_protocol_send_audio_end(guac_socket* socket); * returned, and guac_error is set appropriately. * * @param socket The guac_socket connection to use. + * @param index The index of the blob that will contain the contents + * of this file. * @param name A name describing the file being sent. * @param mimetype The mimetype of the data being sent. - * @param data The file data to be sent. - * @param size The number of bytes of file data to send. * @return Zero on success, non-zero on error. */ -int guac_protocol_send_file(guac_socket* socket, const char* name, - const char* mimetype, void* data, int size); +int guac_protocol_send_file(guac_socket* socket, int index, + const char* name, const char* mimetype); /** - * Begins a file instruction over the given guac_socket connection. Only the - * initial non-data part of the instruction and the length of the data part - * of the instruction are sent. The actual contents of the data must be - * sent with guac_protocol_send_file_data(), and the instruction must be - * completed with guac_protocol_send_file_end(). - * - * Note that the size of the file to be sent MUST be known ahead of time, - * even though the data of the file may be sent in chunks. - * - * No further instruction data may be sent along the givven guac_socket - * except via guac_protocol_send_file_data() until the file instruction - * is completed with guac_protocol_send_file_end(). - * - * If an error occurs sending the instruction, a non-zero value is - * returned, and guac_error is set appropriately. - * - * @param socket The guac_socket connection to use. - * @param name A name describing the file being sent. - * @param mimetype The mimetype of the data being sent. - * @param size The number of bytes of file data to send. - * @return Zero on success, non-zero on error. - */ -int guac_protocol_send_file_header(guac_socket* socket, const char* name, - const char* mimetype, int size); - -/** - * Writes a block of file data to the currently in-progress file instruction - * which was started with guac_protocol_send_file_header(). Exactly the - * number of requested bytes are written unless an error occurs. This function - * may be called multiple times per file instruction for each chunk of file - * data being written, allowing the potentially huge file instruction to be - * split across multiple writes. + * Writes a block of data to the currently in-progress blob which was already + * created. * * If an error occurs sending the instruction, a non-zero value is * returned, and guac_error is set appropriately. * * @param socket The guac_socket connection to use. + * @param index The index of the blob to append data to. * @param data The file data to write. * @param count The number of bytes within the given buffer of file data * that must be written. * @return Zero on success, non-zero on error. */ -int guac_protocol_send_file_data(guac_socket* socket, void* data, int count); +int guac_protocol_send_blob(guac_socket* socket, int index, void* data, int count); /** * Completes the file instruction which was started with @@ -419,9 +390,10 @@ int guac_protocol_send_file_data(guac_socket* socket, void* data, int count); * returned, and guac_error is set appropriately. * * @param socket The guac_socket connection to use. + * @param index The index of the blob which is now complete. * @return Zero on success, non-zero on error. */ -int guac_protocol_send_file_end(guac_socket* socket); +int guac_protocol_send_end(guac_socket* socket, int index); /** * Sends a video instruction over the given guac_socket connection. diff --git a/src/libguac/protocol.c b/src/libguac/protocol.c index 8ed1e091..0f25fae8 100644 --- a/src/libguac/protocol.c +++ b/src/libguac/protocol.c @@ -442,6 +442,22 @@ int guac_protocol_send_audio_end(guac_socket* socket) { } +int guac_protocol_send_blob(guac_socket* socket, int index, void* data, int count) { + + int base64_length = (count + 2) / 3 * 4; + + return + guac_socket_write_string(socket, "4.blob,") + || __guac_socket_write_length_int(socket, index) + || guac_socket_write_string(socket, ",") + || guac_socket_write_int(socket, base64_length) + || guac_socket_write_string(socket, ".") + || guac_socket_write_base64(socket, data, count) + || guac_socket_flush_base64(socket) + || guac_socket_write_string(socket, ";"); + +} + int guac_protocol_send_cfill(guac_socket* socket, guac_composite_mode mode, const guac_layer* layer, int r, int g, int b, int a) { @@ -656,6 +672,16 @@ int guac_protocol_send_distort(guac_socket* socket, const guac_layer* layer, } +int guac_protocol_send_end(guac_socket* socket, int index) { + + return + guac_socket_write_string(socket, "3.end,") + || __guac_socket_write_length_int(socket, index) + || guac_socket_write_string(socket, ";"); + +} + + int guac_protocol_send_error(guac_socket* socket, const char* error) { return @@ -665,43 +691,15 @@ int guac_protocol_send_error(guac_socket* socket, const char* error) { } -int guac_protocol_send_file(guac_socket* socket, const char* name, - const char* mimetype, void* data, int size) { - - return - guac_protocol_send_file_header(socket, name, - mimetype, size) - || guac_protocol_send_file_data(socket, data, size) - || guac_protocol_send_file_end(socket); - -} - -int guac_protocol_send_file_header(guac_socket* socket, const char* name, - const char* mimetype, int size) { - - int base64_length = (size + 2) / 3 * 4; +int guac_protocol_send_file(guac_socket* socket, int index, const char* name, const char* mimetype) { return guac_socket_write_string(socket, "4.file,") + || __guac_socket_write_length_int(socket, index) + || guac_socket_write_string(socket, ",") || __guac_socket_write_length_string(socket, name) || guac_socket_write_string(socket, ",") || __guac_socket_write_length_string(socket, mimetype) - || guac_socket_write_string(socket, ",") - || guac_socket_write_int(socket, base64_length) - || guac_socket_write_string(socket, "."); - -} - -int guac_protocol_send_file_data(guac_socket* socket, void* data, int count) { - - return guac_socket_write_base64(socket, data, count); - -} - -int guac_protocol_send_file_end(guac_socket* socket) { - - return - guac_socket_flush_base64(socket) || guac_socket_write_string(socket, ";"); }