コード例 #1
0
int __guac_fill_instructionbuf(guac_socket* socket) {

    int retval;
    
    /* Attempt to fill buffer */
    retval = guac_socket_read(
        socket,
        socket->__instructionbuf + socket->__instructionbuf_used_length,
        socket->__instructionbuf_size - socket->__instructionbuf_used_length
    );

    /* Set guac_error if recv() unsuccessful */
    if (retval < 0) {
        guac_error = GUAC_STATUS_SEE_ERRNO;
        guac_error_message = "Error filling instruction buffer";
        return retval;
    }

    socket->__instructionbuf_used_length += retval;

    /* Expand buffer if necessary */
    if (socket->__instructionbuf_used_length >
            socket->__instructionbuf_size / 2) {

        socket->__instructionbuf_size *= 2;
        socket->__instructionbuf = realloc(socket->__instructionbuf,
                socket->__instructionbuf_size);
    }

    return retval;

}
コード例 #2
0
int guac_parser_read(guac_parser* parser, guac_socket* socket, int usec_timeout) {

    char* unparsed_end   = parser->__instructionbuf_unparsed_end;
    char* unparsed_start = parser->__instructionbuf_unparsed_start;
    char* instr_start    = parser->__instructionbuf_unparsed_start;
    char* buffer_end     = parser->__instructionbuf + sizeof(parser->__instructionbuf);

    /* Begin next instruction if previous was ended */
    if (parser->state == GUAC_PARSE_COMPLETE)
        guac_parser_reset(parser);

    while (parser->state != GUAC_PARSE_COMPLETE
        && parser->state != GUAC_PARSE_ERROR) {

        /* Add any available data to buffer */
        int parsed = guac_parser_append(parser, unparsed_start, unparsed_end - unparsed_start);

        /* Read more data if not enough data to parse */
        if (parsed == 0 && parser->state != GUAC_PARSE_ERROR) {

            int retval;

            /* If no space left to read, fail */
            if (unparsed_end == buffer_end) {

                /* Shift backward if possible */
                if (instr_start != parser->__instructionbuf) {

                    int i;

                    /* Shift buffer */
                    int offset = instr_start - parser->__instructionbuf;
                    memmove(parser->__instructionbuf, instr_start,
                            unparsed_end - instr_start);

                    /* Update tracking pointers */
                    unparsed_end -= offset;
                    unparsed_start -= offset;
                    instr_start = parser->__instructionbuf;

                    /* Update parsed elements, if any */
                    for (i=0; i < parser->__elementc; i++)
                        parser->__elementv[i] -= offset;

                }

                /* Otherwise, no memory to read */
                else {
                    guac_error = GUAC_STATUS_NO_MEMORY;
                    guac_error_message = "Instruction too long";
                    return -1;
                }

            }

            /* No instruction yet? Get more data ... */
            retval = guac_socket_select(socket, usec_timeout);
            if (retval <= 0)
                return -1;
           
            /* Attempt to fill buffer */
            retval = guac_socket_read(socket, unparsed_end,
                    buffer_end - unparsed_end);

            /* Set guac_error if read unsuccessful */
            if (retval < 0) {
                guac_error = GUAC_STATUS_SEE_ERRNO;
                guac_error_message = "Error filling instruction buffer";
                return -1;
            }

            /* EOF */
            if (retval == 0) {
                guac_error = GUAC_STATUS_CLOSED;
                guac_error_message = "End of stream reached while "
                                     "reading instruction";
                return -1;
            }

            /* Update internal buffer */
            unparsed_end += retval;

        }

        /* If data was parsed, advance buffer */
        else
            unparsed_start += parsed;

    } /* end while parsing data */

    /* Fail on error */
    if (parser->state == GUAC_PARSE_ERROR) {
        guac_error = GUAC_STATUS_PROTOCOL_ERROR;
        guac_error_message = "Instruction parse error";
        return -1;
    }

    parser->__instructionbuf_unparsed_start = unparsed_start;
    parser->__instructionbuf_unparsed_end = unparsed_end;
    return 0;

}
コード例 #3
0
/* Returns new instruction if one exists, or NULL if no more instructions. */
guac_instruction* guac_instruction_read(guac_socket* socket,
        int usec_timeout) {

    char* unparsed_end = socket->__instructionbuf_unparsed_end;
    char* unparsed_start = socket->__instructionbuf_unparsed_start;
    char* instr_start = socket->__instructionbuf_unparsed_start;
    char* buffer_end = socket->__instructionbuf
                            + sizeof(socket->__instructionbuf);

    guac_instruction* instruction = guac_instruction_alloc();

    while (instruction->state != GUAC_INSTRUCTION_PARSE_COMPLETE
        && instruction->state != GUAC_INSTRUCTION_PARSE_ERROR) {

        /* Add any available data to buffer */
        int parsed = guac_instruction_append(instruction, unparsed_start,
                unparsed_end - unparsed_start);

        /* Read more data if not enough data to parse */
        if (parsed == 0) {

            int retval;

            /* If no space left to read, fail */
            if (unparsed_end == buffer_end) {

                /* Shift backward if possible */
                if (instr_start != socket->__instructionbuf) {

                    int i;

                    /* Shift buffer */
                    int offset = instr_start - socket->__instructionbuf;
                    memmove(socket->__instructionbuf, instr_start,
                            unparsed_end - instr_start);

                    /* Update tracking pointers */
                    unparsed_end -= offset;
                    unparsed_start -= offset;
                    instr_start = socket->__instructionbuf;

                    /* Update parsed elements, if any */
                    for (i=0; i<instruction->__elementc; i++)
                        instruction->__elementv[i] -= offset;

                }

                /* Otherwise, no memory to read */
                else {
                    guac_error = GUAC_STATUS_NO_MEMORY;
                    guac_error_message = "Instruction too long";
                    return NULL;
                }

            }

            /* No instruction yet? Get more data ... */
            retval = guac_socket_select(socket, usec_timeout);
            if (retval <= 0)
                return NULL;
           
            /* Attempt to fill buffer */
            retval = guac_socket_read(socket, unparsed_end,
                    buffer_end - unparsed_end);

            /* Set guac_error if read unsuccessful */
            if (retval < 0) {
                guac_error = GUAC_STATUS_SEE_ERRNO;
                guac_error_message = "Error filling instruction buffer";
                return NULL;
            }

            /* EOF */
            if (retval == 0) {
                guac_error = GUAC_STATUS_NO_INPUT;
                guac_error_message = "End of stream reached while "
                                     "reading instruction";
                return NULL;
            }

            /* Update internal buffer */
            unparsed_end += retval;

        }

        /* If data was parsed, advance buffer */
        else
            unparsed_start += parsed;

    } /* end while parsing data */

    /* Fail on error */
    if (instruction->state == GUAC_INSTRUCTION_PARSE_ERROR) {
        guac_error = GUAC_STATUS_BAD_ARGUMENT;
        guac_error_message = "Instruction parse error";
        return NULL;
    }

    socket->__instructionbuf_unparsed_start = unparsed_start;
    socket->__instructionbuf_unparsed_end = unparsed_end;
    return instruction;

}