blob: 1d948089a9cffa70ca3273d6992310473153e48c [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
#ifndef _GUAC_PARSER_H
#define _GUAC_PARSER_H
/**
* Provides functions and structures for parsing the Guacamole protocol.
*
* @file parser.h
*/
#include "parser-types.h"
#include "parser-constants.h"
#include "socket-types.h"
struct guac_parser {
/**
* The opcode of the instruction.
*/
char* opcode;
/**
* The number of arguments passed to this instruction.
*/
int argc;
/**
* Array of all arguments passed to this instruction.
*/
char** argv;
/**
* The parse state of the instruction.
*/
guac_parse_state state;
/**
* The length of the current element, if known.
*/
int __element_length;
/**
* The number of elements currently parsed.
*/
int __elementc;
/**
* All currently parsed elements.
*/
char* __elementv[GUAC_INSTRUCTION_MAX_ELEMENTS];
/**
* Pointer to the first character of the current in-progress instruction
* within the buffer.
*/
char* __instructionbuf_unparsed_start;
/**
* Pointer to the first unused section of the instruction buffer.
*/
char* __instructionbuf_unparsed_end;
/**
* The instruction buffer. This is essentially the input buffer,
* provided as a convenience to be used to buffer instructions until
* those instructions are complete and ready to be parsed.
*/
char __instructionbuf[32768];
};
/**
* Allocates a new parser.
*
* @return The newly allocated parser, or NULL if an error occurs during
* allocation, in which case guac_error will be set appropriately.
*/
guac_parser* guac_parser_alloc();
/**
* Appends data from the given buffer to the given parser. The data will be
* appended, if possible, to the in-progress instruction as a reference and
* thus the buffer must remain valid throughout the life of the current
* instruction. This function may modify the contents of the buffer when those
* contents are part of an element within the instruction being read.
*
* @param parser The parser to append data to.
* @param buffer A buffer containing data that should be appended to this
* parser.
* @param length The number of bytes available for appending within the buffer.
* @return The number of bytes appended to this parser, which may be
* zero if more data is needed.
*/
int guac_parser_append(guac_parser* parser, void* buffer, int length);
/**
* Returns the number of unparsed bytes stored in the given parser's internal
* buffers.
*
* @param parser The parser to return the length of.
* @return The number of unparsed bytes stored in the given parser.
*/
int guac_parser_length(guac_parser* parser);
/**
* Removes up to length bytes from internal buffer of unparsed bytes, storing
* them in the given buffer.
*
* @param parser The parser to remove unparsed bytes from.
* @param buffer The buffer to store the unparsed bytes within.
* @param length The length of the given buffer.
* @return The number of bytes stored in the given buffer.
*/
int guac_parser_shift(guac_parser* parser, void* buffer, int length);
/**
* Frees all memory allocated to the given parser.
*
* @param parser The parser to free.
*/
void guac_parser_free(guac_parser* parser);
/**
* Reads a single instruction from the given guac_socket connection. This
* may result in additional data being read from the guac_socket, stored
* internally within a buffer for future parsing. Future calls to
* guac_parser_read() will read from the interal buffer before reading
* from the guac_socket. Data from the internal buffer can be removed
* and used elsewhere through guac_parser_shift().
*
* If an error occurs reading the instruction, non-zero is returned,
* and guac_error is set appropriately.
*
* @param parser The guac_parser to read instruction data from.
* @param socket The guac_socket connection to use.
* @param usec_timeout The maximum number of microseconds to wait before
* giving up.
* @return Zero if an instruction was read within the time allowed, or
* non-zero if no instruction could be read. If the instruction
* could not be read completely because the timeout elapsed, in
* which case guac_error will be set to GUAC_STATUS_INPUT_TIMEOUT
* and additional calls to guac_parser_read() will be required.
*/
int guac_parser_read(guac_parser* parser, guac_socket* socket, int usec_timeout);
/**
* Reads a single instruction from the given guac_socket. This operates
* identically to guac_parser_read(), except that an error is returned if
* the expected opcode is not received.
*
* If an error occurs reading the instruction, NULL is returned,
* and guac_error is set appropriately.
*
* If the instruction read is not the expected instruction, NULL is returned,
* and guac_error is set to GUAC_STATUS_BAD_STATE.
*
* @param parser The guac_parser to read instruction data from.
* @param socket The guac_socket connection to use.
* @param usec_timeout The maximum number of microseconds to wait before
* giving up.
* @param opcode The opcode of the instruction to read.
* @return Zero if an instruction with the given opcode was read, non-zero
* otherwise. If an instruction was read, but the instruction had a
* different opcode, non-zero is returned and guac_error is set to
* GUAC_STATUS_BAD_STATE.
*/
int guac_parser_expect(guac_parser* parser, guac_socket* socket, int usec_timeout, const char* opcode);
#endif