/*****************************************************************************/
/*
                                  HPACK.h
*/
/*****************************************************************************/

#ifndef HPACK_H_LOADED
#define HPACK_H_LOADED 1

#include "wasd.h"
#include "types.h"

#define HPACK_STATIC_TABLE_COUNT 61

/**************/
/* structures */
/**************/

/* required forward declaration */
typedef struct Http2Struct HTTP2_STRUCT;
typedef struct Http2StreamStruct HTTP2_STREAM_STRUCT;

#pragma member_alignment __save
#pragma member_alignment

typedef struct HpackEntryStruct HPACK_ENTRY_STRUCT;
typedef struct HpackTableStruct HPACK_TABLE_STRUCT;

/* doesn't have to be 32 bytes, just makes it a little more intuitive */
/* 32 bit everything so 7 x 4 := 28 bytes plus 4 byte "buffer" := 32 bytes */
struct HpackEntryStruct
{
   void  *flink,
         *blink;

   uint  hits,
         nlen,
         vlen;

   uchar  *name,
          *value;

   /* "buffer" space also allows for terminating nulls on the two strings */
   uchar  buffer [4];
   /* the actual buffer space used continues with allocated memory */
};

struct HpackTableStruct
{
   HPACK_ENTRY_STRUCT  *head,
                       *tail;
   uint  baseline,
         count,
         max,
         size;

   HTTP2_STRUCT  *h2ptr;
};

#pragma member_alignment __restore

/***********************/
/* function prototypes */
/***********************/

int HpackAddToTable (HPACK_TABLE_STRUCT*, uchar*, uint, uchar*, uint);
uchar* HpackDecodeHuff4 (uchar*, uchar, uchar*, int*);
int HpackDecodeInt32 (HTTP2_STRUCT*, uchar**, uchar*, uint, uint*);
int HpackDecodeString (HTTP2_STRUCT*, uchar**, uchar*, uchar**, uint**);
int HpackEncodeInt32 (HTTP2_STRUCT*, uchar**, uchar*, uint, uint);
int HpackEncodeString (HTTP2_STRUCT*, uchar**, uchar*, uchar*, uint);
int HpackFindInTable (HPACK_TABLE_STRUCT*, uchar*, uint, uchar*, uint);
int HpackGetIndex (HPACK_TABLE_STRUCT*, uint, uchar**, uint**, uchar**, uint**);
void HpackInit ();
int HpackHeadersFrame (HTTP2_STREAM_STRUCT*, uint, uint, uchar*, uint);
void HpackTrimTable (HPACK_TABLE_STRUCT*);
void HpackReport (REQUEST_STRUCT*, uchar*);
void HpackWatchTable (HPACK_TABLE_STRUCT*);

#endif /* HPACK_H_LOADED */

/*****************************************************************************/

