1
0
Fork 0
mirror of git://git.psyc.eu/libpsyc synced 2024-08-15 03:19:02 +00:00
libpsyc/include/psyc/packet.h

187 lines
4.5 KiB
C
Raw Normal View History

#ifndef PSYC_PACKET_H
2011-05-09 12:37:57 +00:00
/**
* @file psyc/packet.h
* @brief Interface for PSYC packet data structures.
*
* Packet data structures and functions for creating them are defined here.
*/
/**
* @defgroup packet Packet data structures
*
* This module contains definitions of packet data structures and functions for
* creating them.
* @{
*/
#include <psyc.h>
#include <psyc/syntax.h>
2011-10-31 19:04:16 +00:00
#include <math.h>
2011-05-09 14:32:39 +00:00
/** Modifier flags. */
typedef enum
{
2011-05-09 14:32:39 +00:00
/// Modifier needs to be checked if it needs length.
PSYC_MODIFIER_CHECK_LENGTH = 0,
2011-05-09 14:32:39 +00:00
/// Modifier needs length.
PSYC_MODIFIER_NEED_LENGTH = 1,
2011-05-09 14:32:39 +00:00
/// Modifier doesn't need length.
PSYC_MODIFIER_NO_LENGTH = 2,
2011-05-09 14:32:39 +00:00
/// Routing modifier, which implies that it doesn't need length.
PSYC_MODIFIER_ROUTING = 3,
2011-10-31 19:26:47 +00:00
} PsycModifierFlag;
2011-05-09 14:32:39 +00:00
/** List flags. */
typedef enum
{
2011-05-09 14:32:39 +00:00
/// List needs to be checked if it needs length.
PSYC_LIST_CHECK_LENGTH = 0,
2011-05-09 14:32:39 +00:00
/// List needs length.
PSYC_LIST_NEED_LENGTH = 1,
2011-05-09 14:32:39 +00:00
/// List doesn't need length.
PSYC_LIST_NO_LENGTH = 2,
2011-10-31 19:26:47 +00:00
} PsycListFlag;
2011-05-09 14:32:39 +00:00
/** Packet flags. */
typedef enum
{
2011-05-09 14:32:39 +00:00
/// Packet needs to be checked if it needs content length.
PSYC_PACKET_CHECK_LENGTH = 0,
2011-05-09 14:32:39 +00:00
/// Packet needs content length.
PSYC_PACKET_NEED_LENGTH = 1,
2011-05-09 14:32:39 +00:00
/// Packet doesn't need content length.
PSYC_PACKET_NO_LENGTH = 2,
2011-10-31 19:26:47 +00:00
} PsycPacketFlag;
2011-05-09 14:32:39 +00:00
/** Structure for a modifier. */
typedef struct
2011-05-09 15:06:15 +00:00
{
char oper;
2011-10-31 19:26:47 +00:00
PsycString name;
PsycString value;
PsycModifierFlag flag;
} PsycModifier;
2011-05-09 14:32:39 +00:00
/** Structure for an entity or routing header. */
typedef struct
{
size_t lines;
2011-10-31 19:26:47 +00:00
PsycModifier *modifiers;
} PsycHeader;
2011-05-09 14:32:39 +00:00
/** Structure for a list. */
typedef struct
{
size_t num_elems;
2011-10-31 19:26:47 +00:00
PsycString *elems;
size_t length;
2011-10-31 19:26:47 +00:00
PsycListFlag flag;
} PsycList;
2011-10-31 19:04:16 +00:00
/** Intermediate struct for a PSYC packet */
typedef struct
{
2011-10-31 19:26:47 +00:00
PsycHeader routing; ///< Routing header.
PsycHeader entity; ///< Entity header.
PsycString method; ///< Contains the method.
PsycString data; ///< Contains the data.
PsycString content; ///< Contains the whole content.
size_t routingLength; ///< Length of routing part.
size_t contentLength; ///< Length of content part.
size_t length; ///< Total length of packet.
2011-10-31 19:26:47 +00:00
PsycPacketFlag flag; ///< Packet flag.
} PsycPacket;
2011-10-31 19:04:16 +00:00
/**
* Return the number of digits a number has in its base 10 representation.
*/
static inline
size_t psyc_num_length (size_t n)
{
return n < 10 ? 1 : log10(n) + 1;
}
2011-05-28 18:24:36 +00:00
/**
* \internal
* Check if a modifier needs length.
*/
static inline
2011-10-31 19:26:47 +00:00
PsycModifierFlag psyc_modifier_length_check (PsycModifier *m)
{
2011-10-31 19:26:47 +00:00
PsycModifierFlag flag;
if (m->value.length > PSYC_MODIFIER_SIZE_THRESHOLD)
flag = PSYC_MODIFIER_NEED_LENGTH;
else if (memchr(m->value.ptr, (int)'\n', m->value.length))
flag = PSYC_MODIFIER_NEED_LENGTH;
else
flag = PSYC_MODIFIER_NO_LENGTH;
return flag;
}
2011-10-31 19:04:16 +00:00
/** Create new modifier */
static inline
2011-10-31 19:26:47 +00:00
PsycModifier psyc_modifier_new (char oper,
2011-10-31 19:04:16 +00:00
char *name, size_t namelen,
char *value, size_t valuelen,
2011-10-31 19:26:47 +00:00
PsycModifierFlag flag){
2011-10-31 19:04:16 +00:00
2011-10-31 19:26:47 +00:00
PsycModifier m = {oper, {namelen, name}, {valuelen, value}, flag};
if (flag == PSYC_MODIFIER_CHECK_LENGTH) // find out if it needs a length
2011-10-31 19:04:16 +00:00
m.flag = psyc_modifier_length_check(&m);
return m;
}
2011-05-28 18:29:19 +00:00
/**
* \internal
* Get the total length of a modifier when rendered.
*/
2011-10-31 19:26:47 +00:00
size_t psyc_modifier_length (PsycModifier *m);
2011-05-28 18:24:36 +00:00
/**
* \internal
* Check if a list needs length.
*/
2011-10-31 19:26:47 +00:00
PsycListFlag psyc_list_length_check (PsycList *list);
2011-05-28 18:29:19 +00:00
/**
* \internal
* Get the total length of a list when rendered.
*/
2011-10-31 19:26:47 +00:00
PsycListFlag psyc_list_length (PsycList *list);
2011-05-28 18:24:36 +00:00
/**
* \internal
* Check if a packet needs length.
*/
2011-10-31 19:26:47 +00:00
PsycPacketFlag psyc_packet_length_check (PsycPacket *p);
2011-05-28 18:29:19 +00:00
/**
* Calculate and set the rendered length of packet parts and total packet length.
*/
2011-10-31 19:26:47 +00:00
size_t psyc_packet_length_set (PsycPacket *p);
2011-05-09 14:32:39 +00:00
/** Create new list. */
2011-10-31 19:26:47 +00:00
PsycList psyc_list_new (PsycString *elems, size_t num_elems, PsycListFlag flag);
2011-05-09 14:32:39 +00:00
/** Create new packet. */
2011-10-31 19:26:47 +00:00
PsycPacket psyc_packet_new (PsycModifier *routing, size_t routinglen,
PsycModifier *entity, size_t entitylen,
2011-10-31 19:04:16 +00:00
char *method, size_t methodlen,
char *data, size_t datalen,
2011-10-31 19:26:47 +00:00
PsycPacketFlag flag);
2011-05-09 14:32:39 +00:00
/** Create new packet with raw content. */
2011-10-31 19:26:47 +00:00
PsycPacket psyc_packet_new_raw (PsycModifier *routing, size_t routinglen,
2011-10-31 19:04:16 +00:00
char *content, size_t contentlen,
2011-10-31 19:26:47 +00:00
PsycPacketFlag flag);
2011-05-09 12:37:57 +00:00
/** @} */ // end of packet group
2011-05-09 07:02:15 +00:00
#define PSYC_PACKET_H
#endif