diff --git a/guacamole/proxy/guacio.c b/guacamole/proxy/guacio.c index b711832a9..612c0504a 100644 --- a/guacamole/proxy/guacio.c +++ b/guacamole/proxy/guacio.c @@ -1,56 +1,68 @@ +#include #include #include #include "guacio.h" -char characters[64] = { +char __GUACIO_BAS64_CHARACTERS[64] = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/', }; -int ready_buf[3]; -int ready = 0; +GUACIO* guac_open(int fd) { -int written = 0; -char out_buf[8192]; + GUACIO* io = malloc(sizeof(GUACIO)); + io->ready = 0; + io->written = 0; + io->fd = fd; -ssize_t __write_base64_triplet(int fd, int a, int b, int c) { +} + +void guac_close(GUACIO* io) { + free(io); +} + + +ssize_t __write_base64_triplet(GUACIO* io, int a, int b, int c) { + + int fd = io->fd; + char* out_buf = io->out_buf; int retval; /* Byte 1 */ - out_buf[written++] = characters[(a & 0xFC) >> 2]; /* [AAAAAA]AABBBB BBBBCC CCCCCC */ + out_buf[io->written++] = __GUACIO_BAS64_CHARACTERS[(a & 0xFC) >> 2]; /* [AAAAAA]AABBBB BBBBCC CCCCCC */ if (b >= 0) { - out_buf[written++] = characters[((a & 0x03) << 4) | ((b & 0xF0) >> 4)]; /* AAAAAA[AABBBB]BBBBCC CCCCCC */ + out_buf[io->written++] = __GUACIO_BAS64_CHARACTERS[((a & 0x03) << 4) | ((b & 0xF0) >> 4)]; /* AAAAAA[AABBBB]BBBBCC CCCCCC */ if (c >= 0) { - out_buf[written++] = characters[((b & 0x0F) << 2) | ((c & 0xC0) >> 6)]; /* AAAAAA AABBBB[BBBBCC]CCCCCC */ - out_buf[written++] = characters[c & 0x3F]; /* AAAAAA AABBBB BBBBCC[CCCCCC] */ + out_buf[io->written++] = __GUACIO_BAS64_CHARACTERS[((b & 0x0F) << 2) | ((c & 0xC0) >> 6)]; /* AAAAAA AABBBB[BBBBCC]CCCCCC */ + out_buf[io->written++] = __GUACIO_BAS64_CHARACTERS[c & 0x3F]; /* AAAAAA AABBBB BBBBCC[CCCCCC] */ } else { - out_buf[written++] = characters[((b & 0x0F) << 2)]; /* AAAAAA AABBBB[BBBB--]------ */ - out_buf[written++] = '='; /* AAAAAA AABBBB BBBB--[------] */ + out_buf[io->written++] = __GUACIO_BAS64_CHARACTERS[((b & 0x0F) << 2)]; /* AAAAAA AABBBB[BBBB--]------ */ + out_buf[io->written++] = '='; /* AAAAAA AABBBB BBBB--[------] */ } } else { - out_buf[written++] = characters[((a & 0x03) << 4)]; /* AAAAAA[AA----]------ ------ */ - out_buf[written++] = '='; /* AAAAAA AA----[------]------ */ - out_buf[written++] = '='; /* AAAAAA AA---- ------[------] */ + out_buf[io->written++] = __GUACIO_BAS64_CHARACTERS[((a & 0x03) << 4)]; /* AAAAAA[AA----]------ ------ */ + out_buf[io->written++] = '='; /* AAAAAA AA----[------]------ */ + out_buf[io->written++] = '='; /* AAAAAA AA---- ------[------] */ } - /* At this point, 4 bytes have been written */ + /* At this point, 4 bytes have been io->written */ /* Flush when necessary, return on error */ - if (written > 8188 /* sizeof(out_buf) - 4 */) { - retval = write(fd, out_buf, written); + if (io->written > 8188 /* sizeof(out_buf) - 4 */) { + retval = write(fd, out_buf, io->written); if (retval < 0) return retval; - written = 0; + io->written = 0; } if (b < 0) @@ -63,25 +75,27 @@ ssize_t __write_base64_triplet(int fd, int a, int b, int c) { } -ssize_t __write_base64_byte(int fd, char buf) { +ssize_t __write_base64_byte(GUACIO* io, char buf) { + + int* ready_buf = io->ready_buf; int retval; - ready_buf[ready++] = buf & 0xFF; + ready_buf[io->ready++] = buf & 0xFF; /* Flush triplet */ - if (ready == 3) { - retval = __write_base64_triplet(fd, ready_buf[0], ready_buf[1], ready_buf[2]); + if (io->ready == 3) { + retval = __write_base64_triplet(io, ready_buf[0], ready_buf[1], ready_buf[2]); if (retval < 0) return retval; - ready = 0; + io->ready = 0; } return 1; } -ssize_t write_base64(int fd, const void* buf, size_t count) { +ssize_t write_base64(GUACIO* io, const void* buf, size_t count) { int retval; @@ -90,7 +104,7 @@ ssize_t write_base64(int fd, const void* buf, size_t count) { while (char_buf < end) { - retval = __write_base64_byte(fd, *(char_buf++)); + retval = __write_base64_byte(io, *(char_buf++)); if (retval < 0) return retval; @@ -100,24 +114,24 @@ ssize_t write_base64(int fd, const void* buf, size_t count) { } -ssize_t flush_base64(int fd) { +ssize_t flush_base64(GUACIO* io) { int retval; /* Flush triplet to output buffer */ - while (ready > 0) { - retval = __write_base64_byte(fd, -1); + while (io->ready > 0) { + retval = __write_base64_byte(io, -1); if (retval < 0) return retval; } /* Flush remaining bytes in buffer */ - if (written > 0) { - retval = write(fd, out_buf, written); + if (io->written > 0) { + retval = write(io->fd, io->out_buf, io->written); if (retval < 0) return retval; - written = 0; + io->written = 0; } return 0; diff --git a/guacamole/proxy/guacio.h b/guacamole/proxy/guacio.h index 802df56f7..1d6cf2d79 100644 --- a/guacamole/proxy/guacio.h +++ b/guacamole/proxy/guacio.h @@ -4,8 +4,22 @@ #include -ssize_t write_base64(int fd, const void* buf, size_t count); -ssize_t flush_base64(int fd); +typedef struct GUACIO { + + int fd; + + int ready; + int ready_buf[3]; + + int written; + char out_buf[8192]; + +} GUACIO; + +GUACIO* guac_open(int fd); +ssize_t write_base64(GUACIO* io, const void* buf, size_t count); +ssize_t flush_base64(GUACIO* io); +void guac_close(GUACIO* io); #endif diff --git a/guacamole/proxy/proxy.c b/guacamole/proxy/proxy.c index 5ad7b8d3f..413cac976 100644 --- a/guacamole/proxy/proxy.c +++ b/guacamole/proxy/proxy.c @@ -6,17 +6,9 @@ #include "guacio.h" #include "proxy.h" -struct guac_write_info { - int client_fd; -}; - void guac_write_png(png_structp png, png_bytep data, png_size_t length) { - int client_fd; - - client_fd = ((struct guac_write_info*) png->io_ptr)->client_fd; - - if (write_base64(client_fd, data, length) < 0) { + if (write_base64((GUACIO*) png->io_ptr, data, length) < 0) { perror("Error writing PNG"); png_error(png, "Error writing PNG"); return; @@ -29,8 +21,6 @@ void guac_write_flush(png_structp png) { void proxy(int client_fd) { - struct guac_write_info write_info; - png_structp png; png_infop png_info; png_byte** png_rows; @@ -38,9 +28,9 @@ void proxy(int client_fd) { int x, y; - /*** INIT ***/ + GUACIO* io = guac_open(client_fd); - write_info.client_fd = client_fd; + /*** INIT ***/ /* Allocate rows for PNG */ png_rows = (png_byte**) malloc(100 /* height */ * sizeof(png_byte*)); @@ -59,7 +49,7 @@ void proxy(int client_fd) { } - write(client_fd, "name:hello;size:1024,768;", 25); + write(io->fd, "name:hello;size:1024,768;", 25); for (y=0; y<200; y++) { @@ -86,7 +76,7 @@ void proxy(int client_fd) { return; } - png_set_write_fn(png, &write_info, guac_write_png, guac_write_flush); + png_set_write_fn(png, io, guac_write_png, guac_write_flush); /* Set PNG IHDR */ png_set_IHDR( @@ -101,11 +91,11 @@ void proxy(int client_fd) { PNG_FILTER_TYPE_DEFAULT ); - write(client_fd, "png:0,0,", 8); + write(io->fd, "png:0,0,", 8); png_set_rows(png, png_info, png_rows); png_write_png(png, png_info, PNG_TRANSFORM_IDENTITY, NULL); - if (flush_base64(client_fd) < 0) { + if (flush_base64(io) < 0) { perror("Error flushing PNG"); png_error(png, "Error flushing PNG"); return; @@ -113,10 +103,10 @@ void proxy(int client_fd) { png_destroy_write_struct(&png, &png_info); - write(client_fd, ";", 1); + write(io->fd, ";", 1); } - write(client_fd, "error:Test finished.;", 21); + write(io->fd, "error:Test finished.;", 21); /* Free PNG data */ for (y = 0; y<100 /* height */; y++)