mirror of
				https://github.com/gyurix1968/guacamole-client.git
				synced 2025-10-31 00:53:21 +00:00 
			
		
		
		
	guac_message structure, initial parsing support
This commit is contained in:
		| @@ -1,6 +1,7 @@ | ||||
| #include <stdlib.h> | ||||
| #include <stdio.h> | ||||
| #include <string.h> | ||||
| #include <errno.h> | ||||
| #include <png.h> | ||||
|  | ||||
| #include "guacio.h" | ||||
| @@ -175,3 +176,98 @@ void guac_send_png(GUACIO* io, int x, int y, png_byte** png_rows, int w, int h) | ||||
| } | ||||
|  | ||||
|  | ||||
| int __guac_fill_messagebuf(GUACIO* io) { | ||||
|  | ||||
|     int retval; | ||||
|      | ||||
|     /* Attempt to fill buffer */ | ||||
|     retval = read( | ||||
|             io->fd, | ||||
|             io->messagebuf + io->messagebuf_used_length, | ||||
|             io->messagebuf_size - io->messagebuf_used_length | ||||
|     ); | ||||
|  | ||||
|     if (retval < 0) | ||||
|         return retval; | ||||
|  | ||||
|     io->messagebuf_used_length += retval; | ||||
|  | ||||
|     /* Expand buffer if necessary */ | ||||
|     if (io->messagebuf_used_length > io->messagebuf_size / 2) { | ||||
|         io->messagebuf_size *= 2; | ||||
|         io->messagebuf = realloc(io->messagebuf, io->messagebuf_size); | ||||
|     } | ||||
|  | ||||
|     return retval; | ||||
|  | ||||
| } | ||||
|  | ||||
| guac_message* guac_read_message(GUACIO* io) { | ||||
|  | ||||
|     guac_message* parsed_message; | ||||
|     int retval; | ||||
|     int i = 0; | ||||
|      | ||||
|     /* Loop until a message is read */ | ||||
|     for (;;) { | ||||
|  | ||||
|         /* Search for end of message */ | ||||
|         for (; i < io->messagebuf_used_length; i++) { | ||||
|  | ||||
|             if (io->messagebuf[i] == ';') { | ||||
|  | ||||
|                 /* Parse new message */ | ||||
|                 char* message = malloc(i+1); | ||||
|                 memcpy(message, io->messagebuf, i+1); | ||||
|                 message[i] = '\0'; /* Replace semicolon with null terminator. */ | ||||
|  | ||||
|                 parsed_message = malloc(sizeof(guac_message)); | ||||
|                 parsed_message->opcode = message; | ||||
|                 parsed_message->argc = 0; | ||||
|                 parsed_message->argv = NULL; | ||||
|  | ||||
|                 /* Found. Reset buffer */ | ||||
|                 memmove(io->messagebuf, io->messagebuf + i + 1, io->messagebuf_used_length - i - 1); | ||||
|                 io->messagebuf_used_length -= i + 1; | ||||
|  | ||||
|                 /* Done */ | ||||
|                 return parsed_message; | ||||
|             } | ||||
|  | ||||
|         } | ||||
|  | ||||
|         /* No message yet? Get more data ... */ | ||||
|         retval = guac_select(io, 1000); | ||||
|         if (retval < 0) | ||||
|             return NULL; | ||||
|  | ||||
|         /* Break if descriptor doesn't have enough data */ | ||||
|         if (retval == 0) | ||||
|             return NULL; /* SOFT FAIL: No message ... yet, but is still in buffer */ | ||||
|  | ||||
|         retval = __guac_fill_messagebuf(io); | ||||
|         if (retval < 0 && errno != EAGAIN && errno != EWOULDBLOCK) | ||||
|             return NULL; | ||||
|  | ||||
|     } | ||||
|  | ||||
| } | ||||
|  | ||||
| void guac_free_message(guac_message* message) { | ||||
|     free(message->opcode); | ||||
|  | ||||
|     if (message->argv) | ||||
|         free(message->argv); | ||||
|  | ||||
|     free(message); | ||||
| } | ||||
|  | ||||
|  | ||||
| int guac_messages_waiting(GUACIO* io) { | ||||
|  | ||||
|     if (io->messagebuf_used_length > 0) | ||||
|         return 1; | ||||
|  | ||||
|     return guac_select(io, 1000); | ||||
| } | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user