src/irc_line.h
author Tero Marttila <terom@fixme.fi>
Thu, 28 May 2009 01:17:36 +0300
branchnew-lib-errors
changeset 219 cefec18b8268
parent 190 69fd25c8484c
permissions -rw-r--r--
some of the lib/transport stuff compiles
#ifndef IRC_LINE_H
#define IRC_LINE_H

/**
 * @file
 *
 * The low-level IRC protocol unit is a line, with prefix, command and arguments
 */
#include "irc_proto.h"
#include "error.h"

/**
 * The maximum length of a line, without terminating CRLF, but including NUL
 */
#define IRC_LINE_MAX (510 + 1)

/**
 * The maximum number of arguments for a single command
 */
#define IRC_ARG_MAX 15

/**
 * Chars that are invalid inside of tokens
 */
#define IRC_TOKEN_INVALID "\r\n\n "

/**
 * Chars that are invalid inside of the trailing-argument token
 */
#define IRC_TOKEN_TRAILING_INVALID "\r\n\n"

/**
 * Low-level IRC protocol unit. Note that all fields are specifically constant strings, MUST NOT be modified, and 
 * usually point at stack-allocated memory. Hence, if you need to mutate or store these values, you must copy them.
 */
struct irc_line {
    /** The message source as a nickmask, for those messages that have a valid prefix. May be NULL otherwise */
    const struct irc_nm *source;

    /** The command, either a numeric or a primary command */
    const char *command;

    /** The arguments, with unused ones set to NULL */
    const char *args[IRC_ARG_MAX];
};

/**
 * Parse an IRC message to fill in an irc_line. This mutates the contents of data (to insert NULs between tokens), and
 * stores pointers into this memory in the irc_line.
 *
 * If the prefix is a valid nickmask, it will be stored in the given given irc_nm, and irc_line.nm set to this.
 *
 * The irc_line will have the first N args values set to valid values, and all the rest set to NULL.
 *
 * XXX: strip trailing \r\n
 */
err_t irc_line_parse (struct irc_line *line, struct irc_nm *nm, char *data);

/**
 * Formats an irc_line as a protocol line into the given buffer (which should hold at least IRC_LINE_MAX bytes).
 *
 * The irc_line.args are ignored from the first NULL argument onwards.
 *
 * An error is returned if a token has an invalid value (e.g. a space in the command or an argument other than the last
 * one), or if the resulting line is too long.
 *
 * XXX: append trailing \r\n
 */
err_t irc_line_build (const struct irc_line *line, char *buf);

/**
 * Iterate through the arguments in an irc_line
 */
#define FOREACH_IRC_LINE_ARGS(line, arg_ptr) \
    for (size_t _irc_line_arg_idx = 0; _irc_line_arg_idx < IRC_ARG_MAX && (arg_ptr = line->args[_irc_line_arg_idx]); _irc_line_arg_idx++)

#endif /* IRC_LINE_H */